1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/graphicscomposition/openwfcompositionengine/common/src/owfmemory.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,322 @@
1.4 +/* Copyright (c) 2009 The Khronos Group Inc.
1.5 + * Portions copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies)
1.6 + *
1.7 + * Permission is hereby granted, free of charge, to any person obtaining a
1.8 + * copy of this software and/or associated documentation files (the
1.9 + * "Materials"), to deal in the Materials without restriction, including
1.10 + * without limitation the rights to use, copy, modify, merge, publish,
1.11 + * distribute, sublicense, and/or sell copies of the Materials, and to
1.12 + * permit persons to whom the Materials are furnished to do so, subject to
1.13 + * the following conditions:
1.14 + *
1.15 + * The above copyright notice and this permission notice shall be included
1.16 + * in all copies or substantial portions of the Materials.
1.17 + *
1.18 + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1.19 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1.20 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1.21 + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
1.22 + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
1.23 + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
1.24 + * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
1.25 + */
1.26 +
1.27 +
1.28 +#ifdef __cplusplus
1.29 +extern "C"
1.30 +{
1.31 +#endif
1.32 +
1.33 +
1.34 +#include <string.h>
1.35 +#include <stdlib.h>
1.36 +#include <stdio.h>
1.37 +#include <pthread.h>
1.38 +
1.39 +#include "owfmemory.h"
1.40 +#include "owfdebug.h"
1.41 +
1.42 +#ifdef DEBUG
1.43 +
1.44 +#define MAGIK 0x05EAF00D
1.45 +#define FENCE1 0xFACED00D
1.46 +#define FENCE2 0xFACE50FF
1.47 +
1.48 +#define OFFSET(x,y) ((OWFuint32)&(((x*) 0x1000)->y) - 0x1000)
1.49 +
1.50 +typedef struct BLOCK_ {
1.51 + OWFint magik;
1.52 + struct BLOCK_* next;
1.53 + const char* file;
1.54 + OWFint line;
1.55 + OWFuint32 size;
1.56 + OWFuint32 nInts;
1.57 + OWFint memory[2];
1.58 +} BLOCK;
1.59 +
1.60 +
1.61 +
1.62 +
1.63 +static void
1.64 +OWF_Memory_Shutdown(void);
1.65 +
1.66 +
1.67 +
1.68 +static void
1.69 +OWF_Memory_LockUnlockManagedBlocks(OWFboolean lock)
1.70 +{
1.71 +#ifndef DEBUG
1.72 + (void) lock;
1.73 +#endif
1.74 +
1.75 +#ifdef DEBUG
1.76 + /* cannot use OWF_MUTEX because it uses managed memory */
1.77 + static pthread_mutex_t mem_mutex = PTHREAD_MUTEX_INITIALIZER;
1.78 +
1.79 + if (lock)
1.80 + {
1.81 + pthread_mutex_lock(&mem_mutex);
1.82 + }
1.83 + else
1.84 + {
1.85 + pthread_mutex_unlock(&mem_mutex);
1.86 + }
1.87 +#endif
1.88 +}
1.89 +
1.90 +static void
1.91 +OWF_Memory_LockManagedBlocks()
1.92 +{
1.93 + OWF_Memory_LockUnlockManagedBlocks(OWF_TRUE);
1.94 +}
1.95 +
1.96 +static void
1.97 +OWF_Memory_UnlockManagedBlocks()
1.98 +{
1.99 + OWF_Memory_LockUnlockManagedBlocks(OWF_FALSE);
1.100 +}
1.101 +
1.102 +
1.103 +OWF_API_CALL BLOCK*
1.104 +OWF_Memory_GetSetManagedBlocks(BLOCK* b, OWFboolean set)
1.105 +{
1.106 +#ifdef DEBUG
1.107 + static BLOCK* managed_blocks = NULL;
1.108 + static OWFboolean initialized = OWF_FALSE;
1.109 +
1.110 + if (!initialized) {
1.111 + /* add exit handler (leak report) */
1.112 + atexit(OWF_Memory_Shutdown);
1.113 + initialized = OWF_TRUE;
1.114 + }
1.115 +
1.116 + if (set)
1.117 + {
1.118 + managed_blocks = b;
1.119 + return b;
1.120 + }
1.121 + else
1.122 + {
1.123 + return managed_blocks;
1.124 + }
1.125 +#else
1.126 + if (set)
1.127 + {
1.128 + b = b; /* dummy code */
1.129 + }
1.130 + return NULL;
1.131 +#endif
1.132 +}
1.133 +
1.134 +static BLOCK*
1.135 +OWF_Memory_GetManagedBlocks()
1.136 +{
1.137 + return OWF_Memory_GetSetManagedBlocks(NULL, OWF_FALSE);
1.138 +}
1.139 +
1.140 +static void
1.141 +OWF_Memory_SetManagedBlocks(BLOCK* b)
1.142 +{
1.143 + OWF_Memory_GetSetManagedBlocks(b, OWF_TRUE);
1.144 +}
1.145 +
1.146 +OWF_API_CALL void*
1.147 +OWF_Memory_Alloc(const char* file, OWFint line, OWFuint32 size)
1.148 +{
1.149 +#define INT_SIZE sizeof(OWFint)
1.150 +
1.151 + BLOCK* block = NULL;
1.152 +
1.153 + /* size rounded to nearest sizeof(int)*n + 2*sizeof(int) for fences */
1.154 + OWFuint32 nInts = 2 + (((size + INT_SIZE-1) &~ (INT_SIZE-1)) >> 2);
1.155 + OWFuint32 realSize = nInts * INT_SIZE + sizeof(BLOCK);
1.156 +
1.157 + if (realSize > size) /* not int overflow */
1.158 + {
1.159 + block = (BLOCK*) malloc(realSize);
1.160 + }
1.161 +
1.162 + if (!block)
1.163 + {
1.164 + DPRINT(("Couldn't alloc %u bytes\n", size));
1.165 + return NULL;
1.166 + }
1.167 +
1.168 + /* populate block header */
1.169 + memset(block, 0, realSize);
1.170 + block->magik = MAGIK;
1.171 + block->file = file;
1.172 + block->line = line;
1.173 + block->size = size;
1.174 + block->nInts = nInts;
1.175 + block->memory[0] = FENCE1;
1.176 + block->memory[nInts-1] = FENCE2;
1.177 +
1.178 + OWF_Memory_LockManagedBlocks();
1.179 + {
1.180 + /* insert to list at position 0 */
1.181 + block->next = (BLOCK*) OWF_Memory_GetManagedBlocks();
1.182 + OWF_Memory_SetManagedBlocks(block);
1.183 + }
1.184 + OWF_Memory_UnlockManagedBlocks();
1.185 +
1.186 + return &block->memory[1];
1.187 +}
1.188 +
1.189 +OWF_API_CALL void
1.190 +OWF_Memory_Free(void* ptr)
1.191 +{
1.192 + BLOCK* block = NULL;
1.193 +
1.194 + if (!ptr) {
1.195 + return;
1.196 + }
1.197 +
1.198 + /* POINTER ARITHMETIC HAZARD */
1.199 + block = (BLOCK*) ((OWFuint32) ptr - (OWFuint32) OFFSET(BLOCK,memory[1]));
1.200 +
1.201 + if (!block)
1.202 + {
1.203 + DPRINT(("Sanity check failed. Ptr was zero....\n"));
1.204 + return;
1.205 + }
1.206 +
1.207 + OWF_Memory_LockManagedBlocks();
1.208 + {
1.209 + BLOCK* temp = NULL;
1.210 + BLOCK* prev = NULL;
1.211 + OWFboolean stillExists = OWF_FALSE;
1.212 +
1.213 + temp = OWF_Memory_GetManagedBlocks();
1.214 +
1.215 + while (temp)
1.216 + {
1.217 + /* the block is on the list? */
1.218 + if (temp == block && ptr == &temp->memory[1])
1.219 + {
1.220 + stillExists = OWF_TRUE;
1.221 + break;
1.222 + }
1.223 + prev = temp;
1.224 + temp = temp->next;
1.225 + }
1.226 +
1.227 + if (stillExists == OWF_TRUE)
1.228 + {
1.229 + if (MAGIK != temp->magik)
1.230 + {
1.231 + DPRINT(("Possibly corrupt or invalid block, addr = %p\n", ptr));
1.232 + }
1.233 + if (block->memory[0] != (OWFint)FENCE1)
1.234 + {
1.235 + DPRINT(("Block's start fence corrupted, addr = %p\n", ptr));
1.236 + }
1.237 + if (block->memory[block->nInts-1] != (OWFint)FENCE2)
1.238 + {
1.239 + DPRINT(("Block's end fence corrupted, addr = %p\n", ptr));
1.240 + }
1.241 +
1.242 + /* valid block, unlink & free it */
1.243 + if (prev)
1.244 + {
1.245 + prev->next = temp->next;
1.246 + }
1.247 + else
1.248 + {
1.249 + OWF_Memory_SetManagedBlocks(temp->next);
1.250 + }
1.251 + free(block);
1.252 + }
1.253 + else
1.254 + {
1.255 + /* possibly already freed, strangled pointer. complain. */
1.256 + DPRINT(("Block possibly freed already! (block = %p, addr = %p)\n",
1.257 + (void*) block, ptr));
1.258 + }
1.259 + }
1.260 + OWF_Memory_UnlockManagedBlocks();
1.261 +
1.262 +}
1.263 +
1.264 +OWF_API_CALL void
1.265 +OWF_Memory_BlockDump()
1.266 +{
1.267 + BLOCK* block = OWF_Memory_GetManagedBlocks();
1.268 +
1.269 + /* managed blocks locked when this is executed */
1.270 +
1.271 + while (block)
1.272 + {
1.273 + BLOCK* next = (BLOCK*) block->next;
1.274 + if (MAGIK == block->magik)
1.275 + {
1.276 + DPRINT(("Block: %p\nFile: %s(%d)\nSize: %u bytes\n",
1.277 + (void*) &block->memory[1],
1.278 + block->file,
1.279 + block->line,
1.280 + block->size));
1.281 + }
1.282 + else
1.283 + {
1.284 + DPRINT(("Possibly corrupt or invalid block (addr = %p)\n",
1.285 + (void*) block));
1.286 + }
1.287 + block = next;
1.288 + }
1.289 +}
1.290 +
1.291 +#ifdef DEBUG
1.292 +static void
1.293 +OWF_Memory_Shutdown()
1.294 +{
1.295 + BLOCK* block = NULL;
1.296 +
1.297 + OWF_Memory_LockManagedBlocks();
1.298 + {
1.299 +
1.300 + if (OWF_Memory_GetManagedBlocks())
1.301 + {
1.302 + DPRINT(("======================================================================\n"));DPRINT(("MEMORY LEAK REPORT\n"));DPRINT(("======================================================================\n"));
1.303 + OWF_Memory_BlockDump();
1.304 + block = OWF_Memory_GetManagedBlocks();
1.305 + while (block)
1.306 + {
1.307 + BLOCK* next = (BLOCK*) block->next;
1.308 + if (MAGIK == block->magik)
1.309 + {
1.310 + free(block);
1.311 + }
1.312 + block = next;
1.313 + }
1.314 + OWF_Memory_SetManagedBlocks(NULL);
1.315 + }
1.316 +
1.317 + }
1.318 + OWF_Memory_UnlockManagedBlocks();
1.319 +}
1.320 +#endif
1.321 +#endif
1.322 +
1.323 +#ifdef __cplusplus
1.324 +}
1.325 +#endif