Pakman
SerialMaster.cc
1 #include <string>
2 #include <memory>
3 #include <utility>
4 
5 #include <assert.h>
6 
7 #include "system/system_call.h"
8 #include "controller/AbstractController.h"
9 
10 #include "SerialMaster.h"
11 
12 // Construct from pointer to program terminated flag
14  bool *p_program_terminated) : AbstractMaster(p_program_terminated),
15  m_simulator(simulator)
16 {
17 }
18 
19 // Probe whether Master is active
21 {
22  return m_state != terminated;
23 }
24 
25 // Iterate
27 {
28  // This function should never be called recursively
29  assert(!m_entered);
30  m_entered = true;
31 
32  // This function should never be called if the Master has
33  // terminated
34  assert(m_state != terminated);
35 
36  // Check for program termination interrupt
37  if (programTerminated())
38  {
39  // Terminate Master
40  m_state = terminated;
41  return;
42  }
43 
44  // If there is at least one pending task, execute the task
45  processTask();
46 
47  // Call controller
48  if (auto p_controller = m_p_controller.lock())
49  p_controller->iterate();
50 
51  m_entered = false;
52 }
53 
54 // Returns true if more pending tasks are needed
56 {
57  return m_pending_tasks.size() < 1;
58 }
59 
60 // Push pending task
61 void SerialMaster::pushPendingTask(const std::string& input_string)
62 {
63  m_pending_tasks.push(input_string);
64 }
65 
66 // Returns whether finished tasks queue is empty
68 {
69  return m_finished_tasks.empty();
70 }
71 
72 // Returns reference to front finished task
74 {
75  return m_finished_tasks.front();
76 }
77 
78 // Pop finished task
80 {
81  m_finished_tasks.pop();
82 }
83 
84 // Flush finished and pending tasks
86 {
87  while (!m_finished_tasks.empty()) m_finished_tasks.pop();
88  while (!m_pending_tasks.empty()) m_pending_tasks.pop();
89 }
90 
91 // Terminate Master
93 {
94  m_state = terminated;
95  return;
96 }
97 
98 // Processes a task from pending queue if there is one and places it in
99 // the finished queue when done.
100 void SerialMaster::processTask()
101 {
102  // Return immediately if there are no pending tasks
103  if (m_pending_tasks.empty())
104  return;
105 
106  // Else, pop a pending task, process it and push it to the finished queue
107  TaskHandler& current_task = m_pending_tasks.front();
108 
109  // Process current task and get output string and error code
110  std::string output_string;
111  int error_code;
112  std::tie(output_string, error_code) =
113  system_call_error_code(m_simulator, current_task.getInputString());
114 
115  // Record output string and error code
116  current_task.recordOutputAndErrorCode(output_string, error_code);
117 
118  // Move task to finished queue
119  m_finished_tasks.push(std::move(m_pending_tasks.front()));
120 
121  // Pop pending queue
122  m_pending_tasks.pop();
123 }
virtual void iterate() override
Definition: SerialMaster.cc:26
virtual bool needMorePendingTasks() const override
Definition: SerialMaster.cc:55
virtual TaskHandler & frontFinishedTask() override
Definition: SerialMaster.cc:73
virtual bool finishedTasksEmpty() const override
Definition: SerialMaster.cc:67
virtual void popFinishedTask() override
Definition: SerialMaster.cc:79
std::weak_ptr< AbstractController > m_p_controller
bool programTerminated() const
virtual void pushPendingTask(const std::string &input_string) override
Definition: SerialMaster.cc:61
SerialMaster(const Command &simulator, bool *p_program_terminated)
Definition: SerialMaster.cc:13
std::string getInputString() const
Definition: TaskHandler.cc:46
void recordOutputAndErrorCode(const std::string &output_string, int error_code)
Definition: TaskHandler.cc:67
virtual void flush() override
Definition: SerialMaster.cc:85
virtual void terminate() override
Definition: SerialMaster.cc:92
virtual bool isActive() const override
Definition: SerialMaster.cc:20