• Double Link List


     1 #ifndef __USBH_X_DLIST_H__
     2 #define __USBH_X_DLIST_H__
     3 
     4 #include "USBH.h"
     5 #include "USBH_Int.h"
     6 #include <string.h>
     7 #include <stdlib.h>   // for atoi(), exit(), malloc(), free()
     8 #include <stddef.h>   // for offsetof()
     9 
    10 #if (0)
    11 
    12 // Double linked list structure. Can be used as either a list head, or as link words.
    13 
    14 // @struct USBH_DLIST |
    15 //   The USBH_DLIST structure is the link element of the double linked list. It is used as either a list head, or as link entry.
    16 // @field  struct tDLIST * | Flink |
    17 //   Pointer to the successor (forward link).
    18 // @field  struct tDLIST * | pPrev |
    19 //   Pointer to the predecessor (backward link).
    20 // @comm By means of such elements any structures may be handled as a double linked list. The USBH_DLIST structure is to be inserted
    21 //   into the structure which is to be handled. A pointer to the original structure can be obtained by means of the macro <f STRUCT_BASE_POINTER>.
    22 typedef struct USBH_DLIST USBH_DLIST;
    23 struct USBH_DLIST
    24 {
    25   USBH_DLIST * pNext;
    26   USBH_DLIST * pPrev;
    27 };
    28 
    29 typedef struct USBH_DLIST_ITEM
    30 {
    31   struct USBH_DLIST_ITEM * pNext;
    32   struct USBH_DLIST_ITEM * pPrev;
    33 }USBH_DLIST_ITEM;
    34 
    35 typedef struct
    36 {
    37   struct USBH_DLIST_ITEM * pFirst;
    38   int NumItems;
    39 }USBH_DLIST_HEAD;
    40 
    41 #endif
    42 
    43 #define offset_of_member( struct_name, member_name ) \
    44   ( (unsigned int) (&  (  (struct_name *) 0 ) -> member_name ) )
    45 
    46 #define container_of(ptr, type, member) \
    47   ( (type *)( (char *)ptr - offset_of_member(type,member) ) )
    48 
    49 void USBH_DLIST_Init(USBH_DLIST * ListHead);
    50 int USBH_DLIST_IsEmpty(USBH_DLIST * ListHead);
    51 void USBH_DLIST_Append(USBH_DLIST * ListHead, USBH_DLIST * List);
    52 void USBH_DLIST_InsertTail(USBH_DLIST * ListHead, USBH_DLIST * Entry);
    53 void USBH_DLIST_InsertHead(USBH_DLIST * ListHead, USBH_DLIST * Entry);
    54 void USBH_DLIST_InsertEntry(USBH_DLIST * Entry, USBH_DLIST * NewEntry);
    55 void USBH_DLIST_RemoveTail(USBH_DLIST * ListHead, USBH_DLIST ** Entry);
    56 void USBH_DLIST_RemoveHead(USBH_DLIST * ListHead, USBH_DLIST ** Entry);
    57 void USBH_DLIST_RemoveEntry(USBH_DLIST * Entry);
    58 USBH_DLIST * USBH_DLIST_GetPrev(USBH_DLIST * Entry);
    59 USBH_DLIST * USBH_DLIST_GetNext(USBH_DLIST * Entry);
    60 
    61 void USBH_DLIST_Add(USBH_DLIST_HEAD * pHead, USBH_DLIST_ITEM * pNew);
    62 void USBH_DLIST_Remove(USBH_DLIST_HEAD * pHead, USBH_DLIST_ITEM * pItem);
    63 
    64 //******************************************************************************
    65 // Added
    66 //******************************************************************************
    67 
    68 typedef unsigned int (*NODE_MATCH_FUNC)(USBH_DLIST * Entry, void * pContext);
    69 
    70 void USBH_X_DLIST_DeleteNode(USBH_DLIST * Entry, unsigned int EntryOffset);
    71 void USBH_X_DLIST_DeleteAllNodes(USBH_DLIST * pHead, unsigned int EntryOffset);
    72 void USBH_X_DLIST_DeleteMatchedNode(USBH_DLIST * pHead,
    73     unsigned int EntryOffset, NODE_MATCH_FUNC NodeMacthFunc, void * pContext);
    74 USBH_DLIST * USBH_X_DLIST_AddNode(USBH_DLIST * pHead,
    75     unsigned int NodeEntryOffset, unsigned int NodeSize);
    76 
    77 void USBH_X_DLIST_Test(void);
    78 
    79 #endif /* __USBH_X_DLIST_H__ */
      1 #include "USBH_X_Dlist.h"
      2 
      3 #if (0)
      4 
      5 void USBH_DLIST_Init(USBH_DLIST * ListHead);
      6 int USBH_DLIST_IsEmpty(USBH_DLIST * ListHead);
      7 void USBH_DLIST_Append(USBH_DLIST * ListHead, USBH_DLIST * List);
      8 void USBH_DLIST_InsertTail(USBH_DLIST * ListHead, USBH_DLIST * Entry);
      9 void USBH_DLIST_InsertHead(USBH_DLIST * ListHead, USBH_DLIST * Entry);
     10 void USBH_DLIST_InsertEntry(USBH_DLIST * Entry, USBH_DLIST * NewEntry);
     11 void USBH_DLIST_RemoveTail(USBH_DLIST * ListHead, USBH_DLIST ** Entry);
     12 void USBH_DLIST_RemoveHead(USBH_DLIST * ListHead, USBH_DLIST ** Entry);
     13 void USBH_DLIST_RemoveEntry(USBH_DLIST * Entry);
     14 USBH_DLIST * USBH_DLIST_GetPrev(USBH_DLIST * Entry);
     15 USBH_DLIST * USBH_DLIST_GetNext(USBH_DLIST * Entry);
     16 
     17 /*********************************************************************
     18  *
     19  *       USBH_DLIST
     20  */
     21 
     22 void USBH_DLIST_EmptyHead(USBH_DLIST_HEAD * pHead);
     23 void USBH_DLIST_Add(USBH_DLIST_HEAD * pHead, USBH_DLIST_ITEM * pNew);
     24 void USBH_DLIST_Remove(USBH_DLIST_HEAD * pHead, USBH_DLIST_ITEM * pItem);
     25 
     26 // USBH_DLIST_Init
     27 //     STR     R0, [R0,#4]
     28 //     STR     R0, [R0]
     29 //     BX      LR
     30 void USBH_DLIST_Init(USBH_DLIST * ListHead)
     31 {
     32   ListHead->pPrev = ListHead;
     33   ListHead->pNext = ListHead;
     34 }
     35 
     36 // USBH_DLIST_Append
     37 //     LDR     R2, [R0,#4]
     38 //     STR     R1, [R2]
     39 //     LDR     R3, [R1,#4]
     40 //     STR     R0, [R3]
     41 //     LDR     R3, [R1,#4]
     42 //     STR     R3, [R0,#4]
     43 //     STR     R2, [R1,#4]
     44 //     BX      LR
     45 
     46 //  /---<<<<<<<<<<<<<<<<<<<<<<pNext---\         /---<<<<<<<<<<<<<<<<<<pNext---\
     47  //  ListHead <----> 0 <----> 1 <----> N         List <----> 0 <----> 1 <----> N
     48 //  pPrev >>>>>>>>>>>>>>>>>>>>>>>>>---/         pPrev >>>>>>>>>>>>>>>>>>>>>---/
     49 //
     50 //  /---<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<pNext---\
     51  //  ListHead <----> 0 <----> 1 <----> N <---->  List <----> 0 <----> 1 <----> N
     52 //  pPrev >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>---/
     53 void USBH_DLIST_Append(USBH_DLIST * ListHead, USBH_DLIST * List)
     54 {
     55   ListHead->pPrev->pNext = List;
     56   List->pPrev->pNext = ListHead;
     57   ListHead->pPrev = List->pPrev;
     58   List->pPrev = ListHead->pPrev;
     59 }
     60 
     61 // USBH_DLIST_IsEmpty
     62 //     LDR     R1, [R0]
     63 //     CMP     R1, R0
     64 //     ITE EQ
     65 //     MOVEQ   R0, #1
     66 //     MOVNE   R0, #0
     67 //     BX      LR
     68 int USBH_DLIST_IsEmpty(USBH_DLIST * ListHead)
     69 {
     70   return ListHead == ListHead->pNext;
     71 }
     72 
     73 // USBH_DLIST_GetNext          USBH_DLIST_GetPrev
     74 //     LDR     R0, [R0]            LDR     R0, [R0,#4]
     75 //     BX      LR                  BX      LR
     76 USBH_DLIST * USBH_DLIST_GetNext(USBH_DLIST * Entry)
     77 {
     78   return Entry->pNext;
     79 }
     80 USBH_DLIST * USBH_DLIST_GetPrev(USBH_DLIST * Entry)
     81 {
     82   return Entry->pPrev;
     83 }
     84 
     85 //                             USBH_DLIST_RemoveHead     USBH_DLIST_RemoveTail
     86 //                                LDR     R0, [R0]          LDR     R0, [R0,#4]
     87 // USBH_DLIST_RemoveEntry         STR     R0, [R1]          STR     R0, [R1]
     88 //
     89 //    LDRD.W  R1, R2, [R0]        LDRD.W  R1, R2, [R0]      LDRD.W  R1, R2, [R0]
     90 //    STR     R1, [R2]            STR     R1, [R2]          STR     R1, [R2]
     91 //
     92 //    LDRD.W  R1, R2, [R0]        LDRD.W  R1, R2, [R0]      LDRD.W  R1, R2, [R0]
     93 //    STR     R2, [R1,#4]         STR     R2, [R1,#4]       STR     R2, [R1,#4]
     94 //
     95 //    STR     R0, [R0,#4]         STR     R0, [R0,#4]       STR     R0, [R0,#4]
     96 //    STR     R0, [R0]            STR     R0, [R0]          STR     R0, [R0]
     97 //    BX      LR                  BX      LR                BX      LR
     98 
     99 // pPrev [ Entry ] pNext ---> pPrev pNext
    100 void USBH_DLIST_RemoveEntry(USBH_DLIST * Entry)
    101 {
    102   Entry->pPrev->pNext = Entry->pNext;
    103   Entry->pNext->pPrev = Entry->pPrev;
    104   //USBH_DLIST_Init( Entry );
    105   Entry->pPrev = Entry;
    106   Entry->pNext = Entry;
    107 }
    108 
    109 void USBH_DLIST_RemoveHead(USBH_DLIST * ListHead, USBH_DLIST ** Entry)
    110 {
    111   ( *Entry )->pNext = ListHead->pNext;
    112   USBH_DLIST_RemoveEntry( ListHead->pNext );
    113 }
    114 
    115 void USBH_DLIST_RemoveTail(USBH_DLIST * ListHead, USBH_DLIST ** Entry)
    116 {
    117   ( *Entry )->pNext = ListHead->pPrev;
    118   USBH_DLIST_RemoveEntry( ListHead->pPrev );
    119 }
    120 
    121 //                                                       USBH_DLIST_InsertTail
    122 // USBH_DLIST_InsertEntry      USBH_DLIST_InsertHead         LDR     R0, [R0,#4]
    123 //     LDR     R2, [R0]            LDR     R2, [R0]          LDR     R2, [R0]
    124 //     STRD.W  R2, R0, [R1]        STRD.W  R2, R0, [R1]      STRD.W  R2, R0, [R1]
    125 //     LDR     R2, [R0]            LDR     R2, [R0]          LDR     R2, [R0]
    126 //     STR     R1, [R2,#4]         STR     R1, [R2,#4]       STR     R1, [R2,#4]
    127 //     STR     R1, [R0]            STR     R1, [R0]          STR     R1, [R0]
    128 //     BX      LR                  BX      LR                BX      LR
    129 
    130 void USBH_DLIST_InsertEntry(USBH_DLIST * Entry, USBH_DLIST * NewEntry)
    131 {
    132   NewEntry->pNext = Entry->pNext;
    133   NewEntry->pPrev = Entry;
    134 
    135   Entry->pNext->pPrev = NewEntry;
    136   Entry->pNext = NewEntry;
    137 }
    138 
    139 void USBH_DLIST_InsertHead(USBH_DLIST * ListHead, USBH_DLIST * Entry)
    140 {
    141   USBH_DLIST_InsertEntry( ListHead, Entry );
    142 }
    143 
    144 void USBH_DLIST_InsertTail(USBH_DLIST * ListHead, USBH_DLIST * Entry)
    145 {
    146   USBH_DLIST_InsertEntry( ListHead->pPrev, Entry );
    147 }
    148 
    149 // USBH_DLIST_Add
    150 //     MOVS    R2, #0
    151 //     STR     R2, [R1,#4]   ; pNew->pPrev = 0;
    152 //
    153 //     LDR     R2, [R0]
    154 //     STR     R2, [R1]      ; pNew->pNext = pHead->pFirst;
    155 //
    156 //     LDR     R2, [R0]
    157 //     CMP     R2, #0
    158 //     IT NE                 ; pHead->pFirst != 0
    159 //     STRNE   R1, [R2,#4]   ; pHead->pFirst->pPrev = pNew;
    160 //
    161 //     STR     R1, [R0]      ; pHead->pFirst = pNew;
    162 //     BX      LR
    163 //
    164 //  pFirst --> pNew
    165 //  0 <------- pNew ----> 0
    166 //
    167 //  0 <------- pNew ----> pOld
    168 //  pNew <---- pOld ----> 0
    169 //
    170 //  0 <-------\____
    171 //  pFirst --> pNew <----> pOld <----> pOld <----> pOld ----> 0
    172 void USBH_DLIST_Add(USBH_DLIST_HEAD * pHead, USBH_DLIST_ITEM * pNew)
    173 {
    174   pNew->pPrev = 0;
    175   pNew->pNext = 0; // (pHead->pFirst == 0)
    176   if (pHead->pFirst != 0)
    177   {
    178     pNew->pNext = pHead->pFirst;
    179     pHead->pFirst->pPrev = pNew;
    180   }
    181   pHead->pFirst = pNew;
    182   //pHead->NumItems++;
    183 }
    184 
    185 // USBH_DLIST_Remove
    186 //     LDR     R3, [R0]
    187 //     LDR     R2, [R1]
    188 //
    189 //     CMP     R3, R1
    190 //     IT NE
    191 //     LDRNE   R0, [R1,#4]
    192 //     STR     R2, [R0]
    193 //
    194 //     LDR     R0, [R1]
    195 //     CMP     R0, #0
    196 //     ITT NE
    197 //     LDRNE   R1, [R1,#4]
    198 //     STRNE   R1, [R0,#4]
    199 //
    200 //     BX      LR
    201 //
    202 //  pFirst ----> pItem ----> pRemoveItem ----> pItem ----> 0
    203 //  pFirst ----> pItem ----------------------> pItem ----> 0
    204 //
    205 //  pFirst ----> pRemoveItem ----> pItem ----> pItem ----> 0
    206 //  pFirst ----------------------> pItem ----> pItem ----> 0
    207 //
    208 void USBH_DLIST_Remove(USBH_DLIST_HEAD * pHead, USBH_DLIST_ITEM * pItem)
    209 {
    210 #if(0)
    211   if (pHead->pFirst == pItem)
    212     pHead->pFirst->pNext = pItem->pNext; // 0
    213   else
    214     pItem->pPrev->pNext = pItem->pNext;
    215 #else
    216   USBH_DLIST_ITEM * pPrevItemOfpItem;
    217   if (pHead->pFirst == pItem)
    218     pPrevItemOfpItem = pHead->pFirst;
    219   else
    220     pPrevItemOfpItem = pItem->pPrev;
    221 
    222   pPrevItemOfpItem->pNext = pItem->pNext;
    223 #endif
    224 
    225   if (pItem->pNext != 0)
    226   {
    227     pHead->NumItems = (int) pItem->pPrev;
    228     //pHead->NumItems--;
    229   }
    230 }
    231 
    232 #endif
    233 
    234 //******************************************************************************
    235 // Added
    236 //******************************************************************************
    237 typedef unsigned int (*NODE_MATCH_FUNC)(USBH_DLIST * Entry, void * pContext);
    238 
    239 USBH_DLIST * USBH_X_DLIST_AddNode(USBH_DLIST * pHead,
    240     unsigned int NodeEntryOffset, unsigned int NodeSize)
    241 {
    242   USBH_DLIST * entry = 0;
    243   void * node = USBH_Malloc( NodeSize );
    244   if (node)
    245   {
    246     entry = (USBH_DLIST *) ( ( (unsigned int) node ) + NodeEntryOffset );
    247     USBH_DLIST_InsertEntry( pHead, entry );
    248   }
    249   return entry;
    250 }
    251 
    252 void USBH_X_DLIST_DeleteNode(USBH_DLIST * Entry, unsigned int EntryOffset)
    253 {
    254   USBH_DLIST_RemoveEntry( Entry );
    255   USBH_Free( (void *) ( (char *) Entry - EntryOffset ) );
    256 }
    257 
    258 void USBH_X_DLIST_DeleteAllNodes(USBH_DLIST * pHead, unsigned int EntryOffset)
    259 {
    260   USBH_DLIST * Entry = pHead->pNext;
    261   while ( Entry != pHead )
    262   {
    263     Entry = Entry->pNext;
    264     USBH_X_DLIST_DeleteNode(Entry->pPrev, EntryOffset);
    265   }
    266 }
    267 
    268 void USBH_X_DLIST_DeleteMatchedNode(USBH_DLIST * pHead,
    269     unsigned int EntryOffset, NODE_MATCH_FUNC NodeMacthFunc, void * pContext)
    270 {
    271   USBH_DLIST * Entry = pHead->pNext;
    272   while ( Entry != pHead )
    273   {
    274     Entry = Entry->pNext;
    275     if (NodeMacthFunc( Entry->pPrev, pContext ))
    276     {
    277       USBH_X_DLIST_DeleteNode(Entry->pPrev, EntryOffset);
    278     }
    279   }
    280 }
    281 
    282 //******************************************************************************
    283 // Demo
    284 //******************************************************************************
    285 // stddef.h
    286 // #define offsetof(T, member)     (__INTADDR__((&((T *)0)->member)))
    287 #define offset_of_member( struct_name, member_name ) \
    288   ( (unsigned int) (&  (  (struct_name *) 0 ) -> member_name ) )
    289 
    290 #define container_of(ptr, type, member) \
    291   ( (type *)( (char *)ptr - offset_of_member(type,member) ) )
    292 
    293 typedef struct HUB_PORT
    294 {
    295   unsigned int PortNumber;
    296   // other members
    297   struct USBH_DLIST ListEntry;
    298 } HUB_PORT;
    299 
    300 typedef struct USBH_ROOT_HUB
    301 {
    302   struct USBH_DLIST PortList;
    303   unsigned int PortCount;
    304 // other members
    305 } USBH_ROOT_HUB;
    306 
    307 typedef struct _PortNumberContext
    308 {
    309   unsigned int PortNumber;
    310 } PortNumberContext_t;
    311 
    312 USBH_ROOT_HUB root_hub;
    313 HUB_PORT * hub_port[4];
    314 
    315 HUB_PORT * HUB_PORT_Get(USBH_DLIST * Entry)
    316 {
    317   return container_of( Entry, HUB_PORT, ListEntry );
    318 }
    319 
    320 unsigned int MatchPortNumber(USBH_DLIST * Entry, void * pContext)
    321 {
    322   HUB_PORT * hub_port;
    323   PortNumberContext_t * pPortNumberContext;
    324   pPortNumberContext = (PortNumberContext_t *)pContext;
    325   hub_port = HUB_PORT_Get( Entry );
    326   unsigned int ContextPortNumber = pPortNumberContext->PortNumber;
    327   unsigned int EntryPortNumber = hub_port->PortNumber;
    328   return EntryPortNumber == ContextPortNumber;
    329 }
    330 
    331 void USBH_X_DLIST_Test(void)
    332 {
    333   PortNumberContext_t PortNumberContext;
    334 
    335   USBH_DLIST * ListHead = &root_hub.PortList;
    336   USBH_DLIST_Init( ListHead );
    337 
    338   USBH_DLIST * ListEntry;
    339   for (unsigned int PortNumber = 0; PortNumber < 4; PortNumber++)
    340   {
    341     ListEntry = USBH_X_DLIST_AddNode( ListHead, offsetof( HUB_PORT, ListEntry ),
    342         sizeof(HUB_PORT) );
    343     if ( ListEntry )
    344     {
    345       hub_port[PortNumber] = HUB_PORT_Get( ListEntry );
    346       hub_port[PortNumber]->PortNumber = PortNumber;
    347       root_hub.PortCount++;
    348     }
    349   }
    350 
    351   if ( root_hub.PortCount == 4 )
    352   {
    353     PortNumberContext.PortNumber = 2;
    354     USBH_X_DLIST_DeleteMatchedNode( ListHead, offsetof( HUB_PORT, ListEntry ),
    355       MatchPortNumber,  &PortNumberContext );
    356 
    357     USBH_X_DLIST_DeleteAllNodes( ListHead, offsetof( HUB_PORT, ListEntry ) );
    358   }
    359 }

  • 相关阅读:
    php-fpm: 某项目网站频繁出现503问题解决( WARNING: [pool www] server reached pm.max_children setting (50), consider raising it)
    spring mvc: rss(xml)输出
    spring mvc: json练习
    spring mvc: xml练习
    spring mvc:输出json,输出多个json
    phalcon: 目录分组后的acl权限控制
    spring mvc: xml生成
    spring mvc:视图解析器
    Python爬虫从入门到放弃(二十)之 Scrapy分布式原理
    Python爬虫从入门到放弃(十九)之 Scrapy爬取所有知乎用户信息(下)
  • 原文地址:https://www.cnblogs.com/shangdawei/p/2679561.html
Copyright © 2020-2023  润新知