DSMCC  17.9.0
 All Data Structures Files Functions Typedefs
linkList.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2004 Ocean Blue Software Ltd
4  * Copyright © 2001 Koninklijke Philips Electronics N.V
5  *
6  * This file is part of a DTVKit Software Component
7  * You are permitted to copy, modify or distribute this file subject to the terms
8  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
9  *
10  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
11  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
12  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
13  *
14  * If you or your organisation is not a member of DTVKit then you have access
15  * to this source code outside of the terms of the licence agreement
16  * and you are expected to delete this and any associated files immediately.
17  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
18  *******************************************************************************/
26 /*---includes for this file--------------------------------------------------*/
27 #include "clDsmSystem.h"
28 #include "linkList.h"
29 
30 #include "cacheMgr.h"
31 
32 
33 /*------------------------------- Local Macros -------------------------------*/
34 
35 
36 
37 /*------------------------------ Exported Data -----------------------------*/
38 
39 
40 
41 /*--------------------------------Local Types --------------------------------*/
42 
43 
44 
45 /*------------------------------- Local Statics ------------------------------*/
46 
47 
48 
49 /*------------------- local prototypes/forward declarations ------------------*/
50 /* eg static void myLocalFunction(); */
51 
52 
53 /*---------------------------- Exported Functions ----------------------------*/
54 
55 /**** LINK LIST CONTROL BLOCK FUNCTIONS ****/
56 
57 /* /////////////////////////////////////////////////////////////////////////////
58 // LLCtrlBlockInit
59 // Initialises a new, empty Control Block.
61 void LLCtrlBlockInit( P_LLControl pCtrl, ListId_t listId, H_Object hParent )
62 {
63  dsmAssert((pCtrl != NULL));
64 
65  pCtrl->pHead = pCtrl->pTail = NULL;
66  pCtrl->count = 0;
67  pCtrl->listId = listId;
68  pCtrl->hParent = hParent;
69 }
70 
71 /* /////////////////////////////////////////////////////////////////////////////
72 // LLCreate
73 // Creates a linked list Control block, and returns a handle to it.
75 E_DscError LLCreate( P_DsmCoreInst idp,
76  H_Object hParent, ListId_t listId, P_LLControl *phLlCtrl )
77 {
78  E_DscError err;
79 
80  dsmAssert((idp != NULL));
81  dsmAssert((phLlCtrl != NULL));
82 
83  *phLlCtrl = (P_LLControl)DSC_CmMemGet( idp, sizeof(S_LLControl) );
84  if (*phLlCtrl == NULL)
85  {
86  err = CLDSM_ERR_MEM_HEAP_FULL;
87  }
88  else
89  {
90  err = CLDSM_OK;
91  LLCtrlBlockInit( *phLlCtrl, listId, hParent );
92  }
93 
94  DEBUG_CHK( err == CLDSM_OK, dsmDP1(("ERROR: LLCreate %u\n", err)));
95  return err;
96 }
97 
98 /* /////////////////////////////////////////////////////////////////////////////
99 // LLDestroy
100 // Destroys a linked list Control block, and sets the handle to NULL.
102 void LLDestroy( P_DsmCoreInst idp, P_LLControl *phLlCtrl )
103 {
104  dsmAssert((idp != NULL));
105  dsmAssert((phLlCtrl != NULL));
106  dsmAssert((*phLlCtrl != NULL));
107 
108  if (!memValidate( *phLlCtrl ))
109  {
110  dsmDP1(("ERROR: LLDestroy mem invalid %p\n", *phLlCtrl));
111  }
112  else
113  {
114  #ifndef NDEBUG
115  dsmAssert(((*phLlCtrl)->count == 0));
116  #endif
117  DSC_CmMemRelease( idp, *phLlCtrl );
118  *phLlCtrl = NULL;
119  }
120 }
121 
122 /* /////////////////////////////////////////////////////////////////////////////
123 // RemoveItem
124 // Removes an object from list given by control block.
125 // returns TRUE if this was the last object in the list
127 void RemoveItem( P_LLControl pLLCtrl, P_LLObject pLL )
128 {
129  dsmAssert((pLL != NULL));
130  dsmAssert((pLLCtrl != NULL));
131  dsmAssert((pLL->pLLCtrl == pLLCtrl));
132  if (pLL->pNext)
133  {
134  P_LLObject pLLNext = pLL->pNext + pLLCtrl->listId;
135  pLLNext->pPrev = pLL->pPrev;
136  }
137  else
138  {
139  dsmAssert((pLLCtrl->pTail == (pLL - pLLCtrl->listId)));
140  pLLCtrl->pTail = pLL->pPrev;
141  }
142  if (pLL->pPrev)
143  {
144  P_LLObject pLLPrev = pLL->pPrev + pLLCtrl->listId;
145  pLLPrev->pNext = pLL->pNext;
146  }
147  else
148  {
149  dsmAssert((pLLCtrl->pHead == (pLL - pLLCtrl->listId)));
150  pLLCtrl->pHead = pLL->pNext;
151  }
152  pLLCtrl->count--;
153  pLL->pLLCtrl = NULL;
154  pLL->pPrev = pLL->pNext = NULL;
155 }
156 
157 /* /////////////////////////////////////////////////////////////////////////////
158 // llRemoveFromAll
159 // Removes an object from all lists it is currently in.
160 // The object becomes a floating object.
162 void LLRemoveFromAll( H_Object hListObj, U16BIT numLists )
163 {
164  P_LLObject pLL = (P_LLObject)hListObj;
165  dsmAssert((pLL != NULL));
166  for (; numLists--; pLL++)
167  {
168  if (pLL->pLLCtrl != NULL)
169  {
170  RemoveItem( pLL->pLLCtrl, pLL );
171  }
172  }
173 }
174 
175 /* /////////////////////////////////////////////////////////////////////////////
176 // LLHead
177 // Returns a handle to the head object. The object is not removed.
179 H_Object LLHead( P_LLControl pCtrlObj )
180 {
181  return (pCtrlObj->count) ? pCtrlObj->pHead : NULL;
182 }
183 
184 /* /////////////////////////////////////////////////////////////////////////////
185 // LLTail
186 // Returns a handle to the head object. The object is not removed.
188 H_Object LLTail( P_LLControl pCtrlObj )
189 {
190  return (pCtrlObj && pCtrlObj->count) ? pCtrlObj->pTail : NULL;
191 }
192 
193 /* /////////////////////////////////////////////////////////////////////////////
194 // LLInsertHead
195 // Inserts an object into the head of the list.
196 // If the object exists already in the list, then it is moved to the head.
197 // returns TRUE if the object was not previously in the list.
199 BOOLEAN LLInsertHead( P_LLControl pCtrlObj, H_Object hNewObj )
200 {
201  P_LLObject pNewObj;
202  P_LLObject pHead;
203  ListId_t listId;
204  BOOLEAN added;
205 
206  dsmAssert((pCtrlObj != NULL));
207  dsmAssert((hNewObj != NULL));
208 
209  listId = pCtrlObj->listId;
210  pNewObj = (P_LLObject)hNewObj;
211  pNewObj += listId;
212 
213  /* If in list already, then remove it ready for re-insertion at the head */
214  if (pNewObj->pLLCtrl != NULL)
215  {
216  added = FALSE;
217  if (pNewObj->pLLCtrl != pCtrlObj)
218  {
219  /* Module is in a different list. This can happen when we have two
220  * DIIs with the same ModuleId. It shouldn't happen under normal
221  * circumstances, but it *can* happen. In this case we just give
222  * up (we don't know which DII it belongs to).
223  */
224  return FALSE;
225  }
226  /* Already in list */
227  RemoveItem( pCtrlObj, pNewObj );
228  }
229  else
230  {
231  added = TRUE;
232  }
233 
234  pNewObj->pNext = pCtrlObj->pHead;
235  pNewObj->pLLCtrl = pCtrlObj;
236  if (pCtrlObj->count++)
237  {
238  pHead = pCtrlObj->pHead + listId;
239  pHead->pPrev = (P_LLObject)hNewObj;
240  }
241  else
242  {
243  pCtrlObj->pTail = (P_LLObject)hNewObj;
244  }
245  pCtrlObj->pHead = (P_LLObject)hNewObj;
246 
247  return added;
248 }
249 
250 /* /////////////////////////////////////////////////////////////////////////////
251 // LLInsertTail
252 // Appends an object onto the tail of the list
253 // If the object exists already in the list, then it is moved to the tail.
254 // returns TRUE if the object was not previously in the list.
256 BOOLEAN LLInsertTail( P_LLControl pCtrlObj, H_Object hNewObj )
257 {
258  P_LLObject pNewObj;
259  P_LLObject pTail = NULL;
260  ListId_t listId;
261  BOOLEAN added;
262 
263  dsmAssert((pCtrlObj != NULL));
264  dsmAssert((hNewObj != NULL));
265 
266  listId = pCtrlObj->listId;
267  pNewObj = (P_LLObject)hNewObj;
268  pNewObj += listId;
269 
270  /* Assert if object is in another list with same listId */
271  dsmAssert(((pNewObj->pLLCtrl == NULL) || (pNewObj->pLLCtrl == pCtrlObj)));
272 
273  /* If in list already, then remove it ready for re-insertion at the head */
274  if (pNewObj->pLLCtrl != NULL)
275  {
276  /* Already in list */
277  RemoveItem( pCtrlObj, pNewObj );
278  added = FALSE;
279  }
280  else
281  {
282  added = TRUE;
283  }
284  pNewObj->pPrev = pCtrlObj->pTail;
285  pNewObj->pLLCtrl = pCtrlObj;
286  if (pCtrlObj->count++)
287  {
288  pTail = pCtrlObj->pTail + listId;
289  pTail->pNext = (P_LLObject)hNewObj;
290  }
291  else
292  {
293  pCtrlObj->pHead = (P_LLObject)hNewObj;
294  }
295  pCtrlObj->pTail = (P_LLObject)hNewObj;
296 
297  return added;
298 }
299 
300 /* /////////////////////////////////////////////////////////////////////////////
301 // LLRemoveHead
302 // Disconnects the first object in the list and returns a handle to it.
303 // Handle is NULL if the list contained no objects.
305 H_Object LLRemoveHead( P_LLControl pCtrlObj )
306 {
307  P_LLObject obj;
308  dsmAssert((pCtrlObj != NULL));
309  if (pCtrlObj->count)
310  {
311  obj = pCtrlObj->pHead;
312  RemoveItem( pCtrlObj, obj + pCtrlObj->listId );
313  }
314  else
315  {
316  obj = NULL;
317  }
318  return (H_Object)obj;
319 }
320 
321 /* /////////////////////////////////////////////////////////////////////////////
322 // LLRemoveTail
323 // Disconnects the last object in the list and returns a handle to it.
324 // Handle is NULL if the list contained no objects.
326 H_Object LLRemoveTail( P_LLControl pCtrlObj )
327 {
328  P_LLObject obj;
329  dsmAssert((pCtrlObj != NULL));
330  if (pCtrlObj->count)
331  {
332  obj = pCtrlObj->pTail;
333  RemoveItem( pCtrlObj, obj + pCtrlObj->listId );
334  }
335  else
336  {
337  obj = NULL;
338  }
339  return (H_Object)obj;
340 }
341 
342 /* /////////////////////////////////////////////////////////////////////////////
343 // LLCount
344 // returns number of objects in the specified list.
346 U16BIT LLCount( P_LLControl pCtrlObj )
347 {
348  return pCtrlObj->count;
349 }
350 
351 /* /////////////////////////////////////////////////////////////////////////////
352 // LLListId
353 // returns number of objects in the specified list.
355 U16BIT LListId( P_LLControl pCtrlObj )
356 {
357  return pCtrlObj->listId;
358 }
359 
360 /**** LINK LIST FUNCTIONS ****/
361 /* /////////////////////////////////////////////////////////////////////////////
362 // llLinkInit
363 // Initialises a new, empty list object's list parameters
365 void llLinkInit( P_LLObject pLL, U32BIT numLists )
366 {
367  S32BIT loop;
368 
369  dsmAssert((pLL != NULL));
370  dsmAssert((numLists != 0));
371 
372  /* Init pointers */
373  for (loop = 0; loop != numLists; loop++)
374  {
375  pLL->pLLCtrl = NULL;
376  pLL->pNext = pLL->pPrev = NULL;
377  pLL++;
378  }
379 }
380 
381 /* /////////////////////////////////////////////////////////////////////////////
382 // LLRemove
383 // Removes an object from the specified list.
384 // returns TRUE if this was the last object in the list
386 BOOLEAN LLRemove( H_Object hListObj, ListId_t listId )
387 {
388  P_LLObject pLL = (P_LLObject)hListObj;
389  P_LLControl pCtrlObj;
390  BOOLEAN islast = FALSE;
391 
392  dsmAssert((hListObj != NULL));
393 
394  pLL += listId;
395  pCtrlObj = pLL->pLLCtrl;
396 
397  if (pCtrlObj != NULL)
398  {
399  RemoveItem( pCtrlObj, pLL );
400  if (pCtrlObj->count == 0)
401  {
402  islast = TRUE;
403  }
404  }
405  return islast;
406 }
407 
408 /* /////////////////////////////////////////////////////////////////////////////
409 // LLNext
410 // Returns the handle to the next object in the list
412 H_Object LLNext( H_Object obj, ListId_t listId )
413 {
414  P_LLObject pLLs = (P_LLObject)obj;
415  return pLLs[listId].pNext;
416 }
417 
418 /* /////////////////////////////////////////////////////////////////////////////
419 // LLPrev
420 // Returns the handle to the previous object in the list
422 H_Object LLPrev( H_Object obj, ListId_t listId )
423 {
424  P_LLObject pLLs = obj;
425  return pLLs[listId].pPrev;
426 }
427 
428 /* /////////////////////////////////////////////////////////////////////////////
429 // LLCheckInListCtrl
430 //
432 BOOLEAN LLCheckInListCtrl( P_LLControl pCtrlBlk, H_Object obj )
433 {
434  P_LLObject pLL = obj;
435 
436  dsmAssert((pCtrlBlk != NULL));
437  dsmAssert((obj != NULL));
438 
439  pLL += pCtrlBlk->listId;
440  return (pLL->pLLCtrl == pCtrlBlk) ? TRUE : FALSE;
441 }
442 
443 /* /////////////////////////////////////////////////////////////////////////////
444 // LLCheckInListId
445 //
447 BOOLEAN LLCheckInListId( ListId_t listId, H_Object obj )
448 {
449  P_LLObject pLL = obj;
450 
451  dsmAssert((obj != NULL));
452 
453  pLL += listId;
454  return pLL->pLLCtrl ? TRUE : FALSE;
455 }
456 
457 /* /////////////////////////////////////////////////////////////////////////////
458 // llGetParent
459 //
461 H_Object LLParent( H_Object obj, ListId_t listId )
462 {
463  P_LLObject pLL = obj;
464  P_LLControl pLLCtrl;
465  dsmAssert((obj != NULL));
466  pLL += listId;
467  pLLCtrl = pLL->pLLCtrl;
468  return (pLLCtrl == NULL) ? NULL : pLLCtrl->hParent;
469 }
470 
471 /* /////////////////////////////////////////////////////////////////////////////
472 // LLReplaceAll
473 //
475 void LLReplaceAll( H_Object oldobj, H_Object newobj, U16BIT numLists )
476 {
477  P_LLObject pLLOld = oldobj;
478  P_LLObject pLLNew = newobj;
479  P_LLControl pLLCtrl;
480  P_LLObject pNext;
481  P_LLObject pPrev;
482  ListId_t listId;
483 
484  dsmAssert((pLLOld != NULL));
485  dsmAssert((pLLNew != NULL));
486 
487  for (listId = 0; listId != numLists; listId++)
488  {
489  pLLCtrl = pLLOld[listId].pLLCtrl;
490  if (pLLCtrl != NULL)
491  {
492  pLLNew[listId].pLLCtrl = pLLCtrl;
493  pLLOld[listId].pLLCtrl = NULL;
494  pNext = pLLOld[listId].pNext;
495  pPrev = pLLOld[listId].pPrev;
496  pLLNew[listId].pNext = pNext;
497  pLLNew[listId].pPrev = pPrev;
498  pLLOld[listId].pNext = NULL;
499  pLLOld[listId].pPrev = NULL;
500  if (pNext)
501  {
502  pNext += listId;
503  pNext->pPrev = pLLNew;
504  }
505  if (pPrev)
506  {
507  pPrev += listId;
508  pPrev->pNext = pLLNew;
509  }
510  if (pLLCtrl->pHead == pLLOld)
511  pLLCtrl->pHead = pLLNew;
512  if (pLLCtrl->pTail == pLLOld)
513  pLLCtrl->pTail = pLLNew;
514  }
515  }
516 }
517 
518 BOOLEAN LLIsObjectInList( P_LLControl pCtrlBlk, H_Object obj )
519 {
520  H_Object object;
521  ListId_t listId;
522  BOOLEAN bFound = FALSE;
523  dsmAssert((pCtrlBlk != NULL));
524  listId = pCtrlBlk->listId;
525  object = pCtrlBlk->pHead;
526  while (object)
527  {
528  /* Is this the OC we want? */
529  if (obj == object)
530  {
531  /* Found the OC */
532  bFound = TRUE;
533  break;
534  }
535  object = LLNext( object, listId );
536  }
537  return(bFound);
538 }
539 
540 /*------------------------------ Local Functions -----------------------------*/
541 
542 
543 /*----------------------------------------------------------------------------*/
General include file for clDsm library internal definitions.
Header to the cacheMgr module.