42 #include <app_util_platform.h> 52 struct process *process_list = NULL;
53 struct process *process_current = NULL;
55 static process_event_t lastevent;
66 static volatile process_num_events_t nevents;
67 static volatile process_num_events_t fevent;
68 static volatile struct event_data events[PROCESS_CONF_NUMEVENTS];
70 #if PROCESS_CONF_STATS 71 process_num_events_t process_maxevents;
74 static volatile unsigned char poll_requested;
76 #define PROCESS_STATE_NONE 0 77 #define PROCESS_STATE_RUNNING 1 78 #define PROCESS_STATE_CALLED 2 80 static void call_process(
struct process *p, process_event_t ev, process_data_t
data);
87 #define PRINTF(...) printf(__VA_ARGS__) 106 for(q = process_list; q != p && q != NULL; q = q->next);
113 p->next = process_list;
115 p->state = PROCESS_STATE_RUNNING;
118 PRINTF(
"process: starting '%s'\n", PROCESS_NAME_STRING(p));
125 exit_process(
struct process *p,
struct process *fromprocess)
127 register struct process *q;
128 struct process *old_current = process_current;
130 PRINTF(
"process: exit_process '%s'\n", PROCESS_NAME_STRING(p));
134 for(q = process_list; q != p && q != NULL; q = q->next);
141 p->state = PROCESS_STATE_NONE;
148 for(q = process_list; q != NULL; q = q->next) {
150 call_process(q, PROCESS_EVENT_EXITED, (process_data_t)p);
154 if(p->thread != NULL && p != fromprocess) {
157 p->thread(&p->pt, PROCESS_EVENT_EXIT, NULL);
161 if(p == process_list) {
162 process_list = process_list->next;
164 for(q = process_list; q != NULL; q = q->next) {
172 process_current = old_current;
176 call_process(
struct process *p, process_event_t ev, process_data_t
data)
181 if(p->state == PROCESS_STATE_CALLED) {
182 printf(
"process: process '%s' called again with event %d\n", PROCESS_NAME_STRING(p), ev);
186 if((p->state & PROCESS_STATE_RUNNING) &&
188 PRINTF(
"process: calling process '%s' with event %d\n", PROCESS_NAME_STRING(p), ev);
190 p->state = PROCESS_STATE_CALLED;
191 ret = p->thread(&p->pt, ev, data);
192 if(ret == PT_EXITED ||
194 ev == PROCESS_EVENT_EXIT) {
197 p->state = PROCESS_STATE_RUNNING;
211 lastevent = PROCESS_EVENT_MAX;
213 nevents = fevent = 0;
214 #if PROCESS_CONF_STATS 215 process_maxevents = 0;
218 process_current = process_list = NULL;
232 for(p = process_list; p != NULL; p = p->next) {
234 p->state = PROCESS_STATE_RUNNING;
236 call_process(p, PROCESS_EVENT_POLL, NULL);
249 static process_event_t ev;
250 static process_data_t
data;
251 static struct process *receiver;
252 static struct process *p;
264 CRITICAL_REGION_ENTER();
267 ev = events[fevent].ev;
269 data = events[fevent].data;
270 receiver = events[fevent].p;
274 fevent = (fevent + 1) % PROCESS_CONF_NUMEVENTS;
277 CRITICAL_REGION_EXIT();
281 if(receiver == PROCESS_BROADCAST) {
282 for(p = process_list; p != NULL; p = p->next) {
289 call_process(p, ev, data);
296 if(ev == PROCESS_EVENT_INIT) {
297 receiver->state = PROCESS_STATE_RUNNING;
301 call_process(receiver, ev, data);
317 return nevents + poll_requested;
323 return nevents + poll_requested;
329 static process_num_events_t snum;
333 PRINTF(
"process_post: NULL process posts event %d to process '%s', nevents %d\n",
334 ev,PROCESS_NAME_STRING(p), nevents);
336 PRINTF(
"process_post: Process '%s' posts event %d to process '%s', nevents %d\n",
338 p == PROCESS_BROADCAST?
"<broadcast>": PROCESS_NAME_STRING(p), nevents);
341 CRITICAL_REGION_ENTER();
342 if(nevents == PROCESS_CONF_NUMEVENTS) {
344 if(p == PROCESS_BROADCAST) {
345 printf(
"soft panic: event queue is full when broadcast event %d was posted from %s\n", ev, PROCESS_NAME_STRING(process_current));
347 printf(
"soft panic: event queue is full when event %d was posted to %s frpm %s\n", ev, PROCESS_NAME_STRING(p), PROCESS_NAME_STRING(process_current));
352 snum = (process_num_events_t)(fevent + nevents) % PROCESS_CONF_NUMEVENTS;
353 events[snum].ev = ev;
354 events[snum].data =
data;
358 #if PROCESS_CONF_STATS 359 if(nevents > process_maxevents) {
360 process_maxevents = nevents;
368 CRITICAL_REGION_EXIT();
376 struct process *caller = process_current;
378 call_process(p, ev, data);
379 process_current = caller;
386 CRITICAL_REGION_ENTER();
388 process_num_events_t index = fevent;
389 process_num_events_t count = nevents;
390 process_num_events_t next;
393 for (; count != 0; index = next, --count) {
394 next = (index + 1) % PROCESS_CONF_NUMEVENTS;
395 if (events[index].p != p || events[index].ev != ev)
398 *pdata = events[index].data;
405 for (; count > 1; index = next, --count) {
406 next = (index + 1) % PROCESS_CONF_NUMEVENTS;
407 events[index] = events[next];
410 CRITICAL_REGION_EXIT();
419 if(p->state == PROCESS_STATE_RUNNING ||
420 p->state == PROCESS_STATE_CALLED) {
431 return p->state != PROCESS_STATE_NONE;
void process_poll(struct process *p)
void process_start(struct process *p, const char *arg)
void process_exit(struct process *p)
Cause a process to exit.
process_event_t process_alloc_event(void)
Allocate a global event number.
Header file for the EVE power management framework.
int process_abort_event(struct process *p, process_event_t ev, void **pdata)
#define PROCESS_ERR_FULL
Return value indicating that the event queue was full.
#define PROCESS_ERR_OK
Return value indicating that an operation was successful.
#define PROCESS_CURRENT()
int process_post(struct process *p, process_event_t ev, process_data_t data)
void process_init(void)
Initialize the process module.
uint8_t data[USBNET_RX_BUF_SIZE]
int process_nevents(void)
void process_post_synch(struct process *p, process_event_t ev, process_data_t data)
int process_is_running(struct process *p)