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

VxWorks

开发平台:

C/C++

  1. /* msgQEvLib.c - VxWorks events support for message queues */
  2. /* Copyright 2001 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01b,18oct01,bwa  Modified comment for options in msgQEvStart(). Added check
  8.  for current task in msgQEvStop().
  9. 01a,21sep01,bwa  written
  10. */
  11. /*
  12. DESCRIPTION
  13. This library is an extension to eventLib, the events library. Its purpose 
  14. is to support events for message queues.
  15. The functions in this library are used to control registration of tasks on a
  16. message queue. The routine msgQEvStart() registers a task and starts the
  17. notification process. The function msgQEvStop() un-registers the task, which 
  18. stops the notification mechanism. 
  19. When a task is registered and a message arrives on the queue, the events
  20. specified are sent to that task, on the condition that no other task is pending
  21. on that message queue. However, if a msgQReceive() is to be done afterwards
  22. to get the message, there is no guarantee that it will still be available.
  23. INCLUDE FILES: msgQEvLib.h
  24. SEE ALSO: eventLib,
  25. .pG "Basic OS"
  26. */
  27. #include "vxWorks.h"
  28. #include "taskLib.h"
  29. #include "errnoLib.h"
  30. #include "intLib.h"
  31. #include "eventLib.h"
  32. #include "msgQLib.h"
  33. #include "taskArchLib.h"
  34. #include "private/msgQLibP.h"
  35. #include "private/windLibP.h"
  36. /* externs */
  37. extern CLASS_ID msgQClassId;
  38. /* locals */
  39. LOCAL BOOL msgQEvIsFree (MSG_Q_ID msgQId);
  40. /*******************************************************************************
  41. *
  42. * msgQEvLibInit - dummy lib init fcn, used to pull lib into kernel
  43. *
  44. * NOMANUAL
  45. *
  46. */
  47. void msgQEvLibInit (void)
  48.     {
  49.     }
  50. /*******************************************************************************
  51. *
  52. * msgQEvStart - start event notification process for a message queue
  53. *
  54. * This routine turns on the event notification process for a given message
  55. * queue. When a message becomes available but not wanted in that 
  56. * particular message queue, the events specified will be sent to the task
  57. * registered by this function. A task can overwrite its own registration
  58. * without first invoking msgQEvStop() or specifying the ALLOW_OVERWRITE option.
  59. *
  60. * The <options> parameter is used for 3 user options:
  61. * - Specify if the events are to be sent only once or every time a message
  62. * arrives until msgQEvStop() is called. The option 
  63. * .iP "EVENTS_SEND_ONCE (0x1)"
  64. * tells the message queue to send the events one time only.
  65. * - Specify if another task can register itself while the current task is
  66. * still registered. If so, the current task registration is overwritten without
  67. * any warning. The option 
  68. * .iP "EVENTS_ALLOW_OVERWRITE (0x2)"
  69. * allow subsequent registrations to overwrite the current one.
  70. * - Specify if events are to be sent right away in the case a message is
  71. * waiting to be picked up. The option
  72. * .iP "EVENTS_SEND_IF_FREE (0x4)"
  73. * tells the registration process to send events if a message is present on the
  74. * message queue.
  75. * If none of those three options is to be used, then the option
  76. * .iP "EVENTS_OPTIONS_NONE (0x0)"
  77. * has to be passed to the <options> parameter.
  78. *
  79. * RETURNS: OK on success, or ERROR.
  80. *
  81. * ERRNO
  82. * .iP "S_objLib_OBJ_ID_ERROR"
  83. * The message queue ID is invalid.
  84. * .iP "S_eventLib_ALREADY_REGISTERED"
  85. * A task is already registered on the message queue.
  86. * .iP "S_intLib_NOT_ISR_CALLABLE"
  87. * Routine has been called from interrupt level.
  88. * .iP "S_eventLib_EVENTSEND_FAILED"
  89. * User chose to send events right away and that operation failed.
  90. * .iP "S_eventLib_ZERO_EVENTS"
  91. * User passed in a value of zero to the <events> parameter.
  92. *
  93. * SEE ALSO: eventLib, msgQLib, msgQEvStop()
  94. */
  95. STATUS msgQEvStart
  96.     (
  97.     MSG_Q_ID msgQId, /* msg Q for which to register events */
  98.     UINT32 events, /* 32 possible events                 */
  99.     UINT8 options  /* event-related msg Q options        */
  100.     )
  101.     {
  102.     if (events == 0x0)
  103. {
  104. errnoSet (S_eventLib_ZERO_EVENTS);
  105. return (ERROR);
  106. }
  107.     if (INT_RESTRICT () != OK)
  108. return (ERROR);    /* errno set by INT_RESTRICT() */
  109.     TASK_LOCK (); /* to prevent msg Q from being deleted */
  110.     if (OBJ_VERIFY(msgQId,msgQClassId) != OK)
  111. {
  112. TASK_UNLOCK ();
  113. return (ERROR);    /* errno is set by OBJ_VERIFY */
  114. }
  115.     /* TASK_UNLOCK() will be done by eventStart() */
  116.     return (eventStart ((OBJ_ID)msgQId, &msgQId->events, &msgQEvIsFree,
  117.     events, options));
  118.     }
  119. /*******************************************************************************
  120. *
  121. * msgQEvIsFree - Determines if a msg is present on the queue
  122. *
  123. * RETURNS: TRUE if a msg is present, FALSE if not
  124. *
  125. * NOTE: the msgQId has to be validated before calling this function since it
  126. *       doesn't validate it itself before dereferencing the pointer.
  127. *
  128. * NOMANUAL
  129. */
  130. LOCAL BOOL msgQEvIsFree (MSG_Q_ID msgQId)
  131.     {
  132.     if (msgQId->msgQ.first != NULL)
  133. return TRUE;
  134.     return FALSE;
  135.     }
  136. /*******************************************************************************
  137. *
  138. * msgQEvStop - stop event notification process for a message queue
  139. *
  140. * This routine turns off the event notification process for a given message
  141. * queue. It thus allows another task to register itself for event notification
  142. * on that particular message queue.
  143. *
  144. * RETURNS: OK on success, or ERROR.
  145. *
  146. * ERRNO
  147. * .iP "S_objLib_OBJ_ID_ERROR"
  148. * The message queue ID is invalid.
  149. * .iP "S_intLib_NOT_ISR_CALLABLE"
  150. * Routine has been called from interrupt level.
  151. * .iP "S_eventLib_TASK_NOT_REGISTERED"
  152. * Routine has not been called by registered task.
  153. *
  154. * SEE ALSO: eventLib, msgQLib, msgQEvStart()
  155. */
  156. STATUS msgQEvStop
  157.     (
  158.     MSG_Q_ID msgQId
  159.     )
  160.     {
  161.     int level;
  162.     if (INT_RESTRICT() != OK)
  163. return (ERROR);
  164.     /*
  165.      * intLock is used instead of TASK_LOCK because it is faster (since
  166.      * TASK_UNLOCK calls intLock anyway) and time the ints are locked is
  167.      * really short
  168.      */
  169.     level = intLock();
  170.     if (OBJ_VERIFY(msgQId,msgQClassId) != OK)
  171. {
  172. intUnlock (level);
  173. return (ERROR);    /* errno is set by OBJ_VERIFY */
  174. }
  175.     if (msgQId->events.taskId != (int)taskIdCurrent)
  176. {
  177. intUnlock (level);
  178. errnoSet (S_eventLib_TASK_NOT_REGISTERED);
  179. return (ERROR);
  180. }
  181.     msgQId->events.taskId = (int)NULL;
  182.     intUnlock (level);
  183.     return (OK);
  184.     }