lf-lang / lingua-franca

Intuitive concurrent programming in any language
https://www.lf-lang.org
Other
220 stars 57 forks source link

Not able to convert c type time data to Lingua franca time data type #2317

Open roy-mamata opened 2 weeks ago

roy-mamata commented 2 weeks ago

I want the deadline parameter to be read from a text file in place of hardcoding it .(The text file is returning interval_t c data type or integer or character data type) Now how to convert the c data type of text file content to lingua franca data type (time data type) as deadline takes only time data type of lingua franca. Here is the example code:

target C {
  keepalive: true
}

preamble {=
  #include <unistd.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <time.h>
  #include "platform.h" // Defines PRINTF_TIME and thread functions  
  interval_t read_time();
=}

reactor Sensor {
  preamble {=
    void* read_input(void* response) {
      int c;
      while(1) {
        while((c = getchar()) != '\n') {
          if (c == EOF) {
            lf_request_stop();
            break;
          }
        }
        lf_schedule(response, 0);
        if (c == EOF) {
          break;
        }
      }
      return NULL;
    }
  =}

  physical action response
  output y: bool

  reaction(startup) -> response {=
    lf_thread_t thread_id;
    lf_thread_create(&thread_id, &read_input, response);
    printf("Press Enter to produce a sensor value.\n");
  =}

  reaction(response) -> y {=
    printf("Reacting to physical action at %lld\n", lf_time_logical_elapsed());
    lf_set(y, true);
  =}
}

reactor Analysis {
  input x: bool
  output y: bool
  state do_work: bool = false

  reaction(x) -> y {=
    if (self->do_work) {
      printf("Working for 500 ms...\n");
      usleep(500);
    } else {
      printf("Skipping work!\n");
    }
    self->do_work = !self->do_work;
    lf_set(y, true);
  =}
}

reactor Actuator(dd_time:interval_t ={= read_time() =}) {
  input x: bool

  reaction(x) {=
    lf_print("%ld",self->dd_time);
    instant_t l = lf_time_logical_elapsed();
    instant_t p = lf_time_physical_elapsed();
    lf_print("Actuating... Logical time: " PRINTF_TIME
        ". Physical time: " PRINTF_TIME ". Lag: " PRINTF_TIME,
        l, p, p-l);
  =} deadline(dd_time) {=
    instant_t d = lf_time_physical_elapsed()
        - lf_time_logical_elapsed();
    lf_print("***** Deadline missed! Lag: " PRINTF_TIME
        " (too late by " PRINTF_TIME " nsecs)",
        d, d-500000);
  =}
}

main reactor {
    preamble {=
     interval_t read_time() {
      FILE *file = fopen("/home/mamata/deadline.txt", "r");  //provide the text file path
      if (!file) {
        perror("Failed to open file");
        exit(EXIT_FAILURE);
      }
      int milliseconds;
      if (fscanf(file, "%d", &milliseconds) != 1) {
        perror("Failed to read the deadline from file");
        fclose(file);
        exit(EXIT_FAILURE);
      }
      fclose(file);

     return milliseconds;
     }
  =}  
  sense = new Sensor()
  analyze = new Analysis()
  actuate = new Actuator(dd_time={= read_time() =})
  sense.y -> analyze.x
  analyze.y -> actuate.x
} 

Below is the issue log I am getting:

lfc: info: Generating sources into: /home/mamata/playground-lingua-franca/examples/C/src-gen/deadlines/Deadline_test lfc: info: Target Configuration:

  • keepalive: true lfc: fatal error: Error running generator java.lang.NullPointerException: Cannot invoke "org.lflang.TimeValue.toNanoSeconds()" because "o" is null at org.lflang.TimeValue.compareTo(TimeValue.java:124) at org.lflang.generator.ReactionInstanceGraph.addDownstreamReactions(ReactionInstanceGraph.java:165) at org.lflang.generator.ReactionInstanceGraph.addNodesAndEdges(ReactionInstanceGraph.java:230) at org.lflang.generator.ReactionInstanceGraph.addNodesAndEdges(ReactionInstanceGraph.java:236) at org.lflang.generator.ReactionInstanceGraph.rebuild(ReactionInstanceGraph.java:81) at org.lflang.generator.ReactionInstanceGraph.(ReactionInstanceGraph.java:64) at org.lflang.generator.ReactorInstance.assignLevels(ReactorInstance.java:205) at org.lflang.ast.ASTUtils.createMainReactorInstance(ASTUtils.java:621) at org.lflang.generator.c.CGenerator.setUpGeneralParameters(CGenerator.java:1966) at org.lflang.generator.c.CGenerator.doGenerate(CGenerator.java:412) at org.lflang.generator.LFGenerator.doGenerate(LFGenerator.java:114) at org.eclipse.xtext.generator.GeneratorDelegate.doGenerate(GeneratorDelegate.java:44) at org.eclipse.xtext.generator.GeneratorDelegate.generate(GeneratorDelegate.java:35) at org.lflang.cli.Lfc.invokeGenerator(Lfc.java:242) at org.lflang.cli.Lfc.doRun(Lfc.java:201) at org.lflang.cli.CliBase.run(CliBase.java:124) at picocli.CommandLine.executeUserObject(CommandLine.java:2026) at picocli.CommandLine.access$1500(CommandLine.java:148) at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2461) at picocli.CommandLine$RunLast.handle(CommandLine.java:2453) at picocli.CommandLine$RunLast.handle(CommandLine.java:2415) at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2273)
edwardalee commented 1 week ago

Yes, currently deadlines can only be constants or parameters in the C target. I'm pretty sure this could be supported, but it would take a little work in the code generator, particularly the code that handles deadline inference for upstream reactions.

roy-mamata commented 1 week ago

Could you please explain a bit exactly how I can approach for this issue.

Yes, currently deadlines can only be constants or parameters in the C target. I'm pretty sure this could be supported, but it would take a little work in the code generator, particularly the code that handles deadline inference for upstream reactions.