FW Profile - C1 Implementation
FwRtCore.c
Go to the documentation of this file.
1 
18 #include "FwRtCore.h"
19 #include "FwRtConstants.h"
20 #include <pthread.h>
21 #include <stdlib.h>
22 
29 void* ExecActivThread(void* ptr);
30 
35 void ExecNotifProcedure(FwRtDesc_t rtDesc);
36 
44 void ExecActivProcedure(FwRtDesc_t rtDesc);
45 
46 /*--------------------------------------------------------------------------------------*/
47 void FwRtStart(FwRtDesc_t rtDesc) {
48  int errCode;
49 
50  if ((errCode = pthread_mutex_lock(&(rtDesc->mutex))) != 0) {
51  rtDesc->errCode = errCode;
52  rtDesc->state = rtMutexLockErr;
53  return;
54  }
55 
56  if (rtDesc->state != rtContStopped) {
57  if ((errCode = pthread_mutex_unlock(&(rtDesc->mutex))) != 0) {
58  rtDesc->errCode = errCode;
59  rtDesc->state = rtMutexUnlockErr;
60  return;
61  }
62  return;
63  }
64 
65  /* Start Notification Procedure */
66  rtDesc->notifPrStarted = 1;
67  /* Start Activation Procedure */
68  rtDesc->activPrStarted = 1;
69 
70  /* Execute Notification and Activation Procedures. Since the procedures have just been
71  * started, this is equivalent to executing their initialization actions and (for the
72  * Activation Procedure) its Set Up Notification action. */
73  rtDesc->initializeNotifPr(rtDesc);
74  rtDesc->initializeActivPr(rtDesc);
75  rtDesc->setUpNotification(rtDesc);
76 
77  rtDesc->state = rtContStarted;
78  rtDesc->notifCounter = 0;
79 
80  /* Create thread */
81  if ((errCode = pthread_create(&(rtDesc->activationThread), rtDesc->pThreadAttr, ExecActivThread, rtDesc)) != 0) {
82  rtDesc->errCode = errCode;
83  rtDesc->state = rtThreadCreateErr;
84  return;
85  }
86 
87  if ((errCode = pthread_mutex_unlock(&(rtDesc->mutex))) != 0) {
88  rtDesc->errCode = errCode;
89  rtDesc->state = rtMutexUnlockErr;
90  return;
91  }
92 
93  return;
94 }
95 
96 /*--------------------------------------------------------------------------------------*/
97 void FwRtStop(FwRtDesc_t rtDesc) {
98  int errCode;
99 
100  if ((errCode = pthread_mutex_lock(&(rtDesc->mutex))) != 0) {
101  rtDesc->errCode = errCode;
102  rtDesc->state = rtMutexLockErr;
103  return;
104  }
105 
106  if (rtDesc->state != rtContStarted) {
107  if ((errCode = pthread_mutex_unlock(&(rtDesc->mutex))) != 0) {
108  rtDesc->errCode = errCode;
109  rtDesc->state = rtMutexUnlockErr;
110  return;
111  }
112  return;
113  }
114 
115  /* Stop the RT Container */
116  rtDesc->state = rtContStopped;
117 
118  /* Notify the Activation Thread */
119  rtDesc->notifCounter++;
120 
121  if ((errCode = pthread_cond_signal(&(rtDesc->cond))) != 0) {
122  rtDesc->errCode = errCode;
123  rtDesc->state = rtCondSignalErr;
124  return;
125  }
126 
127  if ((errCode = pthread_mutex_unlock(&(rtDesc->mutex))) != 0) {
128  rtDesc->errCode = errCode;
129  rtDesc->state = rtMutexUnlockErr;
130  return;
131  }
132 
133  return;
134 }
135 
136 /*--------------------------------------------------------------------------------------*/
137 void FwRtNotify(FwRtDesc_t rtDesc) {
138  int errCode;
139 
140  if ((errCode = pthread_mutex_lock(&(rtDesc->mutex))) != 0) {
141  rtDesc->errCode = errCode;
142  rtDesc->state = rtMutexLockErr;
143  return;
144  }
145  ExecNotifProcedure(rtDesc);
146  if ((errCode = pthread_mutex_unlock(&(rtDesc->mutex))) != 0) {
147  rtDesc->errCode = errCode;
148  rtDesc->state = rtMutexUnlockErr;
149  return;
150  }
151 }
152 
153 /*--------------------------------------------------------------------------------------*/
155  int errCode;
156  void* status = 0;
157 
158  if ((errCode = pthread_join(rtDesc->activationThread, &status)) != 0) {
159  rtDesc->errCode = errCode;
160  rtDesc->state = rtJoinErr;
161  return;
162  }
163 }
164 
165 /*--------------------------------------------------------------------------------------*/
167  return rtDesc->notifPrStarted;
168 }
169 
170 /*--------------------------------------------------------------------------------------*/
172  return rtDesc->activPrStarted;
173 }
174 
175 /*--------------------------------------------------------------------------------------*/
177  return rtDesc->state;
178 }
179 
180 /*--------------------------------------------------------------------------------------*/
182  return rtDesc->errCode;
183 }
184 
185 /*--------------------------------------------------------------------------------------*/
187  return rtDesc->notifCounter;
188 }
189 
190 /*--------------------------------------------------------------------------------------*/
192  int errCode;
193 
194  if (rtDesc->notifPrStarted == 0) {
195  return;
196  }
197 
198  if (rtDesc->activPrStarted == 0) {
199  rtDesc->finalizeNotifPr(rtDesc);
200  rtDesc->notifPrStarted = 0;
201  return;
202  }
203 
204  if (rtDesc->implementNotifLogic(rtDesc) == 1) {
205  rtDesc->notifCounter++;
206  if ((errCode = pthread_cond_signal(&(rtDesc->cond))) != 0) {
207  rtDesc->errCode = errCode;
208  rtDesc->state = rtCondSignalErr;
209  return;
210  }
211  }
212 
213  return;
214 }
215 
216 /*--------------------------------------------------------------------------------------*/
218 
219  if (rtDesc->state == rtContStopped) {
220  rtDesc->finalizeActivPr(rtDesc);
221  rtDesc->activPrStarted = 0;
222  return;
223  }
224 
225  if (rtDesc->implementActivLogic(rtDesc) == 1) { /* Execute functional behaviour */
226  if (rtDesc->execFuncBehaviour(rtDesc) == 1) { /* Functional behaviour is terminated */
227  rtDesc->finalizeActivPr(rtDesc);
228  rtDesc->activPrStarted = 0;
229  return;
230  }
231  }
232  rtDesc->setUpNotification(rtDesc);
233  return;
234 }
235 
236 /*--------------------------------------------------------------------------------------*/
237 void* ExecActivThread(void* ptr) {
238  FwRtDesc_t rtDesc = (FwRtDesc_t)ptr;
239  int errCode;
240 
241  while (1) {
242  if ((errCode = pthread_mutex_lock(&(rtDesc->mutex))) != 0) {
243  rtDesc->errCode = errCode;
244  rtDesc->state = rtMutexLockErr;
245  return NULL;
246  }
247  while (rtDesc->notifCounter == 0) {
248  if ((errCode = pthread_cond_wait(&(rtDesc->cond), &(rtDesc->mutex))) != 0) {
249  rtDesc->errCode = errCode;
250  rtDesc->state = rtCondWaitErr;
251  return NULL;
252  }
253  }
254  rtDesc->notifCounter--;
255  if ((errCode = pthread_mutex_unlock(&(rtDesc->mutex))) != 0) {
256  rtDesc->errCode = errCode;
257  rtDesc->state = rtMutexUnlockErr;
258  return NULL;
259  }
260 
261  ExecActivProcedure(rtDesc);
262 
263  if (rtDesc->activPrStarted == 0) {
264  rtDesc->state = rtContStopped; /* Put RT Container in state STOPPED */
265  FwRtNotify(rtDesc); /* Execute Notification Procedure in mutual exclusion */
266  break;
267  }
268 
269  if (rtDesc->state == rtContStopped) {
270  ExecActivProcedure(rtDesc);
271  FwRtNotify(rtDesc); /* Execute Notification Procedure in mutual exclusion */
272  break;
273  }
274  }
275 
276  return NULL;
277 }
pthread_t activationThread
The thread associated to the RT Container.
The function to wait on a condition has reported an error.
Definition: FwRtConstants.h:84
The function to unlock the container mutex has reported an error.
Definition: FwRtConstants.h:80
void ExecActivProcedure(FwRtDesc_t rtDesc)
Execute the loop in the Activation Procedure.
Definition: FwRtCore.c:217
void * ExecActivThread(void *ptr)
The Activation Thread of the RT Container.
Definition: FwRtCore.c:237
FwRtState_t state
The state of the RT Container.
Declaration of the API for a RT Container.
Header file to define all constants and types for the RT Container Module of the FW Profile...
The RT Container is in state STOPPED.
Definition: FwRtConstants.h:64
FwRtAction_t initializeNotifPr
Pointer to the function encapsulating the initialization action for the Notification Procedure...
The function to create the Activation Thread has reported an error.
Definition: FwRtConstants.h:68
void FwRtNotify(FwRtDesc_t rtDesc)
Execute the Notification Procedure of a RT Container.
Definition: FwRtCore.c:137
The function to wait on a thread join has reported an error.
Definition: FwRtConstants.h:98
FwRtAction_t implementNotifLogic
Pointer to the function encapsulating the implementation of the notification logic.
FwRtCounterU2_t notifCounter
The notification counter.
pthread_cond_t cond
The condition variable associated to the RT Container.
FwRtAction_t finalizeActivPr
Pointer to the function encapsulating the finalization action for the Activation Procedure.
int errCode
The return value of the last system call which failed.
void ExecNotifProcedure(FwRtDesc_t rtDesc)
Execute the loop in the Notification Procedure.
Definition: FwRtCore.c:191
FwRtAction_t implementActivLogic
Pointer to the function encapsulating the implementation of the activation logic. ...
FwRtState_t
Enumerated type for the state of the RT Container.
Definition: FwRtConstants.h:60
void FwRtWaitForTermination(FwRtDesc_t rtDesc)
Blocking function which returns when the Activation Thread has terminated.
Definition: FwRtCore.c:154
void FwRtStop(FwRtDesc_t rtDesc)
Stop a RT Container.
Definition: FwRtCore.c:97
FwRtAction_t setUpNotification
Pointer to the function encapsulating the logic to set up the notification for the RT Container...
FwRtAction_t execFuncBehaviour
Pointer to the function encapsulating the execution of the functional behaviour associated to the RT ...
int FwRtGetErrCode(FwRtDesc_t rtDesc)
Return the error code of the RT Container.
Definition: FwRtCore.c:181
void FwRtStart(FwRtDesc_t rtDesc)
Start a RT Container.
Definition: FwRtCore.c:47
pthread_mutex_t mutex
The mutex associated to the RT Container.
FwRtState_t FwRtGetContState(FwRtDesc_t rtDesc)
Return the RT Container state.
Definition: FwRtCore.c:176
struct FwRtDesc * FwRtDesc_t
Forward declaration for the pointer to a RT Container Descriptor.
Definition: FwRtConstants.h:31
FwRtCounterU2_t FwRtGetNotifCounter(FwRtDesc_t rtDesc)
Return the value of the notification counter.
Definition: FwRtCore.c:186
pthread_attr_t * pThreadAttr
The pointer to the Activation Thread attributes.
int FwRtBool_t
Type used for booleans (0 is "false" and 1 is "true").
Definition: FwRtConstants.h:34
FwRtBool_t FwRtIsActivPrStarted(FwRtDesc_t rtDesc)
Check whether the Activation Procedure is started.
Definition: FwRtCore.c:171
FwRtAction_t initializeActivPr
Pointer to the function encapsulating the initialization action for the Activation Procedure...
FwRtBool_t notifPrStarted
The flag indicating whether the Notification Procedure is STÂRTED.
The function to signal a condition has reported an error.
Definition: FwRtConstants.h:82
FwRtBool_t FwRtIsNotifPrStarted(FwRtDesc_t rtDesc)
Check whether the Notification Procedure is started.
Definition: FwRtCore.c:166
short int FwRtCounterU2_t
Type used for unsigned integers with a "medium" range.
Definition: FwRtConstants.h:40
FwRtAction_t finalizeNotifPr
Pointer to the function encapsulating the finalization action for the Notification Procedure...
The function to lock the container mutex has reported an error.
Definition: FwRtConstants.h:78
Structure representing a RT Container Descriptor.
The RT Container is in state STARTED.
Definition: FwRtConstants.h:66
FwRtBool_t activPrStarted
The flag indicating whether the Activation Procedure is STÂRTED.
P&P Software GmbH, Copyright 2011, All Rights Reserved