home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / stdlib / free.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-12-11  |  3.4 KB  |  127 lines

  1. /* 
  2.  * free.c --
  3.  *
  4.  *    Source code for the "free" library procedure.  See memInt.h for
  5.  *    overall information about how the allocator works.
  6.  *
  7.  * Copyright 1985, 1988 Regents of the University of California
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  */
  16.  
  17. #ifndef lint
  18. static char rcsid[] = "$Header: /sprite/src/lib/c/stdlib/RCS/free.c,v 1.6 89/12/11 13:39:44 rab Exp $ SPRITE (Berkeley)";
  19. #endif /* not lint */
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include "memInt.h"
  24.  
  25. /*
  26.  * Variable that indicates whether or not it's acceptable to free
  27.  * a block that's already free (for some reason, many UNIX programs,
  28.  * damn them to hell, do this).
  29.  */
  30.  
  31. int    memAllowFreeingFree = 1;
  32.  
  33. /*
  34.  * ----------------------------------------------------------------------------
  35.  *
  36.  * free --
  37.  *
  38.  *      Return a previously-allocated block of storage to the free pool.
  39.  *
  40.  * Results:
  41.  *      None.
  42.  *
  43.  * Side effects:
  44.  *      The storage pointed to by blockPtr is marked as free and returned
  45.  *    to the free pool.  Nothing in the bytes pointed to by blockPtr is
  46.  *    modified at this time:  no change will occur until at least the
  47.  *    next call to malloc or realloc.  This means that callers may use
  48.  *    the contents of a block for a short time after free-ing it (e.g.
  49.  *    to read a "next" pointer).
  50.  *
  51.  * ----------------------------------------------------------------------------
  52.  */
  53.  
  54. ENTRY
  55. #ifdef lint
  56. void
  57. #endif
  58. free(blockPtr)
  59.     register Address blockPtr;    /* Pointer to storage to be freed.  Must
  60.                  * have been the return value from Mem_Alloc
  61.                  * at some previous time.  */
  62. {
  63.     register int  admin;
  64.     register int  index;
  65.     register int  size;
  66.  
  67.     LOCK_MONITOR;
  68.  
  69. #ifdef MEM_TRACE
  70.     mem_NumFrees++;
  71. #endif
  72.  
  73.     if (!memInitialized) {
  74.         panic("Mem_Free: allocator not initialized!\n");
  75.     return;        /* should never get here */
  76.     }
  77.     if (blockPtr == NULL) {
  78.     UNLOCK_MONITOR;
  79.     return;
  80.     }
  81.  
  82.     /* 
  83.      *  Make sure that this block bears some resemblance to a
  84.      *  well-formed storage block.
  85.      */
  86.  
  87.     blockPtr -= sizeof(AdminInfo);
  88.     admin = GET_ADMIN(blockPtr);
  89.     if (!IS_IN_USE(admin)) {
  90.     if (IS_DUMMY(admin)) {
  91.         panic("Mem_Free: storage block corrupted\n");
  92.     }
  93.     if (!memAllowFreeingFree) {
  94.         panic("Mem_Free: storage block already free\n");
  95.     }
  96.     UNLOCK_MONITOR;
  97.     return;
  98.     }
  99.  
  100.     /* This procedure is easier for un-binned blocks (those without the
  101.      * DUMMY bit set) than for the binned ones.  If un-binned, just clear
  102.      * the use bit and record how many bytes were freed, for use later
  103.      * when deciding whether or not to allocate more storage.
  104.      */
  105.  
  106.     size = SIZE(admin);
  107.     index = BLOCKSIZE_TO_INDEX(size);
  108.     if (!IS_DUMMY(admin)) {
  109.     SET_ADMIN(blockPtr, MARK_FREE(admin));
  110.     memBytesFreed += SIZE(admin);
  111.     } else {
  112.     /* 
  113.      * For small blocks, add the block back onto its free list.
  114.      */
  115.  
  116.     index = BLOCKSIZE_TO_INDEX(SIZE(admin));
  117.     SET_ADMIN(blockPtr, MARK_FREE((int) memFreeLists[index]));
  118.     memFreeLists[index] = blockPtr;
  119.     }
  120.  
  121. #ifdef MEM_TRACE
  122.     MemDoTrace(FALSE, blockPtr, Mem_CallerPC(), size);
  123. #endif MEM_TRACE
  124.  
  125.     UNLOCK_MONITOR;
  126. }
  127.