distTBufLib.c
上传用户:baixin
上传日期:2008-03-13
资源大小:4795k
文件大小:8k
开发平台:

MultiPlatform

  1. /* distTBufLib.c - distributed objects telegram buffer library (VxFusion option) */
  2. /* Copyright 1999 - 2002 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01g,26nov01,jws  fix void ptr arith not seen by diab (SPR 71154)
  7. 01f,30oct01,jws  fix man pages (SPR 71239)
  8. 01e,24may99,drm  added vxfusion prefix to VxFusion related includes
  9. 01d,23feb99,wlf  doc edits
  10. 01c,18feb99,wlf  doc cleanup
  11. 01b,29oct98,drm  documentation updates
  12. 01a,03sep97,ur   written.
  13. */
  14. /*
  15. DESCRIPTION
  16. This library provides routines for allocating and freeing telegram buffers.  
  17. Telegrams are the largest packets that can be sent between nodes by the 
  18. distributed objects product; their size is limited by the MTU size of the
  19. underlying communications.  If a distributed objects message exceeds the space 
  20. allocated in a telegram for message data, that message is divided 
  21. into multiple telegrams that are sent out in sequence. 
  22. AVAILABILITY
  23. This module is distributed as a component of the unbundled distributed
  24. message queues option, VxFusion.
  25. INCLUDE FILES: distTBufLib.h
  26. */
  27. #include "vxWorks.h"
  28. #ifdef DIST_DIAGNOSTIC
  29. #include "stdio.h"
  30. #endif
  31. #include "stdlib.h"
  32. #include "string.h"
  33. #include "semLib.h"
  34. #include "private/semLibP.h"
  35. #include "vxfusion/distIfLib.h"
  36. #include "vxfusion/distStatLib.h"
  37. #include "vxfusion/private/distNetLibP.h"
  38. #include "vxfusion/private/distTBufLibP.h"
  39. /* defines */
  40. #define MIN(a,b)    (((a) < (b)) ? (a) : (b))
  41. /* local variables */
  42. LOCAL BOOL                distTBufLibInstalled = FALSE;
  43. LOCAL DIST_TBUF_POOL      distTBufPool;
  44. LOCAL int                 tbHSz, ifHSz, ifDSz, tBufSize;
  45. LOCAL SEMAPHORE           distTBufPoolLock;
  46. /***************************************************************************
  47. *
  48. * distTBufLibInit - pre-allocate a pool of telegram buffers (VxFusion option)
  49. *
  50. * This routine initializes a pool of telegram buffers.
  51. *
  52. * AVAILABILITY
  53. * This routine is distributed as a component of the unbundled distributed
  54. * message queues option, VxFusion.
  55. *
  56. * RETURNS: OK, when successful.  ERROR, when initialization fails.
  57. * NOMANUAL
  58. */
  59. STATUS distTBufLibInit
  60.     (
  61.     int      numTBufs    /* the number of buffers to allocate */
  62.     )
  63.     {
  64.     int    i;
  65.     char * pPool;
  66.     char * p;
  67.     if (distTBufLibInstalled == TRUE)
  68.         return (OK);
  69.     tbHSz = MEM_ROUND_UP (sizeof (DIST_TBUF));
  70.     ifHSz = MEM_ROUND_UP (DIST_IF_HDR_SZ);
  71.     ifDSz = MEM_ROUND_UP (DIST_IF_MTU - DIST_IF_HDR_SZ);
  72.     tBufSize = tbHSz + ifHSz + ifDSz;
  73.     if (tBufSize < MEM_ROUND_UP (sizeof (DIST_TBUF_HDR)))
  74.         tBufSize = MEM_ROUND_UP (sizeof (DIST_TBUF_HDR));
  75.     if ((pPool = (char *) malloc (numTBufs * tBufSize)) == NULL)
  76.         {
  77. #ifdef DIST_DIAGNOSTIC
  78.         printf ("distTBufLibInit: memory allocation failedn");
  79. #endif
  80.         return (ERROR);
  81.         }
  82.     distTBufPool.pTBufFree = (DIST_TBUF *) pPool;
  83.     for (p = pPool, i = 1; i < numTBufs; p += tBufSize, i++)
  84.         {
  85.         ((DIST_TBUF_GEN *) p)->pTBufGenNext = (DIST_TBUF_GEN *) (p + tBufSize);
  86.         }
  87.     ((DIST_TBUF_GEN *) p)->pTBufGenNext = NULL;
  88.     semBInit (&distTBufPoolLock, SEM_Q_PRIORITY, SEM_FULL);
  89.     distTBufLibInstalled = TRUE;
  90.     return (OK);
  91.     }
  92. /***************************************************************************
  93. *
  94. * distTBufAlloc - allocate a telegram buffer from the pool of buffers (VxFusion option)
  95. *
  96. * This routine allocates a telegram buffer from a pre-allocated pool
  97. * of telegram buffers.
  98. *
  99. * It is the responsibility of the caller to use the distTBufFree() routine to
  100. * free the buffer when the caller is finished with it.
  101. *
  102. * AVAILABILITY
  103. * This routine is distributed as a component of the unbundled distributed
  104. * message queues option, VxFusion.
  105. *
  106. * RETURNS: A pointer to a DIST_TBUF, or NULL if the allocation fails.
  107. *
  108. * SEE ALSO: distTBufFree
  109. */
  110. DIST_TBUF * distTBufAlloc (void)
  111.     {
  112.     DIST_TBUF * pTBuf;
  113.     distTBufPoolLock();
  114.     if ((pTBuf = distTBufPool.pTBufFree) != NULL)
  115.         {
  116.         distTBufPool.pTBufFree =
  117.                 (DIST_TBUF *) ((DIST_TBUF_GEN *) pTBuf)->pTBufGenNext;
  118.         distTBufPoolUnlock();
  119.         bzero ((char *) pTBuf, tBufSize);
  120.         
  121.         pTBuf->pTBufData = ((char *) pTBuf) + tbHSz + ifHSz;
  122.         ((DIST_TBUF_GEN *) pTBuf)->pTBufGenNext = NULL;
  123.         ((DIST_TBUF_GEN *) pTBuf)->pTBufGenLast = (DIST_TBUF_GEN *) pTBuf;
  124. #ifdef DIST_DIAGNOSTIC
  125.         pTBuf->tBufHeader = FALSE;
  126. #endif
  127.         return (pTBuf);
  128.         }
  129.     distTBufPoolUnlock();
  130.     distStat.tBufShortage++;
  131.     return (NULL);
  132.     }
  133. /***************************************************************************
  134. *
  135. * distTBufAllocHdr - allocate a DIST_TBUF_HDR object (VxFusion option)
  136. *
  137. * This routine allocates and returns a pointer to a DIST_TBUF_HDR.
  138. *
  139. * AVAILABILITY
  140. * This routine is distributed as a component of the unbundled distributed
  141. * message queues option, VxFusion.
  142. *
  143. * RETURNS: A pointer to the DIST_TBUF_HDR, or NULL.
  144. * NOMANUAL
  145. */
  146. DIST_TBUF_HDR * distTBufAllocHdr (void)
  147.     {
  148.     DIST_TBUF_HDR * pTBufHdr;
  149.     distTBufPoolLock();
  150.     if ((pTBufHdr = (DIST_TBUF_HDR *) distTBufPool.pTBufFree) != NULL)
  151.         {
  152.         distTBufPool.pTBufFree =
  153.                 (DIST_TBUF *) ((DIST_TBUF_GEN *) pTBufHdr)->pTBufGenNext;
  154.         distTBufPoolUnlock();
  155.         bzero ((char *) pTBufHdr, tBufSize);
  156.         ((DIST_TBUF_GEN *) pTBufHdr)->pTBufGenNext = NULL;
  157.         ((DIST_TBUF_GEN *) pTBufHdr)->pTBufGenLast =
  158.                                              (DIST_TBUF_GEN *) pTBufHdr;
  159.         pTBufHdr->pTBufHdrNext = pTBufHdr->pTBufHdrPrev = NULL;
  160.         pTBufHdr->pTBufHdrLast = pTBufHdr;
  161.         pTBufHdr->pTBufHdrTm = NULL;
  162. #ifdef DIST_DIAGNOSTIC
  163.         pTBufHdr->tBufHdrHeader = TRUE;
  164. #endif
  165.         return (pTBufHdr);
  166.         }
  167.     distTBufPoolUnlock();
  168.     distStat.tBufShortage++;
  169.     return (NULL);
  170.     }
  171. /***************************************************************************
  172. *
  173. * distTBufFree - return a telegram buffer to the pool of buffers (VxFusion option)
  174. *
  175. * This routine returns a buffer previously allocated to a caller back to
  176. * the pool of free telegram buffers.
  177. *
  178. * AVAILABILITY
  179. * This routine is distributed as a component of the unbundled distributed
  180. * message queues option, VxFusion.
  181. *
  182. * RETURNS: N/A
  183. *
  184. * SEE ALSO: distTBufAlloc
  185. */
  186. void distTBufFree
  187.     (
  188.     DIST_TBUF * pTBuf  /* ptr to buffer to be returned to pool */
  189.     )
  190.     {
  191.     distTBufPoolLock();
  192.     ((DIST_TBUF_GEN *) pTBuf)->pTBufGenNext =
  193.             (DIST_TBUF_GEN *) distTBufPool.pTBufFree;
  194.     distTBufPool.pTBufFree = pTBuf;
  195.     distTBufPoolUnlock();
  196.     }
  197. /***************************************************************************
  198. *
  199. * distTBufCopy - copies from tBuf list to buffer (VxFusion option)
  200. *
  201. * This routine copies bytes from a DIST_TBUF to a buffer.
  202. *
  203. * AVAILABILITY
  204. * This routine is distributed as a component of the unbundled distributed
  205. * message queues option, VxFusion.
  206. *
  207. * RETURNS: The number of bytes copied.
  208. * NOMANUAL
  209. */
  210. int distTBufCopy
  211.     (
  212.     DIST_TBUF * pTBuf,   /* source DIST_TBUF */
  213.     int         offset,  /* byte offset into pTBuf */
  214.     char *      dest,    /* destination */
  215.     int         nBytes   /* maximum bytes to transfer */
  216.     )
  217.     {
  218.     int    copied = 0;
  219.     int    len;
  220.     do
  221.         {
  222.         if (offset == 0 || (offset - pTBuf->tBufNBytes) < 0)
  223.             {
  224.             len = MIN (nBytes, (pTBuf->tBufNBytes - offset));
  225.             bcopy (((char *)pTBuf->pTBufData + offset), dest, len);
  226.             nBytes -= len;
  227.             dest += len;
  228.             copied += len;
  229.             offset = 0;
  230.             }
  231.         else
  232.             offset -= pTBuf->tBufNBytes;
  233.         }
  234.     while (nBytes > 0 && (pTBuf = DIST_TBUF_GET_NEXT (pTBuf)));
  235.     return (copied);
  236.     }