?? taskvarlib.c
字號:
/* taskVarLib.c - task variables support library *//* Copyright 1984-2003 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02a,14jan03,pcm add intLock()/intUnlock() around taskVarAdd() critical code01z,21jan93,jdi documentation cleanup for 5.1.01y,02oct92,jcf added task validity check to switch hook.01x,18jul92,smb changed errno.h to errnoLib.h.01w,07jul92,ajm removed unnecesary cacheClear calls for 04001v,04jul92,jcf scalable/ANSI/cleanup effort.01u,03jul92,jwt converted cacheClearEntry() calls to cacheClear() for 5.1.01t,26may92,rrr the tree shuffle01s,21dec91,gae added includes for ANSI.01r,19nov91,rrr shut up some ansi warnings.01q,04oct91,rrr passed through the ansification filter -changed functions to ansi style -fixed #else and #endif -changed VOID to void -changed copyright notice01p,27aug91,shl added cache coherency calls for MC68040 support.01o,220may1,jdi documentation tweak.01n,05apr91,jdi documentation -- removed header parens and x-ref numbers; doc review by dnw.01m,24mar91,jdi documentation cleanup.01l,01oct90,jcf added taskVarInfo().01k,01aug90,jcf changed tcb taskVar to pTaskVar. added include of taskVarLib.h.01j,19jul90,dnw mangen fix01i,14apr90,jcf removed tcb extension dependencies.01h,14mar90,jdi documentation cleanup.01g,08apr89,dnw added taskVarInit().01f,17aug88,gae documentation.01d,22jun88,dnw name tweaks.01c,30may88,dnw changed to v4 names.01b,08apr88,gae added taskId parm. to taskVar{Add,Del}(); made taskVar{Get,Set}() work with active task. Fixed fatal bug in taskVarDel() of not replacing bg value. Added taskVarDeleteHook() to cleanup after tasks. Lint. Documentation.01a,25jan88,jcf written by extracting from vxLib.c.*//*DESCRIPTIONVxWorks provides a facility called "task variables," which allows4-byte variables to be added to a task's context, and thevariables' values to be switched each time a task switch occurs to orfrom the calling task. Typically, several tasks declare the samevariable (4-byte memory location) as a task variable and treat thatmemory location as their own private variable. For example, thisfacility can be used when a routine must be spawned more than once asseveral simultaneous tasks.The routines taskVarAdd() and taskVarDelete() are used to add or deletea task variable. The routines taskVarGet() and taskVarSet() are used to getor set the value of a task variable.NOTEIf you are using task variables in a task delete hook(see taskHookLib), refer to the manual entry for taskVarInit()for warnings on proper usage.INCLUDE FILES: taskVarLib.hSEE ALSO: taskHookLib,.pG "Basic OS"*//* LINTLIBRARY */#include "vxWorks.h"#include "stdlib.h"#include "taskHookLib.h"#include "taskVarLib.h"#include "taskLib.h"#include "errnoLib.h"#include "intLib.h"/* forward static functions */static void taskVarDeleteHook (WIND_TCB *pTcb);static void taskVarSwitchHook (WIND_TCB *pOldTcb, WIND_TCB *pNewTcb);/********************************************************************************* taskVarInit - initialize the task variables facility** This routine initializes the task variables facility. It installs task* switch and delete hooks used for implementing task variables.* If taskVarInit() is not called explicitly, taskVarAdd() will call it* automatically when the first task variable is added.** After the first invocation of this routine, subsequent invocations* have no effect.** WARNING* Order dependencies in task delete hooks often involve* task variables. If a facility uses task variables and has a* task delete hook that expects to use those task variables,* the facility's delete hook must run before the task* variables' delete hook. Otherwise, the task variables* will be deleted by the time the facility's delete hook runs.** VxWorks is careful to run the delete hooks in reverse of the order in* which they were installed. Any facility that has a delete hook that will* use task variables can guarantee proper ordering by calling taskVarInit()* before adding its own delete hook.** Note that this is not an issue in normal use of task variables. The issue* only arises when adding another task delete hook that uses task variables.** Caution should also be taken when adding task variables from within* create hooks. If the task variable package has not been installed via* taskVarInit(), the create hook attempts to create a create hook, and that* may cause system failure. To avoid this situation, taskVarInit() should* be called during system initialization from the root task, usrRoot(), in* usrConfig.c.** RETURNS: OK, or ERROR if the task switch/delete hooks could not be installed.*/STATUS taskVarInit (void) { static BOOL taskVarInstalled = FALSE; /* TRUE = facility installed */ /* if task variables facility is not already installed, then install it * by adding the switch and delete hooks */ if (!taskVarInstalled) { if ((taskSwitchHookAdd ((FUNCPTR)taskVarSwitchHook) != OK) || (taskDeleteHookAdd ((FUNCPTR)taskVarDeleteHook) != OK)) { return (ERROR); } taskVarInstalled = TRUE; } return (OK); }/********************************************************************************* taskVarDeleteHook - delete task variables of exiting tasks** This routine is the task delete routine that deletes all task* variables of an exiting task.*/LOCAL void taskVarDeleteHook ( WIND_TCB *pTcb ) { FAST TASK_VAR *pTaskVar; FAST TASK_VAR *pTaskVarNext; for (pTaskVar = pTcb->pTaskVar; pTaskVar != NULL; pTaskVar = pTaskVarNext) { pTaskVarNext = pTaskVar->next; free ((char *)pTaskVar); /* free storage of deleted cell */ } }/********************************************************************************* taskVarSwitchHook - switch task variables of switching tasks** This routine is the task switch routine that implements the task variable* facility. It swaps the current and saved values of all the task variables* of the out-going and in-coming tasks.*/LOCAL void taskVarSwitchHook ( WIND_TCB *pOldTcb, WIND_TCB *pNewTcb ) { FAST TASK_VAR *pTaskVar; FAST int temp; /* swap task variables of old task */ if (TASK_ID_VERIFY(pOldTcb) == OK) /* suicide runs delete hook 1st */ { for (pTaskVar = pOldTcb->pTaskVar; pTaskVar != NULL; pTaskVar = pTaskVar->next) { /* swap current and save value of task variable */ temp = pTaskVar->value; pTaskVar->value = *(pTaskVar->address); *(pTaskVar->address) = temp; } } /* swap task variables of new task */ for (pTaskVar = pNewTcb->pTaskVar; pTaskVar != NULL; pTaskVar = pTaskVar->next) { /* swap current and save value of task variable */ temp = pTaskVar->value; pTaskVar->value = *(pTaskVar->address); *(pTaskVar->address) = temp; } }/********************************************************************************* taskVarAdd - add a task variable to a task** This routine adds a specified variable <pVar> (4-byte memory location) to a* specified task's context. After calling this routine, the variable will* be private to the task. The task can access and modify the variable, but* the modifications will not appear to other tasks, and other tasks'* modifications to that variable will not affect the value seen by the* task. This is accomplished by saving and restoring the variable's initial* value each time a task switch occurs to or from the calling task.** This facility can be used when a routine is to be spawned repeatedly as* several independent tasks. Although each task will have its own stack,* and thus separate stack variables, they will all share the same static and* global variables. To make a variable \f2not\fP shareable, the routine can* call taskVarAdd() to make a separate copy of the variable for each task, but* all at the same physical address.** Note that task variables increase the task switch time to and from the* tasks that own them. Therefore, it is desirable to limit the number of* task variables that a task uses. One efficient way to use task variables * is to have a single task variable that is a pointer to a dynamically * allocated structure containing the task's private data.** EXAMPLE:* Assume that three identical tasks were spawned with a routine called* \f2operator()\f1. All three use the structure OP_GLOBAL for all variables* that are specific to a particular incarnation of the task. The following* code fragment shows how this is set up:** .CS* OP_GLOBAL *opGlobal; /@ ptr to operator task's global variables @/** void operator* (* int opNum /@ number of this operator task @/* )* {* if (taskVarAdd (0, (int *)&opGlobal) != OK)* {* printErr ("operator%d: can't taskVarAdd opGlobal\en", opNum);* taskSuspend (0);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -