@@ -284,34 +284,53 @@ static void deleteblock(LispPTR base) {
284284/* */
285285/* */
286286/************************************************************************/
287+ /*
288+ * Links a block onto the free list for a particular size range.
289+ * The free list is maintained as a doubly linked circular list accessed
290+ * from the block pointed to by the free list bucket for the size.
291+ * If there are no blocks in the free list bucket then the forward and
292+ * backward pointers of the newly added block point to the block itself.
293+ */
294+ static LispPTR linkblock (LispPTR base ) {
295+ struct arrayblock * base_np , * freeblock_np , * tail_np ;
296+ LispPTR fbl , freeblock ;
297+ LispPTR * fbl_np ;
287298
288- LispPTR linkblock (LispPTR base ) {
289- struct arrayblock * bbase , * fbbase , * tmpbase ;
290- LispPTR fbl , freeblocklsp ;
291- LispPTR * freeblock ;
292- if (* FreeBlockBuckets_word != NIL ) {
293- bbase = (struct arrayblock * )NativeAligned4FromLAddr (base );
294- if (bbase -> arlen < MINARRAYBLOCKSIZE )
295- checkarrayblock (base , T , NIL );
296- else {
297- fbl = FreeBlockChainN (bbase -> arlen );
298- freeblock = (LispPTR * )NativeAligned4FromLAddr (POINTERMASK & fbl );
299- freeblocklsp = POINTERMASK & (* freeblock );
300- if (freeblocklsp == NIL ) {
301- bbase -> fwd = base ;
302- bbase -> bkwd = base ;
303- } else {
304- fbbase = (struct arrayblock * )NativeAligned4FromLAddr (freeblocklsp );
305- bbase -> fwd = freeblocklsp ;
306- bbase -> bkwd = fbbase -> bkwd ;
307- tmpbase = (struct arrayblock * )NativeAligned4FromLAddr (fbbase -> bkwd );
308- tmpbase -> fwd = base ;
309- fbbase -> bkwd = base ;
310- }
311- * freeblock = base ;
312- checkarrayblock (base , T , T );
313- }
299+ if (* FreeBlockBuckets_word == NIL )
300+ return (base );
301+
302+ base_np = (struct arrayblock * )NativeAligned4FromLAddr (base );
303+ if (base_np -> arlen < MINARRAYBLOCKSIZE ) {
304+ checkarrayblock (base , T , NIL );
305+ return (base );
306+ }
307+
308+ /* lisp pointer to bucket for size */
309+ fbl = FreeBlockChainN (base_np -> arlen );
310+ /* native pointer to bucket */
311+ fbl_np = (LispPTR * )NativeAligned4FromLAddr (POINTERMASK & fbl );
312+ /* lisp pointer to first free block on chain */
313+ freeblock = POINTERMASK & (* fbl_np );
314+ if (freeblock == NIL ) { /* no blocks already in chain */
315+ base_np -> fwd = base ;
316+ base_np -> bkwd = base ;
317+ } else {
318+ /* set up new block to be first free block on the chain */
319+ freeblock_np = (struct arrayblock * )NativeAligned4FromLAddr (freeblock );
320+ /* link new block forward to free block */
321+ base_np -> fwd = freeblock ;
322+ /* new block's backward link becomes free block's backward link */
323+ base_np -> bkwd = freeblock_np -> bkwd ;
324+ /* get the tail location (backward pointer of freelist head) */
325+ tail_np = (struct arrayblock * )NativeAligned4FromLAddr (freeblock_np -> bkwd );
326+ /* set its forward pointer to new block */
327+ tail_np -> fwd = base ;
328+ /* and the update the free block's backward link to new block */
329+ freeblock_np -> bkwd = base ;
314330 }
331+ /* new block becomes the head of the free list */
332+ * fbl_np = base ;
333+ checkarrayblock (base , T , T ); /* free, and on free list */
315334 return (base );
316335}
317336
0 commit comments