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

VxWorks

开发平台:

C/C++

  1. /* dllLib.c - efficient doubly linked list subroutine library */
  2. /* Copyright 1984-1998 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01n,11nov01,dee  Add ColdFire support
  8. 01m,04sep98,cdp  make ARM CPUs with ARM_THUMB==TRUE use portable routines.
  9. 01n,07mar00,zl   fixed syntax error from merge
  10. 01m,03mar00,zl   merged SH support from T1
  11. 01l,22apr97,jpd  added support for optimised ARM code.
  12. 01k,19mar95,dvs  removing tron references.
  13. 01j,09jun93,hdn  added a support for I80X86
  14. 01i,09jul92,hdn  put an optimized dllGet()
  15. 01h,24jun92,ajm  pulled in optimizations for mips
  16. 01g,26may92,rrr  the tree shuffle
  17. 01f,19nov91,rrr  shut up some ansi warnings.
  18. 01e,04oct91,rrr  passed through the ansification filter
  19.                   -changed functions to ansi style
  20.   -fixed #else and #endif
  21.   -changed VOID to void
  22.   -changed copyright notice
  23. 01d,23jul91,hdn  added conditional macro for optimized TRON codes.
  24. 01c,28oct90,jcf  documentation.
  25. 01b,10may90,jcf  fixed PORTABLE definition.
  26. 01a,03jun89,jcf  written.
  27. */
  28. /*
  29. DESCRIPTION
  30. This subroutine library supports the creation and maintenance of a
  31. doubly linked list.  The user supplies a list descriptor (type DL_LIST)
  32. that will contain pointers to the first and last nodes in the list.
  33. The nodes in the list can be any user-defined structure, but they must reserve
  34. space for a pointer as their first element.  The forward chain is terminated
  35. with a NULL pointer.
  36. This library in conjunction with dllALib.s, and the macros defined in dllLib.h,
  37. provide a reduced version of the routines offered in lstLib(1).  For
  38. efficiency, the count field has been eliminated, and enqueueing and dequeueing
  39. functions have been hand optimized.
  40. .ne 16
  41. NON-EMPTY LIST:
  42. .CS
  43.    ---------             --------          --------
  44.    | head--------------->| next----------->| next---------
  45.    |       |             |      |          |      |      |
  46.    |       |        ------ prev |<---------- prev |      |
  47.    |       |       |     |      |          |      |      |
  48.    | tail------    |     | ...  |    ----->| ...  |      |
  49.    |-------|  |    v                 |                   v
  50.               |  -----               |                 -----
  51.               |   ---                |                  ---
  52.               |    -                 |                   -
  53.               ------------------------
  54. .CE
  55. .ne 12
  56. EMPTY LIST:
  57. .CS
  58. -----------
  59.         |  head------------------
  60.         |         |             |
  61.         |  tail----------       |
  62.         |         |     v       v
  63.         |         |   -----   -----
  64.         -----------    ---     ---
  65.                         - -
  66. .CE
  67. INCLUDE FILE: dllLib.h
  68. */
  69. /* LINTLIBRARY */
  70. #include "vxWorks.h"
  71. #include "dllLib.h"
  72. #include "stdlib.h"
  73. /*
  74.  * optimized version available for 680X0, MIPS, I80X86, SH and ARM,
  75.  * but not yet Thumb.
  76.  */
  77. #if (defined(PORTABLE) || 
  78.      ((CPU_FAMILY != MC680X0) && 
  79.       (CPU_FAMILY != MIPS) && 
  80.       (CPU_FAMILY != I80X86) && 
  81.       (CPU_FAMILY != SH) && 
  82.       (CPU_FAMILY != COLDFIRE) && 
  83.       (CPU_FAMILY != ARM)) || 
  84.      ((CPU_FAMILY == ARM) && ARM_THUMB))
  85. #define dllLib_PORTABLE
  86. #endif
  87. /*********************************************************************
  88. *
  89. * dllCreate - create a doubly linked list descriptor
  90. *
  91. * This routine returns a pointer to an initialized doubly linked list
  92. * descriptor.
  93. *
  94. * RETURNS: Pointer to a doubly linked list descriptor, or NULL if ERROR.
  95. */
  96. DL_LIST *dllCreate (void)
  97.     {
  98.     FAST DL_LIST *pList = (DL_LIST *) malloc ((unsigned) sizeof (DL_LIST));
  99.     dllInit (pList);
  100.     return (pList);
  101.     }
  102. /*********************************************************************
  103. *
  104. * dllInit - initialize doubly linked list descriptor
  105. *
  106. * Initialize the specified list to an empty list.
  107. *
  108. * RETURNS: OK, or ERROR if doubly linked list could not be initialized.
  109. */
  110. STATUS dllInit
  111.     (
  112.     FAST DL_LIST *pList     /* pointer to list descriptor to be initialized */
  113.     )
  114.     {
  115.     pList->head  = NULL;
  116.     pList->tail  = NULL;
  117.     return (OK);
  118.     }
  119. /*******************************************************************************
  120. *
  121. * dllDelete - terminate doubly linked list head free associated memory
  122. *
  123. * Terminate the specified list and deallocated associated memory.
  124. *
  125. * RETURNS: OK, or ERROR if doubly linked list could not be deleted.
  126. *
  127. * ARGSUSED
  128. */
  129. STATUS dllDelete
  130.     (
  131.     DL_LIST *pList     /* pointer to list head to be initialized */
  132.     )
  133.     {
  134.     free ((char *) pList); /* free list */
  135.     return OK;
  136.     }
  137. /*******************************************************************************
  138. *
  139. * dllTerminate - terminate doubly linked list head
  140. *
  141. * Terminate the specified list without deallocating associated memory.
  142. *
  143. * RETURNS: OK, or ERROR if doubly linked list could not be terminated.
  144. *
  145. * ARGSUSED
  146. */
  147. STATUS dllTerminate
  148.     (
  149.     DL_LIST *pList     /* pointer to list head to be initialized */
  150.     )
  151.     {
  152.     return (OK);
  153.     }
  154. #ifdef dllLib_PORTABLE
  155. /************************************************************************
  156. *
  157. * dllInsert - insert node in list after specified node
  158. *
  159. * This routine inserts the specified node in the specified list.
  160. * The new node is placed following the specified 'previous' node in the list.
  161. * If the specified previous node is NULL, the node is inserted at the head
  162. * of the list.
  163. */
  164. void dllInsert
  165.     (
  166.     FAST DL_LIST *pList,        /* pointer to list descriptor */
  167.     FAST DL_NODE *pPrev,        /* pointer to node after which to insert */
  168.     FAST DL_NODE *pNode         /* pointer to node to be inserted */
  169.     )
  170.     {
  171.     FAST DL_NODE *pNext;
  172.     if (pPrev == NULL)
  173. { /* new node is to be first in list */
  174. pNext = pList->head;
  175. pList->head = pNode;
  176. }
  177.     else
  178. { /* make prev node point fwd to new */
  179. pNext = pPrev->next;
  180. pPrev->next = pNode;
  181. }
  182.     if (pNext == NULL)
  183. pList->tail = pNode; /* new node is to be last in list */
  184.     else
  185. pNext->previous = pNode; /* make next node point back to new */
  186.     /* set pointers in new node */
  187.     pNode->next = pNext;
  188.     pNode->previous = pPrev;
  189.     }
  190. /************************************************************************
  191. *
  192. * dllAdd - add node to end of list
  193. *
  194. * This routine adds the specified node to the end of the specified list.
  195. */
  196. void dllAdd
  197.     (
  198.     DL_LIST *pList,     /* pointer to list descriptor */
  199.     DL_NODE *pNode      /* pointer to node to be added */
  200.     )
  201.     {
  202.     dllInsert (pList, pList->tail, pNode);
  203.     }
  204. /************************************************************************
  205. *
  206. * dllRemove - remove specified node in list
  207. *
  208. * Remove the specified node in the doubly linked list.
  209. */
  210. void dllRemove
  211.     (
  212.     DL_LIST *pList,             /* pointer to list descriptor */
  213.     DL_NODE *pNode              /* pointer to node to be deleted */
  214.     )
  215.     {
  216.     if (pNode->previous == NULL)
  217. pList->head = pNode->next;
  218.     else
  219. pNode->previous->next = pNode->next;
  220.     if (pNode->next == NULL)
  221. pList->tail = pNode->previous;
  222.     else
  223. pNode->next->previous = pNode->previous;
  224.     }
  225. /************************************************************************
  226. *
  227. * dllGet - get (delete and return) first node from list
  228. *
  229. * This routine gets the first node from the specified list, deletes the node
  230. * from the list, and returns a pointer to the node gotten.
  231. *
  232. * RETURNS: Pointer to the node gotten, or NULL if the list is empty.
  233. */
  234. DL_NODE *dllGet
  235.     (
  236.     FAST DL_LIST *pList         /* pointer to list from which to get node */
  237.     )
  238.     {
  239.     FAST DL_NODE *pNode = pList->head;
  240.     if (pNode != NULL)                      /* is list empty? */
  241. {
  242.         pList->head = pNode->next;          /* make next node be 1st */
  243.         if (pNode->next == NULL)            /* is there any next node? */
  244.             pList->tail = NULL;             /*   no - list is empty */
  245.         else
  246.             pNode->next->previous = NULL;   /*   yes - make it 1st node */
  247. }
  248.     return (pNode);
  249.     }
  250. #endif /* dllLib_PORTABLE */
  251. /**************************************************************************
  252. *
  253. * dllCount - report number of nodes in list
  254. *
  255. * This routine returns the number of nodes in the given list.
  256. *
  257. * CAVEAT
  258. * This routine must actually traverse the list to count the nodes.
  259. * If counting is a time critical fuction, consider using lstLib(1) which
  260. * maintains a count field.
  261. *
  262. * RETURNS: Number of nodes in specified list.
  263. *
  264. * SEE ALSO: lstLib(1).
  265. */
  266. int dllCount
  267.     (
  268.     DL_LIST *pList      /* pointer to list descriptor */
  269.     )
  270.     {
  271.     FAST DL_NODE *pNode = DLL_FIRST (pList);
  272.     FAST int count = 0;
  273.     while (pNode != NULL)
  274. {
  275. count++;
  276. pNode = DLL_NEXT (pNode);
  277. }
  278.     return (count);
  279.     }
  280. /*******************************************************************************
  281. *
  282. * dllEach - call a routine for each node in a linked list
  283. *
  284. * This routine calls a user-supplied routine once for each node in the
  285. * linked list.  The routine should be declared as follows:
  286. *
  287. * .CS
  288. *  BOOL routine (pNode, arg)
  289. *      DL_NODE *pNode; /@ pointer to a linked list node    @/
  290. *      int arg; /@ arbitrary user-supplied argument @/
  291. * .CE
  292. *
  293. * The user-supplied routine should return TRUE if dllEach() is to
  294. * continue calling it with the remaining nodes, or FALSE if it is done and
  295. * dllEach() can exit.
  296. *
  297. * RETURNS: NULL if traversed whole linked list, or pointer to DL_NODE that
  298. *          dllEach ended with.
  299. */
  300. DL_NODE *dllEach
  301.     (
  302.     DL_LIST     *pList,         /* linked list of nodes to call routine for */
  303.     FUNCPTR     routine,        /* the routine to call for each list node */
  304.     int         routineArg      /* arbitrary user-supplied argument */
  305.     )
  306.     {
  307.     FAST DL_NODE *pNode = DLL_FIRST (pList);
  308.     while ((pNode != NULL) && ((* routine) (pNode, routineArg)))
  309. pNode = DLL_NEXT (pNode);
  310.     return (pNode); /* return node we ended with */
  311.     }