54 struct process *process_list =
NULL;
55 struct process *process_current =
NULL;
57 static process_event_t lastevent;
68 static process_num_events_t nevents, fevent;
69 static struct event_data events[PROCESS_CONF_NUMEVENTS];
71 #if PROCESS_CONF_STATS
72 process_num_events_t process_maxevents;
75 static volatile unsigned char poll_requested;
77 #define PROCESS_STATE_NONE 0
78 #define PROCESS_STATE_RUNNING 1
79 #define PROCESS_STATE_CALLED 2
81 static void call_process(
struct process *p, process_event_t ev, process_data_t data);
86 #define PRINTF(...) printf(__VA_ARGS__)
105 for(q = process_list; q != p && q !=
NULL; q = q->next);
112 p->next = process_list;
114 p->state = PROCESS_STATE_RUNNING;
117 PRINTF(
"process: starting '%s'\n", PROCESS_NAME_STRING(p));
124 exit_process(
struct process *p,
struct process *fromprocess)
126 register struct process *q;
127 struct process *old_current = process_current;
129 PRINTF(
"process: exit_process '%s'\n", PROCESS_NAME_STRING(p));
133 for(q = process_list; q != p && q !=
NULL; q = q->next);
140 p->state = PROCESS_STATE_NONE;
147 for(q = process_list; q !=
NULL; q = q->next) {
149 call_process(q, PROCESS_EVENT_EXITED, (process_data_t)p);
153 if(p->thread !=
NULL && p != fromprocess) {
156 p->thread(&p->pt, PROCESS_EVENT_EXIT,
NULL);
160 if(p == process_list) {
161 process_list = process_list->next;
163 for(q = process_list; q !=
NULL; q = q->next) {
171 process_current = old_current;
175 call_process(
struct process *p, process_event_t ev, process_data_t data)
180 if(p->state == PROCESS_STATE_CALLED) {
181 printf(
"process: process '%s' called again with event %d\n", PROCESS_NAME_STRING(p), ev);
185 if((p->state & PROCESS_STATE_RUNNING) &&
187 PRINTF(
"process: calling process '%s' with event %d\n", PROCESS_NAME_STRING(p), ev);
189 p->state = PROCESS_STATE_CALLED;
190 ret = p->thread(&p->pt, ev, data);
191 if(ret == PT_EXITED ||
193 ev == PROCESS_EVENT_EXIT) {
196 p->state = PROCESS_STATE_RUNNING;
210 lastevent = PROCESS_EVENT_MAX;
212 nevents = fevent = 0;
213 #if PROCESS_CONF_STATS
214 process_maxevents = 0;
217 process_current = process_list =
NULL;
231 for(p = process_list; p !=
NULL; p = p->next) {
233 p->state = PROCESS_STATE_RUNNING;
235 call_process(p, PROCESS_EVENT_POLL,
NULL);
248 static process_event_t ev;
249 static process_data_t data;
250 static struct process *receiver;
251 static struct process *p;
264 ev = events[fevent].ev;
266 data = events[fevent].data;
267 receiver = events[fevent].p;
271 fevent = (fevent + 1) % PROCESS_CONF_NUMEVENTS;
276 if(receiver == PROCESS_BROADCAST) {
277 for(p = process_list; p !=
NULL; p = p->next) {
284 call_process(p, ev, data);
291 if(ev == PROCESS_EVENT_INIT) {
292 receiver->state = PROCESS_STATE_RUNNING;
296 call_process(receiver, ev, data);
312 return nevents + poll_requested;
318 return nevents + poll_requested;
322 process_post(
struct process *p, process_event_t ev, process_data_t data)
324 static process_num_events_t snum;
327 PRINTF(
"process_post: NULL process posts event %d to process '%s', nevents %d\n",
328 ev,PROCESS_NAME_STRING(p), nevents);
330 PRINTF(
"process_post: Process '%s' posts event %d to process '%s', nevents %d\n",
332 p == PROCESS_BROADCAST?
"<broadcast>": PROCESS_NAME_STRING(p), nevents);
335 if(nevents == PROCESS_CONF_NUMEVENTS) {
337 if(p == PROCESS_BROADCAST) {
338 printf(
"soft panic: event queue is full when broadcast event %d was posted from %s\n", ev, PROCESS_NAME_STRING(process_current));
340 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));
346 snum = (process_num_events_t)(fevent + nevents) % PROCESS_CONF_NUMEVENTS;
347 events[snum].ev = ev;
348 events[snum].data = data;
352 #if PROCESS_CONF_STATS
353 if(nevents > process_maxevents) {
354 process_maxevents = nevents;
364 struct process *caller = process_current;
366 call_process(p, ev, data);
367 process_current = caller;
374 if(p->state == PROCESS_STATE_RUNNING ||
375 p->state == PROCESS_STATE_CALLED) {
385 return p->state != PROCESS_STATE_NONE;
#define PROCESS_CURRENT()
Get a pointer to the currently running process.
int process_is_running(struct process *p)
Check if a process is running.
void process_poll(struct process *p)
Request a process to be polled.
int process_nevents(void)
Number of events waiting to be processed.
#define PROCESS_ERR_OK
Return value indicating that an operation was successful.
void process_post_synch(struct process *p, process_event_t ev, process_data_t data)
Post a synchronous event to a process.
#define NULL
The null pointer.
#define PT_INIT(pt)
Initialize a protothread.
process_event_t process_alloc_event(void)
Allocate a global event number.
void process_init(void)
Initialize the process module.
int process_post(struct process *p, process_event_t ev, process_data_t data)
Post an asynchronous event.
#define PROCESS_ERR_FULL
Return value indicating that the event queue was full.
void process_start(struct process *p, process_data_t data)
Start a process.
int process_run(void)
Run the system once - call poll handlers and process one event.
Header file for the Contiki process interface.
void process_exit(struct process *p)
Cause a process to exit.