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 }

 

posted @ 2012-09-11 00:10  IAmAProgrammer  阅读(451)  评论(0编辑  收藏  举报