Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add C code generation to store currently executed reaction, add AnytimePrime.lf as a demo for check_deadline(). #960

Merged
merged 9 commits into from
Feb 13, 2022
67 changes: 67 additions & 0 deletions experimental/C/src/AnytimePrime.lf
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* This program is a concept demonstration showing how the check_deadline()
* function works. This program performs "anytime computation" (https://en.wikipedia.org/wiki/Anytime_algorithm)
* to find the largest prime within the given deadline. The check_deadline()
* function is called after checking each number if it is prime. If the
hokeun marked this conversation as resolved.
Show resolved Hide resolved
* check_deadline() is called after the deadline has passed, the function calls
* the deadline handler and returns true. Then the program outputs the largest
hokeun marked this conversation as resolved.
Show resolved Hide resolved
* prime found by that time and exits.
*
* For more discussion on check_deadline(), see: https://github.com/lf-lang/lingua-franca/issues/403
*
* @author Hokeun Kim ([email protected])
* @author Edward A. Lee ([email protected])
* @author Marten Lohstroh ([email protected])
*/
target C {
fast: true,
files: ["/lib/c/reactor-c/core/utils/vector.h",
"/lib/c/reactor-c/core/utils/vector.c"]
};

preamble {=
#include "vector.c"
hokeun marked this conversation as resolved.
Show resolved Hide resolved
=}

reactor Prime {
output out:{=long long=};
reaction(startup) -> out {=
int num_primes = 1;
hokeun marked this conversation as resolved.
Show resolved Hide resolved
long long current_num = 2;
vector_t primes = vector_new(10000);
vector_push(&primes, (void*)2);

while (!check_deadline(self)) {
current_num++;
int i = 0;
for (i = 0; i < num_primes; i++) {
if (current_num % (long long)primes.start[i] == 0) {
break;
}
}
if (i == num_primes) {
// Add the prime to vector.
vector_push(&primes, (void*)current_num);
num_primes++;
}
}

// Output the largest prime found.
SET(out, (long long)primes.start[num_primes - 1]);
=} deadline (3 sec) {=
info_print("Deadline handler called!");
=}
}

reactor Print {
input in:int;
reaction(in) {=
printf("Largest prime found within the deadline: %d\n", in->value);
=}
}

main reactor AnytimePrime {
p = new Prime();
d = new Print();
p.out -> d.in;
}
hokeun marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 1 addition & 1 deletion org.lflang/src/lib/c/reactor-c
1 change: 1 addition & 0 deletions org.lflang/src/org/lflang/generator/c/CGenerator.xtend
Original file line number Diff line number Diff line change
Expand Up @@ -2772,6 +2772,7 @@ class CGenerator extends GeneratorBase {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
«structType»* self = («structType»*)instance_args;
((self_base_t*)self)->executing_reaction = &self->_lf__reaction_«reactionIndex»;
''')
}

Expand Down