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

MultiPlatform

  1. /* smFixBlkLib.c - VxWorks fixed block shared memory manager (VxMP Option) */
  2. /* Copyright 1984-2002 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01g,03may02,mas  cache flush and volatile fix (SPR 68334); bridge flush fix
  7.  (SPR 68844)
  8. 01f,24oct01,mas  doc update (SPR 71149)
  9. 01e,20sep01,jws  correct partition spin-lock tries calc (SPR68418)
  10. 01d,29jan93,pme  added little endian support.
  11.                  added #include "private/smObjLibP.h".
  12.  changed MEM_ROUND_UP() to ROUND_UP() in smFixBlkPartInit().
  13. 01c,02oct92,pme  added SPARC support.
  14. 01b,27jul92,pme  added lock timeout failure notification.
  15. 01a,19jul92,pme  written.
  16. */
  17. /*
  18. DESCRIPTION
  19. This library provides a simple facility for managing the 
  20. allocation of fixed size blocks of shared memory from ranges 
  21. of memory called fixed block size shared memory partitions.
  22. There are no user callable routines.
  23. A shared memory fixed block partition is created when the shared memory 
  24. object facility (VxMP) is installed during system startup by VxWorks
  25. initialization code calling smObjSetup().
  26. This memory allocator is only used to allocate shared TCBs in shared memory
  27. and is provided to give a lower interrupt lattency than the 
  28. standard variable block size shared memory manager.
  29. The allocation of a block is done via smFixBlkPartAlloc() and freeing a block
  30. is done via smFixBlkPartFree().
  31. AVAILABILITY
  32. This module is distributed as a component of the unbundled shared memory
  33. support option, VxMP.
  34. INTERNAL
  35. The fixed block memory partition header is stored in the shared memory header
  36. reachable by all CPUs in the system.
  37. There is no overhead per allocated block since blocks have no headers. The
  38. first 8 bytes of each block are used as doubly linked list nodes when 
  39. blocks are in the free list but they are part of the block when it is
  40. allocated to user.
  41. No validity checking is done on blocks passed to smFixBlkPartFree().
  42. INCLUDE FILE: smFixBlkLib.h
  43. SEE ALSO: smObjLib
  44. NOROUTINES
  45. */
  46. /* includes */
  47. #include "vxWorks.h"
  48. #include "memLib.h"
  49. #include "smObjLib.h"
  50. #include "smLib.h"
  51. #include "intLib.h"
  52. #include "smMemLib.h"
  53. #include "string.h"
  54. #include "taskLib.h"
  55. #include "cacheLib.h"
  56. #include "errno.h"
  57. #include "netinet/in.h"
  58. #include "private/smObjLibP.h"
  59. #include "private/smFixBlkLibP.h"
  60. /* defines */
  61. /* locals */
  62. /* number of tries to get access to a shared fixed block memory partition */
  63. LOCAL int smFixBlkSpinTries;
  64. /******************************************************************************
  65. *
  66. * smFixBlkPartInit - initialize a fixed block shared memory partition
  67. *
  68. * smFixBlkPartInit initializes a shared fixed block memory partition.
  69. * This function is used in smObjInit to initialize the shared TCB
  70. * partition.
  71. * <gPartId> is the global (system wide) identifier of the partition to 
  72. * initialize. Its value is the global address of the partition structure. 
  73. *
  74. * <pPool> is the global address of shared memory dedicated to 
  75. * the fixed block partition.
  76. *
  77. * <poolSize> is the size in bytes of shared memory dedicated to the partition.
  78. *
  79. * <blockSize> is the size in bytes of each block in the partition.
  80. *
  81. * NOMANUAL
  82. */
  83. void smFixBlkPartInit 
  84.     (
  85.     SM_FIX_BLK_PART_ID gPartId,   /* global id of partition to initialize */
  86.     char *             pPool,     /* global adress of memory pool */
  87.     unsigned           poolSize,  /* pool size in bytes */
  88.     unsigned           blockSize  /* block size in bytes */
  89.     )
  90.     {
  91.     SM_FIX_BLK_PART_ID volatile partId; /* local addr of partition to init */
  92.     int                         memLeft;
  93.     char *                      tmp;
  94.     int                         numBlock = 0;
  95.     int                         temp;   /* temp storage */
  96.     partId = (SM_FIX_BLK_PART_ID volatile) GLOB_TO_LOC_ADRS (gPartId);
  97.     /* initialize partition descriptor */
  98.     bzero ((char *) partId, sizeof (SM_FIX_BLK_PART));
  99.     partId->blockSize = htonl (blockSize);
  100.     /* insure that the pool starts on an even byte boundary */
  101.     tmp       = (char *) ROUND_UP (pPool, 4); /* get actual start */
  102.     poolSize -= tmp - pPool; /* adjust length */
  103.     pPool     = (char *) GLOB_TO_LOC_ADRS (tmp);/* convert to local address */
  104.     memLeft = poolSize;
  105.     /* initialize free list */
  106.     smDllInit (&partId->freeList);
  107.     /* Insert blocks in the free list */
  108.     while (memLeft >= blockSize)
  109. {
  110.         smDllAdd (&partId->freeList, (SM_DL_NODE *) pPool);
  111. numBlock ++;
  112. pPool += blockSize;
  113. memLeft -= blockSize;
  114. }
  115.     /*
  116.      * initialize number of tries to get partition spin-lock
  117.      * smObjSpinTries has been set to config param SM_OBJ_MAX_TRIES
  118.      * before the call to this routine
  119.      */
  120.     smFixBlkSpinTries = smObjSpinTries;
  121.     partId->totalBlocks = htonl (numBlock);
  122.     partId->objType = htonl (MEM_PART_TYPE_SM_FIX);
  123.     partId->verify = (UINT32) htonl (LOC_TO_GLOB_ADRS (partId));
  124.     CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */
  125.     temp = partId->verify;                      /* BRIDGE FLUSH  [SPR 68334] */
  126.     }
  127.  
  128. /******************************************************************************
  129. *
  130. * smFixBlkPartAlloc - allocate a block of memory from fixed block partition
  131. *
  132. * From a specified fixed block shared partition, this routine 
  133. * allocates one block of memory whose size is equal to the partition blockSize.
  134. * The fixed block partition must have been previously initialized 
  135. * with smFixBlkPartInit().
  136. *
  137. * <gPartId> is the global (system wide) identifier of the partition to 
  138. * use. Its value is the global address of the partition structure. 
  139. *
  140. * RETURNS:
  141. * A local adress of a block, or
  142. * NULL if the call fails.
  143. *
  144. * ERRNO:
  145. *
  146. *   S_objLib_OBJ_ID_ERROR
  147. *
  148. *   S_memLib_NOT_ENOUGH_MEMORY
  149. *
  150. *   S_smObjLib_LOCK_TIMEOUT
  151. *
  152. * SEE ALSO: smFixBlkPartInit()
  153. *
  154. * NOMANUAL
  155. */
  156. void * smFixBlkPartAlloc 
  157.     (
  158.     SM_FIX_BLK_PART_ID gPartId /* global id of partition to allocate from */
  159.     )
  160.     {
  161.     SM_FIX_BLK_PART_ID volatile partId; /* local address of partition */
  162.     void * pBlock; /* local addr of allocated block */
  163.     int                         level;
  164.     int                         temp;   /* temp storage */
  165.     partId = (SM_FIX_BLK_PART_ID volatile) GLOB_TO_LOC_ADRS (gPartId);
  166.     CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */
  167.     temp = partId->verify;                      /* PCI bridge bug [SPR 68844]*/
  168.     if (SM_OBJ_VERIFY (partId) != OK)
  169.         return (NULL);
  170.     /* ENTER LOCKED SECTION */
  171.     if (smLockTake ((int *) &partId->lock, smObjTasRoutine, 
  172.    smFixBlkSpinTries, &level) != OK)
  173. {
  174. smObjTimeoutLogMsg ("smFixBlkPartAlloc", (char *) &partId->lock);
  175. return (NULL); /* can't take lock */
  176. }
  177.     pBlock = (void *) smDllGet (&partId->freeList); /* get a free block */
  178.     if (pBlock == LOC_NULL) /* no more free blocks */
  179. {
  180.         /* EXIT LOCKED SECTION */
  181.         SM_OBJ_LOCK_GIVE ((SM_SEM_ID) &partId->lock, level);
  182. errno = S_memLib_NOT_ENOUGH_MEMORY;
  183. return (NULL);
  184. }
  185.     /* update allocation statistics */
  186.     CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */
  187.     temp = partId->curBlocksAllocated;          /* PCI bridge bug [SPR 68844]*/
  188.     partId->curBlocksAllocated = htonl (ntohl (partId->curBlocksAllocated) +1);
  189.     partId->cumBlocksAllocated = htonl (ntohl (partId->cumBlocksAllocated) +1);
  190.     CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */
  191.     temp = partId->curBlocksAllocated;          /* BRIDGE FLUSH  [SPR 68334] */
  192.     /* EXIT LOCKED SECTION */
  193.     SM_OBJ_LOCK_GIVE ((SM_SEM_ID) &partId->lock, level);
  194.     return ((void *) pBlock);
  195.     }
  196. /******************************************************************************
  197. *
  198. * smFixBlkPartFree - give back a block to a fixed block shared partition
  199. *
  200. * This routine takes a block of memory previously allocated with
  201. * smFixBlkPartAlloc() and returns it to the shared partition's free memory list.
  202. *
  203. * <gPartId> is the global (system wide) identifier of the partition to 
  204. * use. Its value is the global address of the partition structure. 
  205. *
  206. * <pBlock> is a local address of a shared memory block previously allocated
  207. * by smFixBlkPartAlloc.
  208. *
  209. * WARNING: No validy check is done on <pBlock>.
  210. *
  211. * RETURNS: OK or ERROR if partition id is invalid.
  212. *
  213. * ERRNO:
  214. *
  215. *   S_objLib_OBJ_ID_ERROR:
  216. *
  217. *   S_smObjLib_LOCK_TIMEOUT:
  218. *
  219. * NOMANUAL
  220. */
  221. STATUS smFixBlkPartFree 
  222.     (
  223.     SM_FIX_BLK_PART_ID gPartId, /* global id of partition to use */
  224.     char *             pBlock   /* pointer to block of memory to be freed */
  225.     )
  226.     {
  227.     SM_FIX_BLK_PART_ID volatile partId; /* local address of partition to use */
  228.     int                         level;
  229.     int                         temp;   /* temp storage */
  230.     partId = (SM_FIX_BLK_PART_ID volatile) GLOB_TO_LOC_ADRS (gPartId);
  231.     CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */
  232.     temp = partId->verify;                      /* PCI bridge bug [SPR 68844]*/
  233.     if (SM_OBJ_VERIFY (partId) != OK)
  234.         return (ERROR);
  235.     if (pBlock == NULL)
  236. return (OK); /* ANSI C compatibility */
  237.     /* 
  238.      * If attempt to take lock fails here we only return ERROR,
  239.      * we do not notify the failure since this function is only called
  240.      * in taskDelete which will send a WARNING.
  241.      */
  242.      /* ENTER LOCKED SECTION */
  243.     if (smLockTake ((int *) &partId->lock, smObjTasRoutine,
  244.                     smFixBlkSpinTries, &level) != OK)
  245. return (ERROR); /* can't take lock */
  246.     /* add the block to the free list */
  247.     smDllInsert ((SM_DL_LIST *) &partId->freeList, (SM_DL_NODE *) NULL,
  248.  (SM_DL_NODE *) (pBlock));
  249.     /* adjust allocation statistics */
  250.     CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */
  251.     temp = partId->curBlocksAllocated;          /* PCI bridge bug [SPR 68844]*/
  252.     partId->curBlocksAllocated = htonl (ntohl (partId->curBlocksAllocated) - 1);
  253.     CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */
  254.     temp = partId->curBlocksAllocated;          /* BRIDGE FLUSH  [SPR 68334] */
  255.     /* EXIT LOCKED SECTION */
  256.     SM_OBJ_LOCK_GIVE ((SM_SEM_ID) &partId->lock, level);
  257.     return (OK);
  258.     }