SystemC 41 Interrupt a thread while busy - template class


This example achieves same purpose as previous one. However, a template class is provided to simplify the logic.

With the provided BufferTrigger_t class, a child class can be derived from it, and implements the task_handler(), and interrupt_handler() function. The child class shall also make sure the trigger is notified.


Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Learn with Examples, 2020, MIT license
#include <systemc>
using namespace sc_core;
struct sc_event2 : sc_event { // first extend sc_event, to allow pause/resume
  sc_time remainningTime, doneTime;
  bool isRunning = false;
  void notify(sc_time t) {
    isRunning = true;
    remainningTime = t;
    doneTime = sc_time_stamp() + remainningTime;
    sc_event::notify(t);
  }
  void pause() {
    remainningTime = doneTime - sc_time_stamp();
    cancel();
  }
  void resume() {
    notify(remainningTime);
  }
  void abort() {
    isRunning = false;
    cancel();
  }
  operator bool() {
    return isRunning;
  }
};

SC_MODULE(AllowIntrrupt_t) {
  sc_event task, dispatchTask, interrupt;
  sc_event2 taskDone; // allow being interrupted
  int option; // different options: abort or pause/resume
  SC_HAS_PROCESS(AllowIntrrupt_t);
  AllowIntrrupt_t(sc_module_name name, int option = 0) : sc_module(name), option(option) {
    SC_THREAD(task_handler); // receive task trigger, dispatch task
    sensitive << task;
    dont_initialize();
    
    SC_THREAD(task_processor); // process task
    sensitive << dispatchTask;
    dont_initialize();

    SC_THREAD(task_done); // callback when task completes
    sensitive << taskDone;
    dont_initialize();

    SC_THREAD(interrupt_handler); // receive interrupt
    sensitive << interrupt;
    dont_initialize();
  }
  void task_handler() {
    while (true) {
      dispatchTask.notify(); // dispatch the task
      wait();
    }
  }
  void interrupt_handler() {
    while (true) {
      std::cout << name() << ": Task interrupted at " << sc_time_stamp().to_seconds() << std::endl;
      (option == 1 && taskDone) ? taskDone.pause() : taskDone.abort(); // pause if option 1 && isRunning
      interrupt_processor();
      if (option == 1 && taskDone) { // result
        taskDone.resume();
      }
      wait();
    }
  }
  void task_done() {
    while (true) {
      taskDone.isRunning = false;
      std::cout << name() << ": Task complete at " << sc_time_stamp().to_seconds() << std::endl;
      wait();
    }
  }
  virtual void task_processor() = 0;
  virtual void interrupt_processor() = 0;
};

struct MODULE2 : AllowIntrrupt_t {
  SC_HAS_PROCESS(MODULE2);
  MODULE2(sc_module_name name, int option) : AllowIntrrupt_t(name, option) {
    SC_THREAD(task_trigger);
    SC_THREAD(interrupt_trigger);
  }
  void interrupt_processor() { // interruption will consume 0.3 second
    wait(0.3, SC_SEC);
  }
  void task_processor() {
    while (true) {
      std::cout << name() << ": Task start at " << sc_time_stamp().to_seconds() << std::endl;
      taskDone.notify(sc_time(0.5, SC_SEC)); // process takes 0.5 second to finish
      wait();
    }
  }
  void task_trigger() {
    while (sc_time_stamp() < sc_time(2, SC_SEC)) { // fire trigger every second for 2 seconds
      task.notify();
      wait(1, SC_SEC);
    }
  }
  void interrupt_trigger() {
    wait(0.2, SC_SEC); // interrupt fired 0.2 sec after task is triggered
    while (sc_time_stamp() < sc_time(2, SC_SEC)) { // fire interrupt every second for 2 seconds
      interrupt.notify();
      wait(1, SC_SEC);
    }
  }
};
int sc_main(int, char*[]) {
  MODULE2 module2a("module2a", 0); // task will abort
  MODULE2 module2b("module2b", 1); // task will pause, and resume after interruption
  sc_start(); // run simulation
  return 0;
}


Reference

Notes Mentioning This Note

Table of Contents


Share on: