(file) Return to ownedmemory.c CVS log (file) (dir) Up to [OMI] / omi / pal

  1 krisbash 1.1 #include <pal/ownedmemory.h>
  2              #include <pal/hashmap.h>
  3              #include <pal/lock.h>
  4              
  5              static Lock s_ownedMemoryLock = LOCK_INITIALIZER;
  6              static HashMap _ownedMemoryHashmap;
  7              static PAL_Boolean _ownedMemoryInitialized = PAL_FALSE;
  8              
  9              /*
 10              **==============================================================================
 11              **
 12              ** OwnedMemory hash implementation
 13              **
 14              **==============================================================================
 15              */
 16              
 17              typedef struct _OwnedMemoryBucket /* derives from HashBucket */
 18              {
 19                  struct _OwnedMemoryBucket* next;
 20                  void *key;
 21              }
 22 krisbash 1.1 OwnedMemoryBucket;
 23              
 24              static size_t _OwnedMemoryHash(
 25                  const HashBucket* bucket_)
 26              {
 27                  OwnedMemoryBucket* bucket = (OwnedMemoryBucket*)bucket_;	
 28                  void *key = bucket->key;
 29                  size_t h = (size_t)key >> 4;
 30                  return h;
 31              }
 32              
 33              static int _OwnedMemoryEqual(
 34                  const HashBucket* bucket1_,
 35                  const HashBucket* bucket2_)
 36              {
 37                  OwnedMemoryBucket* bucket1 = (OwnedMemoryBucket*)bucket1_;
 38                  OwnedMemoryBucket* bucket2 = (OwnedMemoryBucket*)bucket2_;
 39                  return (bucket1->key == bucket2->key);
 40              }
 41              
 42              static void _OwnedMemoryRelease(
 43 krisbash 1.1     HashBucket* bucket_)
 44              {
 45                  OwnedMemoryBucket* bucket = (OwnedMemoryBucket*)bucket_;
 46              
 47                  PAL_Free(bucket->key);
 48                  PAL_Free(bucket);
 49              }
 50              
 51              /*
 52              * Called by atexit handler
 53              */
 54              static void ATEXIT_API _OwnedMemory_DeInitialize(void)
 55              {
 56                  Lock_Acquire(&s_ownedMemoryLock);
 57                  
 58                  if(_ownedMemoryInitialized)
 59                  {
 60                      HashMap_Destroy(&_ownedMemoryHashmap);
 61                  }
 62                  
 63                  Lock_Release(&s_ownedMemoryLock);
 64 krisbash 1.1 }
 65              
 66              /*
 67              * Assumes that it is called under lock
 68              */
 69              PAL_Boolean _OwnedMemory_Initialize()
 70              {
 71                  int result = 0;
 72              
 73                  if(!_ownedMemoryInitialized)
 74                  {
 75                      result = HashMap_Init(
 76                          &_ownedMemoryHashmap, 
 77                          64, 
 78                          _OwnedMemoryHash, 
 79                          _OwnedMemoryEqual, 
 80                          _OwnedMemoryRelease);
 81              
 82                      if(result == 0)
 83                      {
 84                          PAL_Atexit(_OwnedMemory_DeInitialize);
 85 krisbash 1.1 
 86                          _ownedMemoryInitialized = PAL_TRUE;
 87                      }
 88                  }
 89              
 90                  return (result == 0);
 91              }
 92              
 93              /*
 94              * Initializes HashMap if not done so yet
 95              * allocates a hash bucket, allocates new memory; stores the bucket in hashmap
 96              * returns the new memory ptr
 97              */
 98              void *OwnedMemory_Alloc(size_t length)
 99              {
100                  OwnedMemoryBucket* bucket = NULL;
101                  void *newMemory = NULL;
102              
103                  Lock_Acquire(&s_ownedMemoryLock);
104                  if(!_OwnedMemory_Initialize())
105                      goto end;
106 krisbash 1.1 
107                  bucket = (OwnedMemoryBucket*)PAL_Calloc(1, sizeof(OwnedMemoryBucket));
108                  if(!bucket)
109                      goto end;
110              
111                  newMemory = PAL_Calloc(1, length);
112              
113                  if(!newMemory)
114                  {
115                      PAL_Free(bucket);
116                      goto end;
117                  }
118                  bucket->key = newMemory;
119              
120                  if(HashMap_Insert(&_ownedMemoryHashmap, (HashBucket *) bucket) != 0)
121                  {
122                      /* this will never happen since same memory location will not be returned 
123                      on two allocations unless first one is freed by the user explicitly 
124                      giving the error to the user by returning NULL in this case */
125                      PAL_Free(bucket);
126                      PAL_Free(newMemory);
127 krisbash 1.1         newMemory = NULL;
128                  }
129              
130              end:
131                  Lock_Release(&s_ownedMemoryLock);
132              
133                  return newMemory;
134              }
135              
136              /*
137              * Attempts to remove the ptr from the hash map and free it; 
138              * returns whether it succeeded in doing so or not
139              */
140              int OwnedMemory_Free(void *ptr)
141              {
142                  int result = 0;
143                  OwnedMemoryBucket bucket;
144                  bucket.key = ptr;
145              
146                  Lock_Acquire(&s_ownedMemoryLock);
147              
148 krisbash 1.1     result = HashMap_Remove(&_ownedMemoryHashmap, (const HashBucket *) &bucket);
149              
150                  Lock_Release(&s_ownedMemoryLock);
151              
152                  return result;
153              }

ViewCVS 0.9.2