TelluIoT / ThingML

The ThingML modelling language
https://github.com/TelluIoT/ThingML
Apache License 2.0
102 stars 32 forks source link

Malfunctioning transition in c? #78

Closed nharrand closed 8 years ago

nharrand commented 9 years ago

Some transitions appear malfunctionning when compiled in c

ThingML code:

configuration testCfg {
    instance t : Test
}

thing Test {
    statechart testChart init S0 {
            on entry do
                print "[Test] Entering testChart\n"
            end
        state S0 {
            on entry do
                print "[Test] Entering S0\n"
            end

            transition -> S1
        }
        state S1 {
            on entry do
                print "[Test] Entering S1\n"
            end

            transition -> S2
        }
        state S2 {
            on entry do
                print "[Test] Entering S2\n"
            end

        }
    }
}

C output:

[Test] Entering testChart
[Test] Entering S0
[Test] Entering S1

While in java... java output:

[Test] Entering testChart

[Test] Entering S0

[Test] Entering S1

[Test] Entering S2

Something less important: the thingml function print add a new line in java, but not in c.

nharrand commented 9 years ago

Indeed the main generated in c is:

int main(int argc, char *argv[]) {
  init_runtime();
  // NO C_MAIN Annotation
  initialize_configuration_testCfg();

  while (1) {
    Test_handle_empty_event(&testCfg_t_var);

    processMessageQueue();
  }
}

with the function processMessageQueue() waiting for a message and locking everything else:

processMessageQueue() {
fifo_lock();
while (fifo_empty()) fifo_wait();
byte mbuf[2];
uint8_t mbufi = 0;

// Read the code of the next port/message in the queue
uint16_t code = fifo_dequeue() << 8;

code += fifo_dequeue();

// Switch to call the appropriate handler
switch(code) {
}
}

if processMessageQueue() was defined as following it solves this problem, but would it create some new one? Shall I commit a change on that matter?

void processMessageQueue() {
fifo_lock();
//while (fifo_empty()) fifo_wait();
if(!fifo_empty()) {
byte mbuf[2];
uint8_t mbufi = 0;

// Read the code of the next port/message in the queue
uint16_t code = fifo_dequeue() << 8;

code += fifo_dequeue();

// Switch to call the appropriate handler
switch(code) {
}
}
}

For arduino it appear to be the chosen solution.

brice-morin commented 9 years ago

Also we should update the tests. We have one that actually tests that, but it might be too simple. I guess we just need to add one more state and one more transition to get the C compiler to fail.

brice-morin commented 8 years ago

@Lyadis if it works on Arduino it is worth trying on Linux

nharrand commented 8 years ago

I would fix this problem, but it would generate active wait in cases where the program is waiting for another thread to enqueue messages (for example, when listening to the network). I think that's why @ffleurey added this line in the first place. So, I don't think it's the right thing to do.

brice-morin commented 8 years ago

hmmmm, I see.... But chaining transitions with no events can be sometimes useful (e.g. for some initialization you want to make in sequence).

nharrand commented 8 years ago

The new behaviour of c compiler is to prioritize empty event over messages. The message queue is now process only when there is no more empty event transition available. It solves this issue without introducing any active wait.