usbQueueLib.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:7k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* usbQueueLib.c - O/S-independent queue functions */
  2. /* Copyright 2000 Wind River Systems, Inc. */
  3. /*
  4. Modification history
  5. --------------------
  6. 01a,07jun99,rcb  First.
  7. */
  8. /*
  9. DESCRIPTION
  10. This file contains a generic implementation of O/S-independent queue
  11. functions which are built on top of the the ossLib library's mutex
  12. and semaphore functions.
  13. The caller creates a queue of depth "n" by calling usbQueueCreate() and
  14. receives a QUEUE_HANDLE in response.  The QUEUE_HANDLE must be used in
  15. all subsequent calls to usbQueuePut(), usbQueueGet(), and usbQueueDestroy().
  16. Each entry on a queue is described by a USB_QUEUE structure which contains
  17. <msg>, <wParam>, and <lParam> fields.  The values of these fields are
  18. completely arbitrary and may be used in any way desired by the calling
  19. application.
  20. */
  21. /* includes */
  22. #include "usb/usbPlatform.h"
  23. #include "string.h"
  24. #include "usb/ossLib.h"     
  25. #include "usb/usbQueueLib.h" /* our API */
  26. /* typedefs */
  27. /* Internal queue control structure. */
  28. typedef struct usb_queue 
  29.     {
  30.     UINT16 max;  /* Number of USB_MESSAGE entries allocated */
  31. /* in messages array */
  32.     UINT16 in; /* Index of the next available message slot */
  33.     UINT16 out;  /* Index to the next message to be retrieved */
  34.     SEM_HANDLE inUse; /* Count of messages currently in queue */
  35.     SEM_HANDLE empty; /* Count of empty message slots in queue */
  36.     MUTEX_HANDLE mutex;  /* The handle of the mutex we use to gain */
  37. /* temporary control of the OSS_QUEUE struct */
  38.     USB_MESSAGE messages [1]; /* Pointer to memory allocated for msg queue */
  39.     } USB_QUEUE, *pUSB_QUEUE;
  40. /* functions */
  41. /***************************************************************************
  42. *
  43. * usbQueueCreate - Creates a O/S-independent queue structure
  44. *
  45. * This function creates a queue which can accomodate a number of 
  46. * USB_MESSAGE entries according to the <depth> parameter.  Returns the
  47. * <pQueueHandle) of the newly created queue if successful.
  48. *
  49. * RETURNS: OK or ERROR
  50. *
  51. * ERRNO:
  52. *  S_usbQueueLib_BAD_PARAMETER
  53. *  S_usbQueueLib_OUT_OF_MEMORY
  54. *  S_usbQueueLib_OUT_OF_RESOURCES
  55. */
  56. STATUS usbQueueCreate 
  57.     (
  58.     UINT16 depth,     /* Max entries queue can handle */
  59.     pQUEUE_HANDLE pQueueHandle     /* Handle of newly created queue */
  60.     )
  61.     {
  62.     pUSB_QUEUE pQueue;
  63.     UINT16 len;
  64.     /* Validate parameters (e.g., the depth of the queue must not be 0). */
  65.     if (depth < 1 || pQueueHandle == NULL) {
  66. return ossStatus (S_usbQueueLib_BAD_PARAMETER);
  67.     }
  68.     /* Allocate the queue control structure. */
  69.     len = sizeof (*pQueue) + sizeof (USB_MESSAGE) * (depth - 1);
  70.     if ((pQueue = OSS_CALLOC (len)) == NULL)
  71. return ossStatus (S_usbQueueLib_OUT_OF_MEMORY);
  72.     
  73.     pQueue->max = depth;
  74.     /* Allocate queue control resources. */
  75.     if (OSS_SEM_CREATE (depth, 0, &pQueue->inUse) != OK ||
  76. OSS_SEM_CREATE (depth, depth, &pQueue->empty) != OK ||
  77. OSS_MUTEX_CREATE (&pQueue->mutex) != OK) 
  78. {
  79. usbQueueDestroy ((QUEUE_HANDLE) pQueue);
  80. return ossStatus (S_usbQueueLib_OUT_OF_RESOURCES);
  81. }
  82.     *pQueueHandle = (QUEUE_HANDLE) pQueue;
  83.     return OK;
  84. }
  85. /***************************************************************************
  86. *
  87. * usbQueueDestroy - Destroys a queue
  88. *
  89. * This function destroys a queue created by calling usbQueueCreate().
  90. *
  91. * RETURNS: OK or ERROR.
  92. *
  93. * ERRNO:
  94. *  S_usbQueueLib_BAD_HANDLE
  95. */
  96. STATUS usbQueueDestroy 
  97.     (
  98.     QUEUE_HANDLE queueHandle     /* Hnadle of queue to destroy */
  99.     )
  100.     {
  101.     pUSB_QUEUE pQueue = (pUSB_QUEUE) queueHandle;
  102.     /* Qualify the queue handle. */
  103.     if (pQueue == NULL)
  104. return ossStatus (S_usbQueueLib_BAD_HANDLE);
  105.     /* Release resources and memory associated with the queue. */
  106.     if (pQueue->inUse)
  107. OSS_SEM_DESTROY (pQueue->inUse);
  108.     if (pQueue->empty)
  109. OSS_SEM_DESTROY (pQueue->empty);
  110.     if (pQueue->mutex)
  111. OSS_SEM_DESTROY (pQueue->mutex);
  112.     OSS_FREE (pQueue);
  113.     return OK;
  114. }
  115. /***************************************************************************
  116. *
  117. * usbQueuePut - Puts a message onto a queue
  118. *
  119. * Places the specified <msg>, <wParam>, and <lParam> onto <queueHandle>.
  120. * This function will only block if the specified queue is full.  If the 
  121. * queue is full, <blockFlag> specifies the blocking behavior.  OSS_BLOCK
  122. * blocks indefinitely. OSS_DONT_BLOCK does not block and returns an error
  123. * if the queue is full.  Other values of <blockFlag> are interpreted as
  124. * a count of milliseconds to block before declaring a failure.
  125. *
  126. * RETURNS: OK or ERROR
  127. *
  128. * ERRNO:
  129. *  S_usbQueueLib_BAD_HANDLE
  130. *  S_usbQueueLib_Q_NOT_AVAILABLE
  131. */
  132. STATUS usbQueuePut 
  133.     (
  134.     QUEUE_HANDLE queueHandle,     /* queue handle */
  135.     UINT16 msg,      /* app-specific message */
  136.     UINT16 wParam,     /* app-specific parameter */
  137.     UINT32 lParam,     /* app-specific parameter */
  138.     UINT32 blockFlag     /* specifies blocking action */
  139.     )
  140.     {
  141.     pUSB_QUEUE pQueue = (pUSB_QUEUE) queueHandle;
  142.     /* Qualify the queue handle. */
  143.     if (pQueue == NULL)
  144. return ossStatus (S_usbQueueLib_BAD_HANDLE);
  145.     /* Wait for space to become available in the queue */
  146.     if ((OSS_SEM_TAKE (pQueue->empty, blockFlag)) != OK)
  147. {
  148. return ossStatus (S_usbQueueLib_Q_NOT_AVAILABLE);
  149. }
  150.     else
  151. {
  152. /* Take the queue mutex before attempting to update the queue. */
  153. if ((OSS_MUTEX_TAKE (pQueue->mutex, OSS_BLOCK)) != OK)
  154.     {
  155.     return ossStatus (S_usbQueueLib_Q_NOT_AVAILABLE);
  156.     }
  157. else
  158.     {
  159.     /* Add an entry to the queue. */
  160.     pQueue->messages [pQueue->in].msg = msg;
  161.     pQueue->messages [pQueue->in].wParam = wParam;
  162.     pQueue->messages [pQueue->in].lParam = lParam;
  163.     if (++pQueue->in == pQueue->max)
  164. pQueue->in = 0;
  165.     OSS_SEM_GIVE (pQueue->inUse);
  166.     OSS_MUTEX_RELEASE (pQueue->mutex);
  167.     }
  168. }
  169.     return OK;
  170.     }
  171. /***************************************************************************
  172. *
  173. * usbQueueGet - Retrieves a message from a queue
  174. *
  175. * Retrieves a message from the specified <queueHandle> and stores it in
  176. * <pOssMsg>.  If the queue is empty, <blockFlag> specifies the blocking
  177. * behavior.  OSS_BLOCK blocks indefinitely.  OSS_DONT_BLOCK does not block
  178. * and returns an error immediately if the queue is empty.  Other values of
  179. * <blockFlag> are interpreted as a count of milliseconds to block before
  180. * declaring a failure.
  181. *
  182. * RETURNS: OK or ERROR
  183. * ERRNO:
  184. *  S_usbQueueLib_BAD_HANDLE
  185. *  S_usbQueueLib_Q_NOT_AVAILABLE
  186. */
  187. STATUS usbQueueGet 
  188.     (
  189.     QUEUE_HANDLE queueHandle,     /* queue handle */
  190.     pUSB_MESSAGE pMsg,     /* USB_MESSAGE to receive msg */
  191.     UINT32 blockFlag     /* specifies blocking action */
  192.     )
  193.     {
  194.     pUSB_QUEUE pQueue = (pUSB_QUEUE) queueHandle;
  195.     /* Qualify the queue handle and msg parameters. */
  196.     if (pQueue == NULL)
  197. return ossStatus (S_usbQueueLib_BAD_HANDLE);
  198.     if (pMsg == NULL)
  199. return ossStatus (S_usbQueueLib_BAD_PARAMETER);
  200.     /* Wait for a message to arrive in the queue before proceeding */
  201.     if ((OSS_SEM_TAKE (pQueue->inUse, blockFlag)) != OK) 
  202. {
  203. return ossStatus (S_usbQueueLib_Q_NOT_AVAILABLE);
  204. }
  205.     else
  206. {
  207. /* Take the queue mutex before attempting to update the queue. */
  208. if ((OSS_MUTEX_TAKE (pQueue->mutex, OSS_BLOCK)) != OK) 
  209.     {
  210.     return ossStatus (S_usbQueueLib_Q_NOT_AVAILABLE);
  211.     }
  212. else
  213.     {
  214.     /* Take an entry off the queue. */
  215.     memcpy (pMsg, &pQueue->messages [pQueue->out], 
  216. sizeof (USB_MESSAGE));
  217.     if (++pQueue->out == pQueue->max)
  218. pQueue->out = 0;
  219.     OSS_SEM_GIVE (pQueue->empty);
  220.     OSS_MUTEX_RELEASE (pQueue->mutex);
  221.     }
  222. }
  223.     return OK;
  224.     }
  225. /* End of file */