Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
src/vm/seglist.c@0:14e5e829dffe, 2010-07-21 (annotated)
- Committer:
- dadaista
- Date:
- Wed Jul 21 12:50:41 2010 +0000
- Revision:
- 0:14e5e829dffe
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dadaista | 0:14e5e829dffe | 1 | /* |
dadaista | 0:14e5e829dffe | 2 | # This file is Copyright 2003, 2006, 2007, 2009 Dean Hall. |
dadaista | 0:14e5e829dffe | 3 | # |
dadaista | 0:14e5e829dffe | 4 | # This file is part of the PyMite VM. |
dadaista | 0:14e5e829dffe | 5 | # The PyMite VM is free software: you can redistribute it and/or modify |
dadaista | 0:14e5e829dffe | 6 | # it under the terms of the GNU GENERAL PUBLIC LICENSE Version 2. |
dadaista | 0:14e5e829dffe | 7 | # |
dadaista | 0:14e5e829dffe | 8 | # The PyMite VM is distributed in the hope that it will be useful, |
dadaista | 0:14e5e829dffe | 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
dadaista | 0:14e5e829dffe | 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
dadaista | 0:14e5e829dffe | 11 | # A copy of the GNU GENERAL PUBLIC LICENSE Version 2 |
dadaista | 0:14e5e829dffe | 12 | # is seen in the file COPYING in this directory. |
dadaista | 0:14e5e829dffe | 13 | */ |
dadaista | 0:14e5e829dffe | 14 | |
dadaista | 0:14e5e829dffe | 15 | |
dadaista | 0:14e5e829dffe | 16 | #undef __FILE_ID__ |
dadaista | 0:14e5e829dffe | 17 | #define __FILE_ID__ 0x10 |
dadaista | 0:14e5e829dffe | 18 | |
dadaista | 0:14e5e829dffe | 19 | |
dadaista | 0:14e5e829dffe | 20 | /** |
dadaista | 0:14e5e829dffe | 21 | * \file |
dadaista | 0:14e5e829dffe | 22 | * \brief Segmented list data type and operations |
dadaista | 0:14e5e829dffe | 23 | * |
dadaista | 0:14e5e829dffe | 24 | * The segmented list is used to implement the Python |
dadaista | 0:14e5e829dffe | 25 | * List and Dict data types. |
dadaista | 0:14e5e829dffe | 26 | * The segmented list is used in preference to the linked list |
dadaista | 0:14e5e829dffe | 27 | * in order to reduce the memory overhead. |
dadaista | 0:14e5e829dffe | 28 | * |
dadaista | 0:14e5e829dffe | 29 | * Unused slots in the segments are expected to contain C_NULL. |
dadaista | 0:14e5e829dffe | 30 | * |
dadaista | 0:14e5e829dffe | 31 | * List implementation: |
dadaista | 0:14e5e829dffe | 32 | * When used in a List, the Seglist.currseg field points |
dadaista | 0:14e5e829dffe | 33 | * to the last segment in the list. |
dadaista | 0:14e5e829dffe | 34 | * The function seglist_appendItem() should be used to append |
dadaista | 0:14e5e829dffe | 35 | * items to the List. |
dadaista | 0:14e5e829dffe | 36 | * Inserting and deleting List items is a more complicated |
dadaista | 0:14e5e829dffe | 37 | * matter. |
dadaista | 0:14e5e829dffe | 38 | * |
dadaista | 0:14e5e829dffe | 39 | * Dict implementation: |
dadaista | 0:14e5e829dffe | 40 | * The currseg field is meaningless since rootseg always |
dadaista | 0:14e5e829dffe | 41 | * points to the current active segment. |
dadaista | 0:14e5e829dffe | 42 | * The function seglist_pushItem() should be used to put |
dadaista | 0:14e5e829dffe | 43 | * items in the Dict. |
dadaista | 0:14e5e829dffe | 44 | * A Dict uses one Seglist for keys and another for values. |
dadaista | 0:14e5e829dffe | 45 | * A Dict entry's (key, value) pair share the same index in |
dadaista | 0:14e5e829dffe | 46 | * the Seglist. |
dadaista | 0:14e5e829dffe | 47 | */ |
dadaista | 0:14e5e829dffe | 48 | |
dadaista | 0:14e5e829dffe | 49 | |
dadaista | 0:14e5e829dffe | 50 | #include "pm.h" |
dadaista | 0:14e5e829dffe | 51 | |
dadaista | 0:14e5e829dffe | 52 | |
dadaista | 0:14e5e829dffe | 53 | /** |
dadaista | 0:14e5e829dffe | 54 | * Set this to 1 if seglist_clear() should manually free its segments. |
dadaista | 0:14e5e829dffe | 55 | * Set this to 0 if seglist_clear() should do nothing |
dadaista | 0:14e5e829dffe | 56 | * and let the GC reclaim objects. |
dadaista | 0:14e5e829dffe | 57 | */ |
dadaista | 0:14e5e829dffe | 58 | #define SEGLIST_CLEAR_SEGMENTS 1 |
dadaista | 0:14e5e829dffe | 59 | |
dadaista | 0:14e5e829dffe | 60 | |
dadaista | 0:14e5e829dffe | 61 | PmReturn_t |
dadaista | 0:14e5e829dffe | 62 | seglist_appendItem(pSeglist_t pseglist, pPmObj_t pobj) |
dadaista | 0:14e5e829dffe | 63 | { |
dadaista | 0:14e5e829dffe | 64 | return seglist_insertItem(pseglist, pobj, pseglist->sl_length); |
dadaista | 0:14e5e829dffe | 65 | } |
dadaista | 0:14e5e829dffe | 66 | |
dadaista | 0:14e5e829dffe | 67 | |
dadaista | 0:14e5e829dffe | 68 | PmReturn_t |
dadaista | 0:14e5e829dffe | 69 | seglist_clear(pSeglist_t pseglist) |
dadaista | 0:14e5e829dffe | 70 | { |
dadaista | 0:14e5e829dffe | 71 | pSegment_t pseg1 = C_NULL; |
dadaista | 0:14e5e829dffe | 72 | pSegment_t pseg2 = C_NULL; |
dadaista | 0:14e5e829dffe | 73 | |
dadaista | 0:14e5e829dffe | 74 | #if SEGLIST_CLEAR_SEGMENTS |
dadaista | 0:14e5e829dffe | 75 | /* Deallocate all linked segments */ |
dadaista | 0:14e5e829dffe | 76 | pseg1 = ((pSeglist_t)pseglist)->sl_rootseg; |
dadaista | 0:14e5e829dffe | 77 | while (pseg1 != C_NULL) |
dadaista | 0:14e5e829dffe | 78 | { |
dadaista | 0:14e5e829dffe | 79 | pseg2 = pseg1->next; |
dadaista | 0:14e5e829dffe | 80 | PM_RETURN_IF_ERROR(heap_freeChunk((pPmObj_t)pseg1)); |
dadaista | 0:14e5e829dffe | 81 | pseg1 = pseg2; |
dadaista | 0:14e5e829dffe | 82 | } |
dadaista | 0:14e5e829dffe | 83 | #endif |
dadaista | 0:14e5e829dffe | 84 | |
dadaista | 0:14e5e829dffe | 85 | /* Clear seglist fields */ |
dadaista | 0:14e5e829dffe | 86 | ((pSeglist_t)pseglist)->sl_rootseg = C_NULL; |
dadaista | 0:14e5e829dffe | 87 | ((pSeglist_t)pseglist)->sl_lastseg = C_NULL; |
dadaista | 0:14e5e829dffe | 88 | ((pSeglist_t)pseglist)->sl_length = 0; |
dadaista | 0:14e5e829dffe | 89 | |
dadaista | 0:14e5e829dffe | 90 | return PM_RET_OK; |
dadaista | 0:14e5e829dffe | 91 | } |
dadaista | 0:14e5e829dffe | 92 | |
dadaista | 0:14e5e829dffe | 93 | |
dadaista | 0:14e5e829dffe | 94 | PmReturn_t |
dadaista | 0:14e5e829dffe | 95 | seglist_findEqual(pSeglist_t pseglist, pPmObj_t pobj, int16_t *r_index) |
dadaista | 0:14e5e829dffe | 96 | { |
dadaista | 0:14e5e829dffe | 97 | pSegment_t pseg; |
dadaista | 0:14e5e829dffe | 98 | int8_t i = 0; |
dadaista | 0:14e5e829dffe | 99 | uint8_t segindex; |
dadaista | 0:14e5e829dffe | 100 | |
dadaista | 0:14e5e829dffe | 101 | C_ASSERT(pseglist != C_NULL); |
dadaista | 0:14e5e829dffe | 102 | C_ASSERT(pobj != C_NULL); |
dadaista | 0:14e5e829dffe | 103 | C_ASSERT((*r_index >= 0)); |
dadaista | 0:14e5e829dffe | 104 | C_ASSERT((*r_index == 0) || (*r_index < pseglist->sl_length)); |
dadaista | 0:14e5e829dffe | 105 | |
dadaista | 0:14e5e829dffe | 106 | /* Walk out to the starting segment */ |
dadaista | 0:14e5e829dffe | 107 | pseg = pseglist->sl_rootseg; |
dadaista | 0:14e5e829dffe | 108 | for (i = (*r_index / SEGLIST_OBJS_PER_SEG); i > (int8_t)0; i--) |
dadaista | 0:14e5e829dffe | 109 | { |
dadaista | 0:14e5e829dffe | 110 | C_ASSERT(pseg != C_NULL); |
dadaista | 0:14e5e829dffe | 111 | pseg = pseg->next; |
dadaista | 0:14e5e829dffe | 112 | } |
dadaista | 0:14e5e829dffe | 113 | |
dadaista | 0:14e5e829dffe | 114 | /* Set the starting index within the segment */ |
dadaista | 0:14e5e829dffe | 115 | segindex = *r_index % SEGLIST_OBJS_PER_SEG; |
dadaista | 0:14e5e829dffe | 116 | |
dadaista | 0:14e5e829dffe | 117 | /* Search the remaining segments */ |
dadaista | 0:14e5e829dffe | 118 | for (; pseg != C_NULL; pseg = pseg->next) |
dadaista | 0:14e5e829dffe | 119 | { |
dadaista | 0:14e5e829dffe | 120 | while (segindex < SEGLIST_OBJS_PER_SEG) |
dadaista | 0:14e5e829dffe | 121 | { |
dadaista | 0:14e5e829dffe | 122 | /* If past the end of the seglist, return no item found */ |
dadaista | 0:14e5e829dffe | 123 | if (*r_index >= pseglist->sl_length) |
dadaista | 0:14e5e829dffe | 124 | { |
dadaista | 0:14e5e829dffe | 125 | return PM_RET_NO; |
dadaista | 0:14e5e829dffe | 126 | } |
dadaista | 0:14e5e829dffe | 127 | |
dadaista | 0:14e5e829dffe | 128 | /* If items are equal, return with index of found item */ |
dadaista | 0:14e5e829dffe | 129 | if (obj_compare(pobj, pseg->s_val[segindex]) == C_SAME) |
dadaista | 0:14e5e829dffe | 130 | { |
dadaista | 0:14e5e829dffe | 131 | return PM_RET_OK; |
dadaista | 0:14e5e829dffe | 132 | } |
dadaista | 0:14e5e829dffe | 133 | |
dadaista | 0:14e5e829dffe | 134 | /* Proceed to next item */ |
dadaista | 0:14e5e829dffe | 135 | segindex++; |
dadaista | 0:14e5e829dffe | 136 | (*r_index)++; |
dadaista | 0:14e5e829dffe | 137 | } |
dadaista | 0:14e5e829dffe | 138 | |
dadaista | 0:14e5e829dffe | 139 | /* Proceed to next segment */ |
dadaista | 0:14e5e829dffe | 140 | segindex = 0; |
dadaista | 0:14e5e829dffe | 141 | } |
dadaista | 0:14e5e829dffe | 142 | return PM_RET_NO; |
dadaista | 0:14e5e829dffe | 143 | } |
dadaista | 0:14e5e829dffe | 144 | |
dadaista | 0:14e5e829dffe | 145 | |
dadaista | 0:14e5e829dffe | 146 | PmReturn_t |
dadaista | 0:14e5e829dffe | 147 | seglist_getItem(pSeglist_t pseglist, int16_t index, pPmObj_t *r_pobj) |
dadaista | 0:14e5e829dffe | 148 | { |
dadaista | 0:14e5e829dffe | 149 | pSegment_t pseg; |
dadaista | 0:14e5e829dffe | 150 | int16_t i; |
dadaista | 0:14e5e829dffe | 151 | |
dadaista | 0:14e5e829dffe | 152 | C_ASSERT(pseglist != C_NULL); |
dadaista | 0:14e5e829dffe | 153 | C_ASSERT(index >= 0); |
dadaista | 0:14e5e829dffe | 154 | C_ASSERT(index < pseglist->sl_length); |
dadaista | 0:14e5e829dffe | 155 | |
dadaista | 0:14e5e829dffe | 156 | /* Walk out to the proper segment */ |
dadaista | 0:14e5e829dffe | 157 | pseg = pseglist->sl_rootseg; |
dadaista | 0:14e5e829dffe | 158 | C_ASSERT(pseg != C_NULL); |
dadaista | 0:14e5e829dffe | 159 | for (i = (index / SEGLIST_OBJS_PER_SEG); i > 0; i--) |
dadaista | 0:14e5e829dffe | 160 | { |
dadaista | 0:14e5e829dffe | 161 | pseg = pseg->next; |
dadaista | 0:14e5e829dffe | 162 | C_ASSERT(pseg != C_NULL); |
dadaista | 0:14e5e829dffe | 163 | } |
dadaista | 0:14e5e829dffe | 164 | |
dadaista | 0:14e5e829dffe | 165 | /* Return ptr to obj in this seg at the index */ |
dadaista | 0:14e5e829dffe | 166 | *r_pobj = pseg->s_val[index % SEGLIST_OBJS_PER_SEG]; |
dadaista | 0:14e5e829dffe | 167 | return PM_RET_OK; |
dadaista | 0:14e5e829dffe | 168 | } |
dadaista | 0:14e5e829dffe | 169 | |
dadaista | 0:14e5e829dffe | 170 | |
dadaista | 0:14e5e829dffe | 171 | PmReturn_t |
dadaista | 0:14e5e829dffe | 172 | seglist_insertItem(pSeglist_t pseglist, pPmObj_t pobj, int16_t index) |
dadaista | 0:14e5e829dffe | 173 | { |
dadaista | 0:14e5e829dffe | 174 | PmReturn_t retval = PM_RET_OK; |
dadaista | 0:14e5e829dffe | 175 | pSegment_t pseg = C_NULL; |
dadaista | 0:14e5e829dffe | 176 | pPmObj_t pobj1 = C_NULL; |
dadaista | 0:14e5e829dffe | 177 | pPmObj_t pobj2 = C_NULL; |
dadaista | 0:14e5e829dffe | 178 | int8_t indx = (int8_t)0; |
dadaista | 0:14e5e829dffe | 179 | int16_t i = 0; |
dadaista | 0:14e5e829dffe | 180 | uint8_t *pchunk; |
dadaista | 0:14e5e829dffe | 181 | |
dadaista | 0:14e5e829dffe | 182 | C_ASSERT(index <= pseglist->sl_length); |
dadaista | 0:14e5e829dffe | 183 | |
dadaista | 0:14e5e829dffe | 184 | /* If a new seg is needed */ |
dadaista | 0:14e5e829dffe | 185 | if ((pseglist->sl_length % SEGLIST_OBJS_PER_SEG) == 0) |
dadaista | 0:14e5e829dffe | 186 | { |
dadaista | 0:14e5e829dffe | 187 | /* Alloc and init new segment */ |
dadaista | 0:14e5e829dffe | 188 | retval = heap_getChunk(sizeof(Segment_t), &pchunk); |
dadaista | 0:14e5e829dffe | 189 | PM_RETURN_IF_ERROR(retval); |
dadaista | 0:14e5e829dffe | 190 | pseg = (pSegment_t)pchunk; |
dadaista | 0:14e5e829dffe | 191 | OBJ_SET_TYPE(pseg, OBJ_TYPE_SEG); |
dadaista | 0:14e5e829dffe | 192 | sli_memset((unsigned char *)pseg->s_val, |
dadaista | 0:14e5e829dffe | 193 | 0, SEGLIST_OBJS_PER_SEG * sizeof(pPmObj_t)); |
dadaista | 0:14e5e829dffe | 194 | pseg->next = C_NULL; |
dadaista | 0:14e5e829dffe | 195 | |
dadaista | 0:14e5e829dffe | 196 | /* If this is the first seg, set as root */ |
dadaista | 0:14e5e829dffe | 197 | if (pseglist->sl_rootseg == C_NULL) |
dadaista | 0:14e5e829dffe | 198 | { |
dadaista | 0:14e5e829dffe | 199 | pseglist->sl_rootseg = pseg; |
dadaista | 0:14e5e829dffe | 200 | } |
dadaista | 0:14e5e829dffe | 201 | |
dadaista | 0:14e5e829dffe | 202 | /* Else append the seg to the end */ |
dadaista | 0:14e5e829dffe | 203 | else |
dadaista | 0:14e5e829dffe | 204 | { |
dadaista | 0:14e5e829dffe | 205 | pseglist->sl_lastseg->next = pseg; |
dadaista | 0:14e5e829dffe | 206 | } |
dadaista | 0:14e5e829dffe | 207 | |
dadaista | 0:14e5e829dffe | 208 | /* Either way, this is now the last segment */ |
dadaista | 0:14e5e829dffe | 209 | pseglist->sl_lastseg = pseg; |
dadaista | 0:14e5e829dffe | 210 | } |
dadaista | 0:14e5e829dffe | 211 | |
dadaista | 0:14e5e829dffe | 212 | /* Walk out to the segment for insertion */ |
dadaista | 0:14e5e829dffe | 213 | pseg = pseglist->sl_rootseg; |
dadaista | 0:14e5e829dffe | 214 | C_ASSERT(pseg != C_NULL); |
dadaista | 0:14e5e829dffe | 215 | for (i = (index / SEGLIST_OBJS_PER_SEG); i > 0; i--) |
dadaista | 0:14e5e829dffe | 216 | { |
dadaista | 0:14e5e829dffe | 217 | pseg = pseg->next; |
dadaista | 0:14e5e829dffe | 218 | C_ASSERT(pseg != C_NULL); |
dadaista | 0:14e5e829dffe | 219 | } |
dadaista | 0:14e5e829dffe | 220 | |
dadaista | 0:14e5e829dffe | 221 | /* Insert obj and ripple copy all those afterward */ |
dadaista | 0:14e5e829dffe | 222 | indx = index % SEGLIST_OBJS_PER_SEG;; |
dadaista | 0:14e5e829dffe | 223 | pobj1 = pobj; |
dadaista | 0:14e5e829dffe | 224 | while (pobj1 != C_NULL) |
dadaista | 0:14e5e829dffe | 225 | { |
dadaista | 0:14e5e829dffe | 226 | pobj2 = pseg->s_val[indx]; |
dadaista | 0:14e5e829dffe | 227 | pseg->s_val[indx] = pobj1; |
dadaista | 0:14e5e829dffe | 228 | pobj1 = pobj2; |
dadaista | 0:14e5e829dffe | 229 | indx++; |
dadaista | 0:14e5e829dffe | 230 | |
dadaista | 0:14e5e829dffe | 231 | /* If indx exceeds this seg, go to next seg */ |
dadaista | 0:14e5e829dffe | 232 | if ((indx >= SEGLIST_OBJS_PER_SEG) && (pobj1 != C_NULL)) |
dadaista | 0:14e5e829dffe | 233 | { |
dadaista | 0:14e5e829dffe | 234 | pseg = pseg->next; |
dadaista | 0:14e5e829dffe | 235 | C_ASSERT(pseg != C_NULL); |
dadaista | 0:14e5e829dffe | 236 | indx = (int8_t)0; |
dadaista | 0:14e5e829dffe | 237 | } |
dadaista | 0:14e5e829dffe | 238 | } |
dadaista | 0:14e5e829dffe | 239 | pseglist->sl_length++; |
dadaista | 0:14e5e829dffe | 240 | return retval; |
dadaista | 0:14e5e829dffe | 241 | } |
dadaista | 0:14e5e829dffe | 242 | |
dadaista | 0:14e5e829dffe | 243 | |
dadaista | 0:14e5e829dffe | 244 | PmReturn_t |
dadaista | 0:14e5e829dffe | 245 | seglist_new(pSeglist_t *r_pseglist) |
dadaista | 0:14e5e829dffe | 246 | { |
dadaista | 0:14e5e829dffe | 247 | PmReturn_t retval = PM_RET_OK; |
dadaista | 0:14e5e829dffe | 248 | |
dadaista | 0:14e5e829dffe | 249 | retval = heap_getChunk(sizeof(Seglist_t), (uint8_t **)r_pseglist); |
dadaista | 0:14e5e829dffe | 250 | PM_RETURN_IF_ERROR(retval); |
dadaista | 0:14e5e829dffe | 251 | |
dadaista | 0:14e5e829dffe | 252 | OBJ_SET_TYPE(*r_pseglist, OBJ_TYPE_SGL); |
dadaista | 0:14e5e829dffe | 253 | (*r_pseglist)->sl_rootseg = C_NULL; |
dadaista | 0:14e5e829dffe | 254 | (*r_pseglist)->sl_lastseg = C_NULL; |
dadaista | 0:14e5e829dffe | 255 | (*r_pseglist)->sl_length = 0; |
dadaista | 0:14e5e829dffe | 256 | return retval; |
dadaista | 0:14e5e829dffe | 257 | } |
dadaista | 0:14e5e829dffe | 258 | |
dadaista | 0:14e5e829dffe | 259 | |
dadaista | 0:14e5e829dffe | 260 | PmReturn_t |
dadaista | 0:14e5e829dffe | 261 | seglist_setItem(pSeglist_t pseglist, pPmObj_t pobj, int16_t index) |
dadaista | 0:14e5e829dffe | 262 | { |
dadaista | 0:14e5e829dffe | 263 | pSegment_t pseg; |
dadaista | 0:14e5e829dffe | 264 | int16_t i; |
dadaista | 0:14e5e829dffe | 265 | |
dadaista | 0:14e5e829dffe | 266 | C_ASSERT(index <= pseglist->sl_length); |
dadaista | 0:14e5e829dffe | 267 | |
dadaista | 0:14e5e829dffe | 268 | /* Walk out to the proper segment */ |
dadaista | 0:14e5e829dffe | 269 | pseg = pseglist->sl_rootseg; |
dadaista | 0:14e5e829dffe | 270 | C_ASSERT(pseg != C_NULL); |
dadaista | 0:14e5e829dffe | 271 | for (i = (index / SEGLIST_OBJS_PER_SEG); i > 0; i--) |
dadaista | 0:14e5e829dffe | 272 | { |
dadaista | 0:14e5e829dffe | 273 | pseg = pseg->next; |
dadaista | 0:14e5e829dffe | 274 | C_ASSERT(pseg != C_NULL); |
dadaista | 0:14e5e829dffe | 275 | } |
dadaista | 0:14e5e829dffe | 276 | |
dadaista | 0:14e5e829dffe | 277 | /* Set item in this seg at the index */ |
dadaista | 0:14e5e829dffe | 278 | pseg->s_val[index % SEGLIST_OBJS_PER_SEG] = pobj; |
dadaista | 0:14e5e829dffe | 279 | return PM_RET_OK; |
dadaista | 0:14e5e829dffe | 280 | } |
dadaista | 0:14e5e829dffe | 281 | |
dadaista | 0:14e5e829dffe | 282 | |
dadaista | 0:14e5e829dffe | 283 | PmReturn_t |
dadaista | 0:14e5e829dffe | 284 | seglist_removeItem(pSeglist_t pseglist, uint16_t index) |
dadaista | 0:14e5e829dffe | 285 | { |
dadaista | 0:14e5e829dffe | 286 | pSegment_t pseg; |
dadaista | 0:14e5e829dffe | 287 | int16_t i, |
dadaista | 0:14e5e829dffe | 288 | k; |
dadaista | 0:14e5e829dffe | 289 | |
dadaista | 0:14e5e829dffe | 290 | C_ASSERT(index < pseglist->sl_length); |
dadaista | 0:14e5e829dffe | 291 | |
dadaista | 0:14e5e829dffe | 292 | /* Walk through the segments */ |
dadaista | 0:14e5e829dffe | 293 | pseg = pseglist->sl_rootseg; |
dadaista | 0:14e5e829dffe | 294 | C_ASSERT(pseg != C_NULL); |
dadaista | 0:14e5e829dffe | 295 | for (i = (index / SEGLIST_OBJS_PER_SEG); i > 0; i--) |
dadaista | 0:14e5e829dffe | 296 | { |
dadaista | 0:14e5e829dffe | 297 | pseg = pseg->next; |
dadaista | 0:14e5e829dffe | 298 | C_ASSERT(pseg != C_NULL); |
dadaista | 0:14e5e829dffe | 299 | } |
dadaista | 0:14e5e829dffe | 300 | |
dadaista | 0:14e5e829dffe | 301 | /* |
dadaista | 0:14e5e829dffe | 302 | * pseg now points to the correct segment of the item to be removed, so |
dadaista | 0:14e5e829dffe | 303 | * start ripple copying all following items up to the last |
dadaista | 0:14e5e829dffe | 304 | * in the last segment |
dadaista | 0:14e5e829dffe | 305 | */ |
dadaista | 0:14e5e829dffe | 306 | |
dadaista | 0:14e5e829dffe | 307 | for (i = index; i < ((pseglist->sl_length) - 1); i++) |
dadaista | 0:14e5e829dffe | 308 | { |
dadaista | 0:14e5e829dffe | 309 | k = i % SEGLIST_OBJS_PER_SEG; |
dadaista | 0:14e5e829dffe | 310 | |
dadaista | 0:14e5e829dffe | 311 | /* Copy element i+1 to slot i */ |
dadaista | 0:14e5e829dffe | 312 | if ((k + 1) == SEGLIST_OBJS_PER_SEG) |
dadaista | 0:14e5e829dffe | 313 | { |
dadaista | 0:14e5e829dffe | 314 | /* Source is first item in next segment */ |
dadaista | 0:14e5e829dffe | 315 | pseg->s_val[i % SEGLIST_OBJS_PER_SEG] = (pseg->next)->s_val[0]; |
dadaista | 0:14e5e829dffe | 316 | pseg = pseg->next; |
dadaista | 0:14e5e829dffe | 317 | } |
dadaista | 0:14e5e829dffe | 318 | else |
dadaista | 0:14e5e829dffe | 319 | { |
dadaista | 0:14e5e829dffe | 320 | /* Source and target are in the same segment */ |
dadaista | 0:14e5e829dffe | 321 | pseg->s_val[k] = pseg->s_val[k + 1]; |
dadaista | 0:14e5e829dffe | 322 | } |
dadaista | 0:14e5e829dffe | 323 | } |
dadaista | 0:14e5e829dffe | 324 | |
dadaista | 0:14e5e829dffe | 325 | pseglist->sl_length -= 1; |
dadaista | 0:14e5e829dffe | 326 | |
dadaista | 0:14e5e829dffe | 327 | /* Remove the last segment if it was emptied */ |
dadaista | 0:14e5e829dffe | 328 | if (pseglist->sl_length % SEGLIST_OBJS_PER_SEG == 0) |
dadaista | 0:14e5e829dffe | 329 | { |
dadaista | 0:14e5e829dffe | 330 | pseg = pseglist->sl_rootseg; |
dadaista | 0:14e5e829dffe | 331 | |
dadaista | 0:14e5e829dffe | 332 | /* Find the segment before the last */ |
dadaista | 0:14e5e829dffe | 333 | for (i = 0; i < ((pseglist->sl_length - 1) / SEGLIST_OBJS_PER_SEG); |
dadaista | 0:14e5e829dffe | 334 | i++) |
dadaista | 0:14e5e829dffe | 335 | { |
dadaista | 0:14e5e829dffe | 336 | pseg = pseg->next; |
dadaista | 0:14e5e829dffe | 337 | C_ASSERT(pseg != C_NULL); |
dadaista | 0:14e5e829dffe | 338 | } |
dadaista | 0:14e5e829dffe | 339 | if (pseg->next == C_NULL) |
dadaista | 0:14e5e829dffe | 340 | { |
dadaista | 0:14e5e829dffe | 341 | /* |
dadaista | 0:14e5e829dffe | 342 | * Seglist is now completely empty and the last segment can be |
dadaista | 0:14e5e829dffe | 343 | * recycled. |
dadaista | 0:14e5e829dffe | 344 | */ |
dadaista | 0:14e5e829dffe | 345 | #if SEGLIST_CLEAR_SEGMENTS |
dadaista | 0:14e5e829dffe | 346 | PM_RETURN_IF_ERROR(heap_freeChunk((pPmObj_t)pseg)); |
dadaista | 0:14e5e829dffe | 347 | #endif |
dadaista | 0:14e5e829dffe | 348 | pseglist->sl_lastseg = C_NULL; |
dadaista | 0:14e5e829dffe | 349 | pseglist->sl_rootseg = C_NULL; |
dadaista | 0:14e5e829dffe | 350 | } |
dadaista | 0:14e5e829dffe | 351 | else |
dadaista | 0:14e5e829dffe | 352 | { |
dadaista | 0:14e5e829dffe | 353 | /* At least one segment remains */ |
dadaista | 0:14e5e829dffe | 354 | pseglist->sl_lastseg = pseg; |
dadaista | 0:14e5e829dffe | 355 | pseg->next = C_NULL; |
dadaista | 0:14e5e829dffe | 356 | } |
dadaista | 0:14e5e829dffe | 357 | } |
dadaista | 0:14e5e829dffe | 358 | else |
dadaista | 0:14e5e829dffe | 359 | { |
dadaista | 0:14e5e829dffe | 360 | /* Zero out the now unused slot */ |
dadaista | 0:14e5e829dffe | 361 | pseg->s_val[pseglist->sl_length % SEGLIST_OBJS_PER_SEG] = C_NULL; |
dadaista | 0:14e5e829dffe | 362 | } |
dadaista | 0:14e5e829dffe | 363 | |
dadaista | 0:14e5e829dffe | 364 | return PM_RET_OK; |
dadaista | 0:14e5e829dffe | 365 | } |