松岗网站建设,重庆今天刚刚发生的新闻,wordpress+中文站,最新wordpress知更鸟00. 目录 文章目录 00. 目录01. 进程类型02. 进程结构03. 事件04. 进程调度函数05. 程序实例06. process实现07. 附录 01. 进程类型 进程类型主要有**协同式#xff08;cooperative#xff09;和抢占式#xff08;preemptive#xff09;**两种。
协同式进程#xff0c;要…00. 目录 文章目录 00. 目录01. 进程类型02. 进程结构03. 事件04. 进程调度函数05. 程序实例06. process实现07. 附录 01. 进程类型 进程类型主要有**协同式cooperative和抢占式preemptive**两种。
协同式进程要等其他进程运行完进程实体函数进程不一定运行完这个时候有可能是阻塞总之只要执行到return语句具体看然后才能开始运行。
抢占式进程会优先运行当有抢占式进程需要执行时协同式进程将会被挂起直到抢占式进程实体函数执行完毕。中断和实时任务就需要用抢占式进程实现。
02. 进程结构
2.1 进程结构体
struct process {struct process *next;//指向下个进程结构体在进程链表中使用
#if PROCESS_CONF_NO_PROCESS_NAMES//配置进程字符串名字
#define PROCESS_NAME_STRING(process) //没有空
#else//有字符串名字const char *name;//定义进程字符串名字
#define PROCESS_NAME_STRING(process) (process)-name//取名字
#endifPT_THREAD((* thread)(struct pt *, process_event_t, process_data_t));//进程执行实体函数struct pt pt;//pt结构体存储实体函数阻塞时的位置unsigned char state, needspoll;//state是进程状态needspoll标志进程是否需要优先执行
};2.2 进程链表
process_list -----
只要抓住了进程链表头process_list那么进程的各种操作都做得到了。
2.3 进程执行实体函数
PROCESS_THREAD(hello_world_process, ev, data)
{PROCESS_BEGIN();printf(Hello, world\n);PROCESS_END();
}#define PROCESS_THREAD(name, ev, data) \
static PT_THREAD(process_thread_##name(struct pt *process_pt, \process_event_t ev, \process_data_t data))#define PT_THREAD(name_args) char name_args最后展开为
static char process_thread_hello_world_process(struct pt *process_pt, process_event_t ev, process_data_t data)
{//略
}03. 事件
非同步事件 非同步事件处理中先将事件放到事件队列中然后事件处理程序再把事件传递给接收这个事件的进程。
同步事件 同步事件处理中事件立马就传递给了特定的进程表现为立马执行ProcessB的执行实体函数。
Polling推举
推举某个进程让这个进程尽可能快的执行。抢占式进程的唯一调用方式。
04. 进程调度函数
先处理所有poll的进程再处理一个事件最后返回剩余的事件数。
int
process_run(void)
{/* Process poll events. */if(poll_requested) {do_poll();}/* Process one event from the queue */do_event();return nevents poll_requested;
}源码文件 源码 c o n t i k i contiki contiki\core\sys\process.c 源码 c o n t i k i contiki contiki\core\sys\process.h 05. 程序实例
test.c #include contiki.hPROCESS(example_process, Example process);AUTOSTART_PROCESSES(example_process);PROCESS_THREAD(example_process, ev, data){PROCESS_BEGIN();while(1) {PROCESS_WAIT_EVENT();printf(Got event number %d\n, ev);}PROCESS_END();}06. process实现
process.h
/** Copyright (c) 2005, Swedish Institute of Computer Science* All rights reserved.** Redistribution and use in source and binary forms, with or without* modification, are permitted provided that the following conditions* are met:* 1. Redistributions of source code must retain the above copyright* notice, this list of conditions and the following disclaimer.* 2. Redistributions in binary form must reproduce the above copyright* notice, this list of conditions and the following disclaimer in the* documentation and/or other materials provided with the distribution.* 3. Neither the name of the Institute nor the names of its contributors* may be used to endorse or promote products derived from this software* without specific prior written permission.** THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS AS IS AND* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF* SUCH DAMAGE.** This file is part of the Contiki operating system.**//*** \addtogroup sys* {*//*** \defgroup process Contiki processes** A process in Contiki consists of a single \ref pt protothread.** {*//*** \file* Header file for the Contiki process interface.* \author* Adam Dunkels adamsics.se**/
#ifndef PROCESS_H_
#define PROCESS_H_#include sys/pt.h
#include sys/cc.htypedef unsigned char process_event_t;
typedef void * process_data_t;
typedef unsigned char process_num_events_t;/*** \name Return values* {*//*** \brief Return value indicating that an operation was successful.** This value is returned to indicate that an operation* was successful.*/
#define PROCESS_ERR_OK 0
/*** \brief Return value indicating that the event queue was full.** This value is returned from process_post() to indicate* that the event queue was full and that an event could* not be posted.*/
#define PROCESS_ERR_FULL 1
/* } */#define PROCESS_NONE NULL#ifndef PROCESS_CONF_NUMEVENTS
#define PROCESS_CONF_NUMEVENTS 32
#endif /* PROCESS_CONF_NUMEVENTS */#define PROCESS_EVENT_NONE 0x80
#define PROCESS_EVENT_INIT 0x81
#define PROCESS_EVENT_POLL 0x82
#define PROCESS_EVENT_EXIT 0x83
#define PROCESS_EVENT_SERVICE_REMOVED 0x84
#define PROCESS_EVENT_CONTINUE 0x85
#define PROCESS_EVENT_MSG 0x86
#define PROCESS_EVENT_EXITED 0x87
#define PROCESS_EVENT_TIMER 0x88
#define PROCESS_EVENT_COM 0x89
#define PROCESS_EVENT_MAX 0x8a#define PROCESS_BROADCAST NULL
#define PROCESS_ZOMBIE ((struct process *)0x1)/*** \name Process protothread functions* {*//*** Define the beginning of a process.** This macro defines the beginning of a process, and must always* appear in a PROCESS_THREAD() definition. The PROCESS_END() macro* must come at the end of the process.** \hideinitializer*/
#define PROCESS_BEGIN() PT_BEGIN(process_pt)/*** Define the end of a process.** This macro defines the end of a process. It must appear in a* PROCESS_THREAD() definition and must always be included. The* process exits when the PROCESS_END() macro is reached.** \hideinitializer*/
#define PROCESS_END() PT_END(process_pt)/*** Wait for an event to be posted to the process.** This macro blocks the currently running process until the process* receives an event.** \hideinitializer*/
#define PROCESS_WAIT_EVENT() PROCESS_YIELD()/*** Wait for an event to be posted to the process, with an extra* condition.** This macro is similar to PROCESS_WAIT_EVENT() in that it blocks the* currently running process until the process receives an event. But* PROCESS_WAIT_EVENT_UNTIL() takes an extra condition which must be* true for the process to continue.** \param c The condition that must be true for the process to continue.* \sa PT_WAIT_UNTIL()** \hideinitializer*/
#define PROCESS_WAIT_EVENT_UNTIL(c) PROCESS_YIELD_UNTIL(c)/*** Yield the currently running process.** \hideinitializer*/
#define PROCESS_YIELD() PT_YIELD(process_pt)/*** Yield the currently running process until a condition occurs.** This macro is different from PROCESS_WAIT_UNTIL() in that* PROCESS_YIELD_UNTIL() is guaranteed to always yield at least* once. This ensures that the process does not end up in an infinite* loop and monopolizing the CPU.** \param c The condition to wait for.** \hideinitializer*/
#define PROCESS_YIELD_UNTIL(c) PT_YIELD_UNTIL(process_pt, c)/*** Wait for a condition to occur.** This macro does not guarantee that the process yields, and should* therefore be used with care. In most cases, PROCESS_WAIT_EVENT(),* PROCESS_WAIT_EVENT_UNTIL(), PROCESS_YIELD() or* PROCESS_YIELD_UNTIL() should be used instead.** \param c The condition to wait for.** \hideinitializer*/
#define PROCESS_WAIT_UNTIL(c) PT_WAIT_UNTIL(process_pt, c)
#define PROCESS_WAIT_WHILE(c) PT_WAIT_WHILE(process_pt, c)/*** Exit the currently running process.** \hideinitializer*/
#define PROCESS_EXIT() PT_EXIT(process_pt)/*** Spawn a protothread from the process.** \param pt The protothread state (struct pt) for the new protothread* \param thread The call to the protothread function.* \sa PT_SPAWN()** \hideinitializer*/
#define PROCESS_PT_SPAWN(pt, thread) PT_SPAWN(process_pt, pt, thread)/*** Yield the process for a short while.** This macro yields the currently running process for a short while,* thus letting other processes run before the process continues.** \hideinitializer*/
#define PROCESS_PAUSE() do { \process_post(PROCESS_CURRENT(), PROCESS_EVENT_CONTINUE, NULL); \PROCESS_WAIT_EVENT_UNTIL(ev PROCESS_EVENT_CONTINUE); \
} while(0)/** } end of protothread functions *//*** \name Poll and exit handlers* {*/
/*** Specify an action when a process is polled.** \note This declaration must come immediately before the* PROCESS_BEGIN() macro.** \param handler The action to be performed.** \hideinitializer*/
#define PROCESS_POLLHANDLER(handler) if(ev PROCESS_EVENT_POLL) { handler; }/*** Specify an action when a process exits.** \note This declaration must come immediately before the* PROCESS_BEGIN() macro.** \param handler The action to be performed.** \hideinitializer*/
#define PROCESS_EXITHANDLER(handler) if(ev PROCESS_EVENT_EXIT) { handler; }/** } *//*** \name Process declaration and definition* {*//*** Define the body of a process.** This macro is used to define the body (protothread) of a* process. The process is called whenever an event occurs in the* system, A process always start with the PROCESS_BEGIN() macro and* end with the PROCESS_END() macro.** \hideinitializer*/
#define PROCESS_THREAD(name, ev, data) \
static PT_THREAD(process_thread_##name(struct pt *process_pt, \process_event_t ev, \process_data_t data))/*** Declare the name of a process.** This macro is typically used in header files to declare the name of* a process that is implemented in the C file.** \hideinitializer*/
#define PROCESS_NAME(name) extern struct process name/*** Declare a process.** This macro declares a process. The process has two names: the* variable of the process structure, which is used by the C program,* and a human readable string name, which is used when debugging.* A configuration option allows removal of the readable name to save RAM.** \param name The variable name of the process structure.* \param strname The string representation of the process name.** \hideinitializer*/
#if PROCESS_CONF_NO_PROCESS_NAMES
#define PROCESS(name, strname) \PROCESS_THREAD(name, ev, data); \struct process name { NULL, \process_thread_##name }
#else
#define PROCESS(name, strname) \PROCESS_THREAD(name, ev, data); \struct process name { NULL, strname, \process_thread_##name }
#endif/** } */struct process {struct process *next;
#if PROCESS_CONF_NO_PROCESS_NAMES
#define PROCESS_NAME_STRING(process)
#elseconst char *name;
#define PROCESS_NAME_STRING(process) (process)-name
#endifPT_THREAD((* thread)(struct pt *, process_event_t, process_data_t));struct pt pt;unsigned char state, needspoll;
};/*** \name Functions called from application programs* {*//*** Start a process.** \param p A pointer to a process structure.** \param data An argument pointer that can be passed to the new* process**/
CCIF void process_start(struct process *p, process_data_t data);/*** Post an asynchronous event.** This function posts an asynchronous event to one or more* processes. The handing of the event is deferred until the target* process is scheduled by the kernel. An event can be broadcast to* all processes, in which case all processes in the system will be* scheduled to handle the event.** \param ev The event to be posted.** \param data The auxiliary data to be sent with the event** \param p The process to which the event should be posted, or* PROCESS_BROADCAST if the event should be posted to all processes.** \retval PROCESS_ERR_OK The event could be posted.** \retval PROCESS_ERR_FULL The event queue was full and the event could* not be posted.*/
CCIF int process_post(struct process *p, process_event_t ev, process_data_t data);/*** Post a synchronous event to a process.** \param p A pointer to the process process structure.** \param ev The event to be posted.** \param data A pointer to additional data that is posted together* with the event.*/
CCIF void process_post_synch(struct process *p,process_event_t ev, process_data_t data);/*** \brief Cause a process to exit* \param p The process that is to be exited** This function causes a process to exit. The process can* either be the currently executing process, or another* process that is currently running.** \sa PROCESS_CURRENT()*/
CCIF void process_exit(struct process *p);/*** Get a pointer to the currently running process.** This macro get a pointer to the currently running* process. Typically, this macro is used to post an event to the* current process with process_post().** \hideinitializer*/
#define PROCESS_CURRENT() process_current
CCIF extern struct process *process_current;/*** Switch context to another process** This function switch context to the specified process and executes* the code as if run by that process. Typical use of this function is* to switch context in services, called by other processes. Each* PROCESS_CONTEXT_BEGIN() must be followed by the* PROCESS_CONTEXT_END() macro to end the context switch.** Example:\codePROCESS_CONTEXT_BEGIN(test_process);etimer_set(timer, CLOCK_SECOND);PROCESS_CONTEXT_END(test_process);\endcode** \param p The process to use as context** \sa PROCESS_CONTEXT_END()* \sa PROCESS_CURRENT()*/
#define PROCESS_CONTEXT_BEGIN(p) {\
struct process *tmp_current PROCESS_CURRENT();\
process_current p/*** End a context switch** This function ends a context switch and changes back to the* previous process.** \param p The process used in the context switch** \sa PROCESS_CONTEXT_START()*/
#define PROCESS_CONTEXT_END(p) process_current tmp_current; }/*** \brief Allocate a global event number.* \return The allocated event number** In Contiki, event numbers above 128 are global and may* be posted from one process to another. This function* allocates one such event number.** \note There currently is no way to deallocate an allocated event* number.*/
CCIF process_event_t process_alloc_event(void);/** } *//*** \name Functions called from device drivers* {*//*** Request a process to be polled.** This function typically is called from an interrupt handler to* cause a process to be polled.** \param p A pointer to the process process structure.*/
CCIF void process_poll(struct process *p);/** } *//*** \name Functions called by the system and boot-up code* {*//*** \brief Initialize the process module.** This function initializes the process module and should* be called by the system boot-up code.*/
void process_init(void);/*** Run the system once - call poll handlers and process one event.** This function should be called repeatedly from the main() program* to actually run the Contiki system. It calls the necessary poll* handlers, and processes one event. The function returns the number* of events that are waiting in the event queue so that the caller* may choose to put the CPU to sleep when there are no pending* events.** \return The number of events that are currently waiting in the* event queue.*/
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.*/
CCIF int process_is_running(struct process *p);/*** Number of events waiting to be processed.** \return The number of events that are currently waiting to be* processed.*/
int process_nevents(void);/** } */CCIF extern struct process *process_list;#define PROCESS_LIST() process_list#endif /* PROCESS_H_ *//** } */
/** } */
process.c
/** Copyright (c) 2005, Swedish Institute of Computer Science* All rights reserved.** Redistribution and use in source and binary forms, with or without* modification, are permitted provided that the following conditions* are met:* 1. Redistributions of source code must retain the above copyright* notice, this list of conditions and the following disclaimer.* 2. Redistributions in binary form must reproduce the above copyright* notice, this list of conditions and the following disclaimer in the* documentation and/or other materials provided with the distribution.* 3. Neither the name of the Institute nor the names of its contributors* may be used to endorse or promote products derived from this software* without specific prior written permission.** THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS AS IS AND* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF* SUCH DAMAGE.** This file is part of the Contiki operating system.**//*** \addtogroup process* {*//*** \file* Implementation of the Contiki process kernel.* \author* Adam Dunkels adamsics.se**/#include stdio.h#include sys/process.h
#include sys/arg.h/** Pointer to the currently running process structure.*/
struct process *process_list NULL;
struct process *process_current NULL;static process_event_t lastevent;/** Structure used for keeping the queue of active events.*/
struct event_data {process_event_t ev;process_data_t data;struct process *p;
};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;
#endifstatic volatile unsigned char poll_requested;#define PROCESS_STATE_NONE 0
#define PROCESS_STATE_RUNNING 1
#define PROCESS_STATE_CALLED 2static void call_process(struct process *p, process_event_t ev, process_data_t data);#define DEBUG 0
#if DEBUG
#include stdio.h
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif/*---------------------------------------------------------------------------*/
process_event_t
process_alloc_event(void)
{return lastevent;
}
/*---------------------------------------------------------------------------*/
void
process_start(struct process *p, process_data_t data)
{struct process *q;/* First make sure that we dont try to start a process that isalready running. */for(q process_list; q ! p q ! NULL; q q-next);/* If we found the process on the process list, we bail out. */if(q p) {return;}/* Put on the procs list.*/p-next process_list;process_list p;p-state PROCESS_STATE_RUNNING;PT_INIT(p-pt);PRINTF(process: starting %s\n, PROCESS_NAME_STRING(p));/* Post a synchronous initialization event to the process. */process_post_synch(p, PROCESS_EVENT_INIT, data);
}
/*---------------------------------------------------------------------------*/
static void
exit_process(struct process *p, struct process *fromprocess)
{register struct process *q;struct process *old_current process_current;PRINTF(process: exit_process %s\n, PROCESS_NAME_STRING(p));/* Make sure the process is in the process list before we try toexit it. */for(q process_list; q ! p q ! NULL; q q-next);if(q NULL) {return;}if(process_is_running(p)) {/* Process was running */p-state PROCESS_STATE_NONE;/** Post a synchronous event to all processes to inform them that* this process is about to exit. This will allow services to* deallocate state associated with this process.*/for(q process_list; q ! NULL; q q-next) {if(p ! q) {call_process(q, PROCESS_EVENT_EXITED, (process_data_t)p);}}if(p-thread ! NULL p ! fromprocess) {/* Post the exit event to the process that is about to exit. */process_current p;p-thread(p-pt, PROCESS_EVENT_EXIT, NULL);}}if(p process_list) {process_list process_list-next;} else {for(q process_list; q ! NULL; q q-next) {if(q-next p) {q-next p-next;break;}}}process_current old_current;
}
/*---------------------------------------------------------------------------*/
static void
call_process(struct process *p, process_event_t ev, process_data_t data)
{int ret;#if DEBUGif(p-state PROCESS_STATE_CALLED) {printf(process: process %s called again with event %d\n, PROCESS_NAME_STRING(p), ev);}
#endif /* DEBUG */if((p-state PROCESS_STATE_RUNNING) p-thread ! NULL) {PRINTF(process: calling process %s with event %d\n, PROCESS_NAME_STRING(p), 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;}}
}
/*---------------------------------------------------------------------------*/
void
process_exit(struct process *p)
{exit_process(p, PROCESS_CURRENT());
}
/*---------------------------------------------------------------------------*/
void
process_init(void)
{lastevent PROCESS_EVENT_MAX;nevents fevent 0;
#if PROCESS_CONF_STATSprocess_maxevents 0;
#endif /* PROCESS_CONF_STATS */process_current process_list NULL;
}
/*---------------------------------------------------------------------------*/
/** Call each process poll handler.*/
/*---------------------------------------------------------------------------*/
static void
do_poll(void)
{struct process *p;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);}}
}
/*---------------------------------------------------------------------------*/
/** Process the next event in the event queue and deliver it to* listening processes.*/
/*---------------------------------------------------------------------------*/
static void
do_event(void)
{process_event_t ev;process_data_t data;struct process *receiver;struct process *p;/** If there are any events in the queue, take the first one and walk* through the list of processes to see if the event should be* delivered to any of them. If so, we call the event handler* function for the process. We only process one event at a time and* call the poll handlers inbetween.*/if(nevents 0) {/* There are events that we should deliver. */ev events[fevent].ev;data events[fevent].data;receiver events[fevent].p;/* Since we have seen the new event, we move pointer upwardsand decrease the number of events. */fevent (fevent 1) % PROCESS_CONF_NUMEVENTS;--nevents;/* If this is a broadcast event, we deliver it to all events, inorder of their priority. */if(receiver PROCESS_BROADCAST) {for(p process_list; p ! NULL; p p-next) {/* If we have been requested to poll a process, we do this inbetween processing the broadcast event. */if(poll_requested) {do_poll();}call_process(p, ev, data);}} else {/* This is not a broadcast event, so we deliver it to thespecified process. *//* If the event was an INIT event, we should also update thestate of the process. */if(ev PROCESS_EVENT_INIT) {receiver-state PROCESS_STATE_RUNNING;}/* Make sure that the process actually is running. */call_process(receiver, ev, data);}}
}
/*---------------------------------------------------------------------------*/
int
process_run(void)
{/* Process poll events. */if(poll_requested) {do_poll();}/* Process one event from the queue */do_event();return nevents poll_requested;
}
/*---------------------------------------------------------------------------*/
int
process_nevents(void)
{return nevents poll_requested;
}
/*---------------------------------------------------------------------------*/
int
process_post(struct process *p, process_event_t ev, process_data_t data)
{process_num_events_t snum;if(PROCESS_CURRENT() NULL) {PRINTF(process_post: NULL process posts event %d to process %s, nevents %d\n,ev,PROCESS_NAME_STRING(p), nevents);} else {PRINTF(process_post: Process %s posts event %d to process %s, nevents %d\n,PROCESS_NAME_STRING(PROCESS_CURRENT()), ev,p PROCESS_BROADCAST? broadcast: PROCESS_NAME_STRING(p), nevents);}if(nevents PROCESS_CONF_NUMEVENTS) {
#if DEBUGif(p PROCESS_BROADCAST) {printf(soft panic: event queue is full when broadcast event %d was posted from %s\n, ev, PROCESS_NAME_STRING(process_current));} else {printf(soft panic: event queue is full when event %d was posted to %s from %s\n, ev, PROCESS_NAME_STRING(p), PROCESS_NAME_STRING(process_current));}
#endif /* DEBUG */return PROCESS_ERR_FULL;}snum (process_num_events_t)(fevent nevents) % PROCESS_CONF_NUMEVENTS;events[snum].ev ev;events[snum].data data;events[snum].p p;nevents;#if PROCESS_CONF_STATSif(nevents process_maxevents) {process_maxevents nevents;}
#endif /* PROCESS_CONF_STATS */return PROCESS_ERR_OK;
}
/*---------------------------------------------------------------------------*/
void
process_post_synch(struct process *p, process_event_t ev, process_data_t data)
{struct process *caller process_current;call_process(p, ev, data);process_current caller;
}
/*---------------------------------------------------------------------------*/
void
process_poll(struct process *p)
{if(p ! NULL) {if(p-state PROCESS_STATE_RUNNING ||p-state PROCESS_STATE_CALLED) {p-needspoll 1;poll_requested 1;}}
}
/*---------------------------------------------------------------------------*/
int
process_is_running(struct process *p)
{return p-state ! PROCESS_STATE_NONE;
}
/*---------------------------------------------------------------------------*/
/** } */
07. 附录
参考Contiki 2.6: Contiki processes
参考Processes · contiki-os/contiki Wiki · GitHub