diff --git a/core/sys/process.c b/core/sys/process.c index 10cb2616b..ff3a14e3f 100644 --- a/core/sys/process.c +++ b/core/sys/process.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.c,v 1.5 2007/04/04 09:19:18 nifi Exp $ + * @(#)$Id: process.c,v 1.6 2008/01/23 15:18:06 adamdunkels Exp $ */ /** @@ -49,6 +49,8 @@ #include "sys/process.h" #include "sys/arg.h" +PROCESS_NAME(simple_cc2420_process); + /* * Pointer to the currently running process structure. */ @@ -66,20 +68,18 @@ struct event_data { struct process *p; }; -#ifdef PROCESS_CONF_FASTPOLL -#define NPOLLS PROCESS_CONF_FASTPOLL -static volatile unsigned npolls; -static struct process *needpoll[NPOLLS]; -#endif static process_num_events_t nevents, fevent; static struct event_data events[PROCESS_CONF_NUMEVENTS]; +#if PROCESS_CONF_STATS +process_num_events_t process_maxevents; +#endif + static volatile unsigned char poll_requested; #define PROCESS_STATE_NONE 0 -#define PROCESS_STATE_INIT 1 -#define PROCESS_STATE_RUNNING 2 -#define PROCESS_STATE_NEEDS_POLL 3 +#define PROCESS_STATE_RUNNING 1 +#define PROCESS_STATE_CALLED 2 static void call_process(struct process *p, process_event_t ev, process_data_t data); @@ -99,7 +99,7 @@ process_alloc_event(void) } /*---------------------------------------------------------------------------*/ void -process_start(struct process *p, char *arg) +process_start(struct process *p, const char *arg) { struct process *q; @@ -114,13 +114,13 @@ process_start(struct process *p, char *arg) /* Put on the procs list.*/ p->next = process_list; process_list = p; - - p->state = PROCESS_STATE_INIT; - + p->state = PROCESS_STATE_RUNNING; PT_INIT(&p->pt); - - /* Post an asynchronous event to the process. */ - process_post(p, PROCESS_EVENT_INIT, (process_data_t)arg); + + PRINTF("process: starting '%s'\n", p->name); + + /* Post a synchronous initialization event to the process. */ + process_post_synch(p, PROCESS_EVENT_INIT, (process_data_t)arg); } /*---------------------------------------------------------------------------*/ static void @@ -129,7 +129,9 @@ exit_process(struct process *p, struct process *fromprocess) register struct process *q; struct process *old_current = process_current; - if(p->state != PROCESS_STATE_NONE) { + PRINTF("process: exit_process '%s'\n", p->name); + + if(process_is_running(p)) { /* Process was running */ p->state = PROCESS_STATE_NONE; @@ -168,20 +170,13 @@ exit_process(struct process *p, struct process *fromprocess) for(n = nevents; n > 0; n--) { if(events[i].p == p) { events[i].p = PROCESS_ZOMBIE; -#if 0 +#if DEBUG printf("soft panic: exiting process has remaining event 0x%x\n", events[i].ev); #endif } i = (i + 1) % PROCESS_CONF_NUMEVENTS; } -#ifdef NPOLLS - for(i = 0; i < NPOLLS && i < npolls; i++) { - if(needpoll[i] == p) { - needpoll[i] = PROCESS_ZOMBIE; - } - } -#endif } process_current = old_current; } @@ -190,17 +185,25 @@ static void call_process(struct process *p, process_event_t ev, process_data_t data) { int ret; - - if((p->state == PROCESS_STATE_RUNNING || - p->state == PROCESS_STATE_NEEDS_POLL) && - p->thread != NULL) { - process_current = p; +#if DEBUG + if(p->state == PROCESS_STATE_CALLED) { + printf("process: process '%s' called again with event %d\n", p->name, ev); + } +#endif /* DEBUG */ + + if((p->state & PROCESS_STATE_RUNNING) && + p->thread != NULL) { + PRINTF("process: calling process '%s' with event %d\n", p->name, ev); + process_current = p; + p->state = PROCESS_STATE_CALLED; ret = p->thread(&p->pt, ev, data); if(ret == PT_EXITED || ret == PT_ENDED || ev == PROCESS_EVENT_EXIT) { exit_process(p, p); + } else { + p->state = PROCESS_STATE_RUNNING; } } } @@ -217,6 +220,9 @@ process_init(void) lastevent = PROCESS_EVENT_MAX; nevents = fevent = 0; +#if PROCESS_CONF_STATS + process_maxevents = 0; +#endif /* PROCESS_CONF_STATS */ process_current = process_list = NULL; } @@ -229,56 +235,18 @@ static void do_poll(void) { struct process *p; - - poll_requested = 0; - -#ifdef NPOLLS - unsigned i; - int s; - /* Fastpoll */ - //printf("F %d\n", npolls); - for(i = 0; i < npolls; i++) { - do_more: - if(i == NPOLLS) { - goto slowpoll; - } - if(needpoll[i] != PROCESS_ZOMBIE - && needpoll[i]->state == PROCESS_STATE_NEEDS_POLL) { - needpoll[i]->state = PROCESS_STATE_RUNNING; - call_process(needpoll[i], PROCESS_EVENT_POLL, NULL); - } - } - s = splhigh(); - if(i == npolls) { - npolls = 0; - splx(s); - return; - } - splx(s); - goto do_more; - /* Call poll handlers. */ - slowpoll: - //printf("S %d\n", npolls); - npolls = 0; -#endif - /* Call poll handlers. */ - for(p = process_list; p != NULL; p = p->next) { - - if(p->state == PROCESS_STATE_NEEDS_POLL) { - p->state = PROCESS_STATE_RUNNING; - call_process(p, PROCESS_EVENT_POLL, NULL); + do { + poll_requested = 0; + /* Call the processes that needs to be polled. */ + for(p = process_list; p != NULL; p = p->next) { + if(p->needspoll) { + p->state = PROCESS_STATE_RUNNING; + p->needspoll = 0; + call_process(p, PROCESS_EVENT_POLL, NULL); + } } - -#if 0 - /* If a poll has been requested for one of the processes, we start - from the beginning again. */ - if(poll_requested) { - poll_requested = 0; - p = process_list; - } -#endif - } + } while(poll_requested); } /*---------------------------------------------------------------------------*/ /* @@ -347,12 +315,12 @@ do_event(void) int process_run(void) { - /* Process "poll" events. */ + /* Process poll events. */ if(poll_requested) { do_poll(); } - - /* Process one event */ + + /* Process one event from the queue */ do_event(); return nevents + poll_requested; @@ -361,11 +329,7 @@ process_run(void) int process_nevents(void) { -#ifdef NPOLLS - return nevents + npolls; -#else return nevents + poll_requested; -#endif } /*---------------------------------------------------------------------------*/ int @@ -390,6 +354,12 @@ process_post(struct process *p, process_event_t ev, process_data_t data) events[snum].p = p; ++nevents; +#if PROCESS_CONF_STATS + if(nevents > process_maxevents) { + process_maxevents = nevents; + } +#endif /* PROCESS_CONF_STATS */ + return PROCESS_ERR_OK; } /*---------------------------------------------------------------------------*/ @@ -406,19 +376,18 @@ void process_poll(struct process *p) { if(p != NULL) { - if(p->state == PROCESS_STATE_RUNNING) { - p->state = PROCESS_STATE_NEEDS_POLL; + if(p->state == PROCESS_STATE_RUNNING || + p->state == PROCESS_STATE_CALLED) { + p->needspoll = 1; poll_requested = 1; -#ifdef NPOLLS - int s = splhigh(); - if(npolls < NPOLLS) { - needpoll[npolls] = p; - } - if(npolls != ~0u) npolls++; /* Beware of overflow! */ - splx(s); -#endif } } } /*---------------------------------------------------------------------------*/ +int +process_is_running(struct process *p) +{ + return p->state != PROCESS_STATE_NONE; +} +/*---------------------------------------------------------------------------*/ /** @} */ diff --git a/core/sys/process.h b/core/sys/process.h index e14ad3a0e..92bd7e57e 100644 --- a/core/sys/process.h +++ b/core/sys/process.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: process.h,v 1.12 2007/11/17 22:11:19 adamdunkels Exp $ + * @(#)$Id: process.h,v 1.13 2008/01/23 15:18:06 adamdunkels Exp $ */ /** @@ -275,7 +275,6 @@ typedef unsigned char process_num_events_t; static PT_THREAD(process_thread_##name(struct pt *process_pt, \ process_event_t ev, \ process_data_t data)) - #if PROCESS_LOADABLE #define PROCESS_LOAD(name) const struct process *process_load = &name #else /* PROCESS_LOADABLE */ @@ -320,7 +319,7 @@ struct process { const char *name; PT_THREAD((* thread)(struct pt *, process_event_t, process_data_t)); struct pt pt; - unsigned char state; + unsigned char state, needspoll; }; /** @@ -337,7 +336,7 @@ struct process { * process * */ -void process_start(struct process *p, char *arg); +void process_start(struct process *p, const char *arg); /** * Post an asynchronous event. @@ -497,6 +496,18 @@ void process_init(void); */ int process_run(void); + +/** + * Check if a process is running. + * + * This function checks if a specific process is running. + * + * \param p The process. + * \retval Non-zero if the process is running. + * \retval Zero if the process is not running. + */ +int process_is_running(struct process *p); + /** * Number of events waiting to be processed. *