taskHookLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:21k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* taskHookLib.c - task hook library */
  2. /* Copyright 1984-1995 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01z,14mar99,jdi  doc: removed refs to config.h and/or configAll.h (SPR 25663).
  8. 01y,27may95,p_m  added _func_taskCreateHookAdd and _func_taskDeleteHookAdd
  9.  initialization in taskHookInit().
  10. 01x,11feb95,jdi  doc format repair in taskSwitchHookAdd().
  11. 01w,09dec94,rhp  add list of fns callable from task-switch hooks (SPR 2206)
  12. 01v,02feb93,jdi  documentation tweak for configuration.
  13. 01u,21jan93,jdi  documentation cleanup for 5.1.
  14. 01t,18jul92,smb  Changed errno.h to errnoLib.h.
  15. 01s,04jul92,jcf  scalable/ANSI/cleanup effort.
  16. 01r,26may92,rrr  the tree shuffle
  17. 01q,13dec91,gae  ANSI cleanup.
  18. 01p,19nov91,rrr  shut up some ansi warnings.
  19. 01o,04oct91,rrr  passed through the ansification filter
  20.                   -changed functions to ansi style
  21.   -changed VOID to void
  22.   -changed copyright notice
  23. 01n,05apr91,jdi  documentation -- removed header parens and x-ref numbers;
  24.  doc review by dnw.
  25. 01m,24mar91,jdi  documentation cleanup.
  26. 01l,28sep90,jcf  documentation.
  27. 01k,10aug90,kdl  added forward declaration for taskHookShow.
  28. 01j,02aug90,jcf  documentation.
  29. 01i,10dec89,jcf  symbol table type now SYM_TYPE.
  30.  removed tcb extension dependencies.
  31.  added swap hook support.
  32. 01h,23jul89,gae  added task{Create,Switch,Delete}HookShow.
  33. 01g,08apr89,dnw  changed to store delete hooks in reverse order in the table.
  34. 01f,17aug88,gae  documentation.
  35. 01e,22jun88,dnw  name tweaks.
  36. 01d,05jun88,dnw  changed from hookLib to taskHookLib.
  37. 01c,30may88,dnw  changed to v4 names.
  38. 01b,28may88,dnw  removed hookAddRebootRtn to rebootLib.c
  39.  changed some status value names.
  40. 01a,25jan88,jcf  written by extracting from vxLib.c.
  41. */
  42. /*
  43. DESCRIPTION
  44. This library provides routines for adding extensions to the VxWorks
  45. tasking facility.  To allow task-related facilities to be added to the
  46. system without modifying the kernel, the kernel provides call-outs every
  47. time a task is created, switched, or deleted.  The call-outs allow additional
  48. routines, or "hooks," to be invoked whenever these events occur.
  49. The hook management routines below allow hooks to be dynamically added to
  50. and deleted from the current lists of create, switch, and delete hooks:
  51. .iP "taskCreateHookAdd() and taskCreateHookDelete()" 10
  52. Add and delete routines to be called when a task is created.
  53. .iP "taskSwitchHookAdd() and taskSwitchHookDelete()"
  54. Add and delete routines to be called when a task is switched.
  55. .iP "taskDeleteHookAdd() and taskDeleteHookDelete()"
  56. Add and delete routines to be called when a task is deleted.
  57. .LP
  58. This facility is used by dbgLib to provide task-specific breakpoints
  59. and single-stepping.  It is used by taskVarLib for the "task variable"
  60. mechanism.  It is also used by fppLib for floating-point coprocessor
  61. support.
  62. NOTE
  63. It is possible to have dependencies among task hook routines.  For
  64. example, a delete hook may use facilities that are cleaned up and deleted
  65. by another delete hook.  In such cases, the order in which the hooks run
  66. is important.  VxWorks runs the create and switch hooks in the order in
  67. which they were added, and runs the delete hooks in reverse of the order
  68. in which they were added.  Thus, if the hooks are added in "hierarchical"
  69. order, such that they rely only on facilities whose hook routines have
  70. already been added, then the required facilities will be initialized
  71. before any other facilities need them, and will be deleted after all
  72. facilities are finished with them.
  73. VxWorks facilities guarantee this by having each facility's initialization
  74. routine first call any prerequisite facility's initialization routine
  75. before adding its own hooks.  Thus, the hooks are always added in the
  76. correct order.  Each initialization routine protects itself from multiple
  77. invocations, allowing only the first invocation to have any effect.
  78. INCLUDE FILES: taskHookLib.h
  79. SEE ALSO: dbgLib, fppLib, taskLib, taskVarLib
  80. .pG "Basic OS"
  81. */
  82. #include "vxWorks.h"
  83. #include "errnoLib.h"
  84. #include "taskHookLib.h"
  85. #include "private/funcBindP.h"
  86. #include "private/taskLibP.h"
  87. /* forward static functions */
  88. static STATUS taskHookAdd (FUNCPTR hook, FUNCPTR table [], int maxEntries);
  89. static STATUS taskHookDelete (FUNCPTR hook, FUNCPTR table [], int maxEntries);
  90. static STATUS taskSwapMaskClear (int tid, int index, BOOL in, BOOL out);
  91. static STATUS taskSwapMaskSet (int tid, int index, BOOL in, BOOL out);
  92. /*******************************************************************************
  93. *
  94. * taskHookInit - initialize task hook facilities
  95. *
  96. * This routine is a NULL routine called to configure the task hook package
  97. * into the system.  It is called automatically if the configuration macro
  98. * INCLUDE_TASK_HOOKS is defined.
  99. *
  100. * RETURNS: N/A
  101. */
  102. void taskHookInit (void)
  103.     {
  104.     _func_taskCreateHookAdd = (FUNCPTR) taskCreateHookAdd;
  105.     _func_taskDeleteHookAdd = (FUNCPTR) taskDeleteHookAdd;
  106.     }
  107. /*******************************************************************************
  108. *
  109. * taskCreateHookAdd - add a routine to be called at every task create
  110. *
  111. * This routine adds a specified routine to a list of routines
  112. * that will be called whenever a task is created.  The routine should be
  113. * declared as follows:
  114. * .CS
  115. *     void createHook
  116. *         (
  117. *         WIND_TCB *pNewTcb /@ pointer to new task's TCB @/
  118. *         )
  119. * .CE
  120. *
  121. * RETURNS: OK, or ERROR if the table of task create routines is full.
  122. *
  123. * SEE ALSO: taskCreateHookDelete()
  124. */
  125. STATUS taskCreateHookAdd
  126.     (
  127.     FUNCPTR createHook  /* routine to be called when a task is created */
  128.     )
  129.     {
  130.     return (taskHookAdd (createHook, taskCreateTable, VX_MAX_TASK_CREATE_RTNS));
  131.     }
  132. /*******************************************************************************
  133. *
  134. * taskCreateHookDelete - delete a previously added task create routine
  135. *
  136. * This routine removes a specified routine from the list of
  137. * routines to be called at each task create.
  138. *
  139. * RETURNS: OK, or ERROR if the routine is not in the table of task create
  140. * routines.
  141. *
  142. * SEE ALSO: taskCreateHookAdd()
  143. */
  144. STATUS taskCreateHookDelete
  145.     (
  146.     FUNCPTR createHook          /* routine to be deleted from list */
  147.     )
  148.     {
  149.     return (taskHookDelete (createHook, taskCreateTable,
  150.     VX_MAX_TASK_CREATE_RTNS));
  151.     }
  152. /*******************************************************************************
  153. *
  154. * taskSwitchHookAdd - add a routine to be called at every task switch
  155. *
  156. * This routine adds a specified routine to a list of routines
  157. * that will be called at every task switch.  The routine should be
  158. * declared as follows:
  159. * .CS
  160. *     void switchHook
  161. *         (
  162. *         WIND_TCB *pOldTcb, /@ pointer to old task's WIND_TCB @/
  163. *         WIND_TCB *pNewTcb /@ pointer to new task's WIND_TCB @/
  164. *         )
  165. * .CE
  166. *
  167. * NOTE
  168. * User-installed switch hooks are called within the kernel context.
  169. * Therefore, switch hooks do not have access to all VxWorks
  170. * facilities.  The following routines can be called from within a task
  171. * switch hook:
  172. * .TS
  173. * tab(|);
  174. * lf3 lf3
  175. * l   l .
  176. * Library    |  Routines
  177. * _
  178. * bLib       |  All routines
  179. * fppArchLib |  fppSave(), fppRestore()
  180. * intLib     |  intContext(), intCount(), intVecSet(), intVecGet()
  181. * lstLib     |  All routines
  182. * mathALib   |  All routines, if fppSave()/fppRestore() are used
  183. * rngLib     |  All routines except rngCreate()
  184. * taskLib    |  taskIdVerify(), taskIdDefault(), taskIsReady(),
  185. *            |  taskIsSuspended(), taskTcb()
  186. * vxLib      |  vxTas()
  187. * .TE
  188. * RETURNS: OK, or ERROR if the table of task switch routines is full.
  189. *
  190. * SEE ALSO: taskSwitchHookDelete()
  191. */
  192. STATUS taskSwitchHookAdd
  193.     (
  194.     FUNCPTR switchHook  /* routine to be called at every task switch */
  195.     )
  196.     {
  197.     return (taskHookAdd (switchHook, taskSwitchTable, VX_MAX_TASK_SWITCH_RTNS));
  198.     }
  199. /*******************************************************************************
  200. *
  201. * taskSwitchHookDelete - delete a previously added task switch routine
  202. *
  203. * This routine removes the specified routine from the list of
  204. * routines to be called at each task switch.
  205. *
  206. * RETURNS: OK, or ERROR if the routine is not in the table of task switch
  207. * routines.
  208. *
  209. * SEE ALSO: taskSwitchHookAdd()
  210. */
  211. STATUS taskSwitchHookDelete
  212.     (
  213.     FUNCPTR switchHook          /* routine to be deleted from list */
  214.     )
  215.     {
  216.     return (taskHookDelete (switchHook, taskSwitchTable,
  217.     VX_MAX_TASK_SWITCH_RTNS));
  218.     }
  219. /*******************************************************************************
  220. *
  221. * taskSwapHookAdd - add routine to be called at every task switch
  222. *
  223. * This routine adds the specified routine to a list of routines
  224. * that get called at every task switch.  The routine should be
  225. * declared as follows:
  226. * .CS
  227. * void swapHook (pOldTcb, pNewTcb)
  228. *     WIND_TCB *pOldTcb; /@ pointer to old task's WIND_TCB @/
  229. *     WIND_TCB *pNewTcb; /@ pointer to new task's WIND_TCB @/
  230. * .CE
  231. *
  232. * RETURNS: OK, or ERROR if table of task switch routines is full.
  233. *
  234. * SEE ALSO: taskSwapHookDelete()
  235. *
  236. * NOMANUAL
  237. */
  238. STATUS taskSwapHookAdd
  239.     (
  240.     FUNCPTR swapHook    /* routine to be called at every task switch */
  241.     )
  242.     {
  243.     FAST int ix;
  244.     taskLock (); /* disable task switching */
  245.     /* find slot after last hook in table */
  246.     for (ix = 0; ix < VX_MAX_TASK_SWAP_RTNS; ++ix)
  247. {
  248. if (taskSwapTable[ix] == NULL)
  249.     {
  250.     taskSwapTable[ix]     = swapHook;
  251.     taskSwapReference[ix] = 0;
  252.     taskUnlock (); /* re-enable task switching */
  253.     return (OK);
  254.     }
  255. }
  256.     /* no free slot found */
  257.     taskUnlock (); /* re-enable task switching */
  258.     errnoSet (S_taskLib_TASK_HOOK_TABLE_FULL);
  259.     return (ERROR);
  260.     }
  261. /*******************************************************************************
  262. *
  263. * taskSwapHookAttach - attach a task to a swap routine
  264. *
  265. * A swap hook is only called for a task that has attached to it.  If task
  266. * attaches to the swap hook as <in>, then the hook will be called every time
  267. * the task is swapped in.  If the task attaches to the swap hook as <out>, then
  268. * the hook will be called every time the task is swapped out.
  269. *
  270. * RETURNS: OK or ERROR.
  271. *
  272. * NOMANUAL
  273. */
  274. STATUS taskSwapHookAttach
  275.     (
  276.     FUNCPTR     swapHook,       /* swap hook for conection */
  277.     int         tid,            /* task to connect to swap hook */
  278.     BOOL        in,             /* conection for swap in */
  279.     BOOL        out             /* conection for swap out */
  280.     )
  281.     {
  282.     int ix;
  283.     taskLock (); /* disable task switching */
  284.     /* find hook in hook table */
  285.     for (ix = 0; ix < VX_MAX_TASK_SWAP_RTNS; ++ix)
  286. {
  287. if (taskSwapTable [ix] == swapHook)
  288.     {
  289.     taskSwapReference[ix] += (in)  ? 1 : 0; /* reference swap hook */
  290.     taskSwapReference[ix] += (out) ? 1 : 0; /* reference swap hook */
  291.     if (taskSwapMaskSet (tid, ix, in, out) != OK)
  292. {
  293. taskSwapReference[ix] -= (in)  ? 1 : 0; /* deref. swap hook */
  294. taskSwapReference[ix] -= (out) ? 1 : 0; /* deref. swap hook */
  295. taskUnlock ();     /* reenable switching */
  296. return (ERROR);
  297. }
  298.     else
  299. {
  300. taskUnlock ();     /* reenable switching */
  301. return (OK);
  302. }
  303.     }
  304. }
  305.     /* hook not found in table */
  306.     taskUnlock (); /* re-enable task switching */
  307.     errnoSet (S_taskLib_TASK_HOOK_NOT_FOUND);
  308.     return (ERROR);
  309.     }
  310. /*******************************************************************************
  311. *
  312. * taskSwapHookDetach - detach a task from a swap routine
  313. *
  314. * A task may detach itself from a swap hook.  Once detached, the hook will not
  315. * be called when the task is involved in a context switch.
  316. *
  317. * RETURNS: OK or ERROR.
  318. *
  319. * NOMANUAL
  320. */
  321. STATUS taskSwapHookDetach
  322.     (
  323.     FUNCPTR     swapHook,       /* swap hook for disconection */
  324.     int         tid,            /* task to disconnect from swap hook */
  325.     BOOL        in,             /* conection for swap in */
  326.     BOOL        out             /* conection for swap out */
  327.     )
  328.     {
  329.     int ix;
  330.     taskLock (); /* disable task switching */
  331.     /* find hook in hook table */
  332.     for (ix = 0; ix < VX_MAX_TASK_SWAP_RTNS; ++ix)
  333. {
  334. if (taskSwapTable [ix] == swapHook)
  335.     {
  336.     if (taskSwapMaskClear (tid, ix, in, out) != OK)
  337. {
  338. taskUnlock (); /* re-enable task switching */
  339. return (ERROR); /* must of been a bum tid */
  340. }
  341.     else
  342. {
  343. taskSwapReference[ix] -= (in)  ? 1 : 0; /* deref. swap hook */
  344. taskSwapReference[ix] -= (out) ? 1 : 0; /* deref. swap hook */
  345. taskUnlock (); /* re-enable task switching */
  346. return (OK);
  347. }
  348.     }
  349. }
  350.     /* hook not found in table */
  351.     taskUnlock (); /* re-enable task switching */
  352.     errnoSet (S_taskLib_TASK_HOOK_NOT_FOUND);
  353.     return (ERROR);
  354.     }
  355. /*******************************************************************************
  356. *
  357. * taskSwapHookDelete - delete previously added task switch routine
  358. *
  359. * This routine removes the specified routine from the list of
  360. * routines to be called by attached tasks during context switch.
  361. *
  362. * RETURNS: OK, or ERROR if the routine is not in the table of task delete
  363. * routines.
  364. *
  365. * SEE ALSO: taskSwapHookAdd()
  366. *
  367. * NOMANUAL
  368. */
  369. STATUS taskSwapHookDelete
  370.     (
  371.     FUNCPTR swapHook            /* routine to be deleted from list */
  372.     )
  373.     {
  374.     int ix;
  375.     taskLock (); /* disable task switching */
  376.     /* find hook in hook table */
  377.     for (ix = 0; ix < VX_MAX_TASK_SWAP_RTNS; ++ix)
  378. {
  379. if (taskSwapTable [ix] == swapHook)
  380.     {
  381.     if (taskSwapReference [ix] != 0) /* reference swap hook */
  382. {
  383. taskUnlock (); /* re-enable task switching */
  384. errnoSet (S_taskLib_TASK_SWAP_HOOK_REFERENCED);
  385. return (ERROR);
  386. }
  387.     else
  388. {
  389. taskSwapTable [ix] = NULL;  /* take out of table */
  390. taskUnlock (); /* re-enable task switching */
  391. return (OK);
  392. }
  393.     }
  394. }
  395.     /* hook not found in table */
  396.     taskUnlock (); /* re-enable task switching */
  397.     errnoSet (S_taskLib_TASK_HOOK_NOT_FOUND);
  398.     return (ERROR);
  399.     }
  400. /*******************************************************************************
  401. *
  402. * taskDeleteHookAdd - add a routine to be called at every task delete
  403. *
  404. * This routine adds a specified routine to a list of routines
  405. * that will be called whenever a task is deleted.  The routine should be
  406. * declared as follows:
  407. * .CS
  408. *     void deleteHook
  409. *         (
  410. *         WIND_TCB *pTcb /@ pointer to deleted task's WIND_TCB @/
  411. *         )
  412. * .CE
  413. *
  414. * RETURNS: OK, or ERROR if the table of task delete routines is full.
  415. *
  416. * SEE ALSO: taskDeleteHookDelete()
  417. *
  418. * INTERNAL:
  419. * Unlike the other "hook add" routines, this routine keeps the delete hooks in
  420. * the table in REVERSE of the order in which they are added.  Thus the most
  421. * recently added hook is the FIRST entry in the table.  This causes the delete
  422. * hooks to be run in the reverse order when a task is deleted.  This is
  423. * necessary since a task delete hook may depend on another facility that
  424. * has a delete hook, e.g., stdio uses task variables.  If we ensure that the
  425. * delete hooks are added in hierarchical order (i.e., any delete hook only
  426. * uses facilities whose delete hooks have already been added), then running
  427. * them in reverse order guarantees that facilities are not cleaned up
  428. * prematurely.
  429. */
  430. STATUS taskDeleteHookAdd
  431.     (
  432.     FUNCPTR deleteHook  /* routine to be called when a task is deleted */
  433.     )
  434.     {
  435.     FAST int ix;
  436.     STATUS status = OK;
  437.     taskLock (); /* disable task switching */
  438.     if (taskDeleteTable [VX_MAX_TASK_DELETE_RTNS] != NULL)
  439. {
  440. /* no free slot found */
  441. errnoSet (S_taskLib_TASK_HOOK_TABLE_FULL);
  442. status = ERROR;
  443. }
  444.     else
  445. {
  446. /* move all the hooks down one slot in the table */
  447. for (ix = VX_MAX_TASK_DELETE_RTNS - 2; ix >= 0; --ix)
  448.     taskDeleteTable [ix + 1] = taskDeleteTable [ix];
  449. taskDeleteTable [0] = deleteHook;
  450. }
  451.     taskUnlock (); /* re-enable task switching */
  452.     return (status);
  453.     }
  454. /*******************************************************************************
  455. *
  456. * taskDeleteHookDelete - delete a previously added task delete routine
  457. *
  458. * This routine removes a specified routine from the list of
  459. * routines to be called at each task delete.
  460. *
  461. * RETURNS: OK, or ERROR if the routine is not in the table of task delete
  462. * routines.
  463. *
  464. * SEE ALSO: taskDeleteHookAdd()
  465. */
  466. STATUS taskDeleteHookDelete
  467.     (
  468.     FUNCPTR deleteHook          /* routine to be deleted from list */
  469.     )
  470.     {
  471.     return (taskHookDelete (deleteHook, taskDeleteTable,
  472.     VX_MAX_TASK_DELETE_RTNS));
  473.     }
  474. /*******************************************************************************
  475. *
  476. * taskHookAdd - add a hook routine to a hook table
  477. *
  478. * This routine does not guard against duplicate entries.
  479. *
  480. * RETURNS: OK, or ERROR if task hook table is full.
  481. */
  482. LOCAL STATUS taskHookAdd
  483.     (
  484.     FUNCPTR hook,       /* routine to be added to table */
  485.     FUNCPTR table[],    /* table to which to add */
  486.     int maxEntries      /* max entries in table */
  487.     )
  488.     {
  489.     FAST int ix;
  490.     taskLock (); /* disable task switching */
  491.     /* find slot after last hook in table */
  492.     for (ix = 0; ix < maxEntries; ++ix)
  493. {
  494. if (table[ix] == NULL)
  495.     {
  496.     table[ix] = hook;
  497.     taskUnlock (); /* re-enable task switching */
  498.     return (OK);
  499.     }
  500. }
  501.     /* no free slot found */
  502.     taskUnlock (); /* re-enable task switching */
  503.     errnoSet (S_taskLib_TASK_HOOK_TABLE_FULL);
  504.     return (ERROR);
  505.     }
  506. /*******************************************************************************
  507. *
  508. * taskHookDelete - delete a hook from a hook table
  509. *
  510. * RETURNS: OK, or ERROR if task hook could not be found.
  511. */
  512. LOCAL STATUS taskHookDelete
  513.     (
  514.     FUNCPTR hook,       /* routine to be deleted from table */
  515.     FUNCPTR table[],    /* table from which to delete */
  516.     int maxEntries      /* max entries in table */
  517.     )
  518.     {
  519.     FAST int ix;
  520.     taskLock (); /* disable task switching */
  521.     /* find hook in hook table */
  522.     for (ix = 0; ix < maxEntries; ++ix)
  523. {
  524. if (table [ix] == hook)
  525.     {
  526.     /* move all the remaining hooks up one slot in the table */
  527.     do
  528. table [ix] = table [ix + 1];
  529.     while (table [++ix] != NULL);
  530.     taskUnlock (); /* re-enable task switching */
  531.     return (OK);
  532.     }
  533. }
  534.     /* hook not found in table */
  535.     taskUnlock (); /* re-enable task switching */
  536.     errnoSet (S_taskLib_TASK_HOOK_NOT_FOUND);
  537.     return (ERROR);
  538.     }
  539. /*******************************************************************************
  540. *
  541. * taskSwapMaskSet - set a task's swap-in/swap-out mask
  542. *
  543. * This routine sets the bit for the specified index in the specified task's
  544. * swap-in/swap-out mask.  The parameter index is the index into the
  545. * taskSwapTable for the swap hook of interest.
  546. *
  547. * INTERNAL
  548. * The most significant bit corresponds to the first element of the
  549. * swap table.  This was done because optimized versions of the kernel
  550. * utilize the fact that the most significant bit sets the carry flag on a
  551. * shift left operation.
  552. *
  553. * RETURNS: OK, or ERROR if the swap mask could not be set.
  554. *
  555. * NOMANUAL
  556. */
  557. LOCAL STATUS taskSwapMaskSet
  558.     (
  559.     int  tid,   /* task to change swap-in mask */
  560.     int  index, /* index of task swap routine in taskSwapTable */
  561.     BOOL in,    /* call swap routine when task is switched in */
  562.     BOOL out    /* call swap routine when task is switched out */
  563.     )
  564.     {
  565.     WIND_TCB *pTcb = taskTcb (tid);
  566.     USHORT    ixBit = (1 << (15 - index));
  567.     if (pTcb == NULL) /* invalid task ID */
  568. return (ERROR);
  569.     if (((in) && (pTcb->swapInMask & ixBit)) ||
  570.         ((out) && (pTcb->swapOutMask & ixBit)))
  571. {
  572. errno = S_taskLib_TASK_SWAP_HOOK_SET;
  573. return (ERROR);
  574. }
  575.     if (in)
  576. pTcb->swapInMask |= ixBit; /* turn on swapInMask bit */
  577.     if (out)
  578. pTcb->swapOutMask |= ixBit; /* turn on swapOutMask bit */
  579.     return (OK);
  580.     }
  581. /*******************************************************************************
  582. *
  583. * taskSwapMaskClear - clear a task's swap-in/swap-out mask
  584. *
  585. * This routine clears the bit for the specified index in the specified task's
  586. * swap-in/swap-out mask.  The parameter index is the index into the
  587. * taskSwapTable for the swap hook of interest.
  588. *
  589. * INTERNAL
  590. * The most significant bit corresponds to the first element of the
  591. * swap table.  This was done for kernel efficiency.
  592. *
  593. * RETURNS: OK, or ERROR if the swap mask could not be cleared.
  594. *
  595. * NOMANUAL
  596. */
  597. LOCAL STATUS taskSwapMaskClear
  598.     (
  599.     int  tid,   /* task to change swap-in mask */
  600.     int  index, /* index of task swap routine in taskSwapTable */
  601.     BOOL in,    /* swap routine called when task is switched in */
  602.     BOOL out    /* swap routine called when task is switched out */
  603.     )
  604.     {
  605.     WIND_TCB *pTcb  = taskTcb (tid);
  606.     USHORT    ixBit = (1 << (15 - index));
  607.     if (pTcb == NULL) /* invalid task ID */
  608. return (ERROR);
  609.     if (((in) && !(pTcb->swapInMask & ixBit)) ||
  610.         ((out) && !(pTcb->swapOutMask & ixBit)))
  611. {
  612. errno = S_taskLib_TASK_SWAP_HOOK_CLEAR;
  613. return (ERROR);
  614. }
  615.     if (in)
  616. pTcb->swapInMask &= ~ixBit; /* turn off swapInMask bit */
  617.     if (out)
  618. pTcb->swapOutMask &= ~ixBit; /* turn off swapOutMask bit */
  619.     return (OK);
  620.     }