/* * Emulates the Heap* routines. * * Authors: * Gonzalo Paniagua (gonzalo@ximian.com) * Miguel de Icaza (miguel@novell.com) * * (C) 2005 Novell, Inc. * */ #include #include #include #include #include "supportw.h" gpointer HeapAlloc (gpointer unused1, gint32 unused2, gint32 nbytes); gpointer HeapCreate (gint32 flags, gint32 initial_size, gint32 max_size); gboolean HeapSetInformation (gpointer handle, gpointer heap_info_class, gpointer heap_info, gint32 head_info_length); gboolean HeapQueryInformation (gpointer handle, gpointer heap_info_class, gpointer heap_info, gint32 head_info_length, gint32 *ret_length); gpointer HeapAlloc (gpointer handle, gint32 flags, gint32 nbytes); gpointer HeapReAlloc (gpointer handle, gint32 flags, gpointer mem, gint32 nbytes); gint32 HeapSize (gpointer handle, gint32 flags, gpointer mem); gboolean HeapFree (gpointer handle, gint32 flags, gpointer mem); gboolean HeapValidate (gpointer handle, gpointer mem); gboolean HeapDestroy (gpointer handle); typedef struct _HeapInfo { gint32 flags; gint32 initial_size; gint32 max_size; GHashTable *hash; } HeapInfo; /* Some initial value for the process heap */ HeapInfo *process_heap; static GHashTable *heaps; gpointer HeapCreate (gint32 flags, gint32 initial_size, gint32 max_size) { HeapInfo *hi; if (heaps == NULL) heaps = g_hash_table_new (g_direct_hash, g_direct_equal); if (flags != 0) g_warning ("Flags for HeapCreate are the unsupported value non-zero"); hi = g_new (HeapInfo, 1); hi->flags = flags; hi->initial_size = initial_size; hi->max_size = max_size; hi->hash = g_hash_table_new (g_direct_hash, g_direct_equal); g_hash_table_insert (heaps, hi, hi); return hi; } gboolean HeapSetInformation (gpointer handle, gpointer heap_info_class, gpointer heap_info, gint32 head_info_length) { return TRUE; } gboolean HeapQueryInformation (gpointer handle, gpointer heap_info_class, gpointer heap_info, gint32 head_info_length, gint32 *ret_length) { *ret_length = 0; return TRUE; } gpointer HeapAlloc (gpointer handle, gint32 flags, gint32 nbytes) { HeapInfo *heap = (HeapInfo *) handle; void *ptr; ptr = g_malloc0 (nbytes); g_hash_table_insert (heap->hash, ptr, GINT_TO_POINTER (nbytes)); return ptr; } gpointer HeapReAlloc (gpointer handle, gint32 flags, gpointer mem, gint32 nbytes) { HeapInfo *heap = (HeapInfo *) handle; void *ptr; g_hash_table_remove (heap->hash, mem); ptr = g_realloc (mem, nbytes); g_hash_table_insert (heap->hash, ptr, GINT_TO_POINTER (nbytes)); return ptr; } gint32 HeapSize (gpointer handle, gint32 flags, gpointer mem) { HeapInfo *heap = (HeapInfo *) handle; gint32 size = GPOINTER_TO_INT (g_hash_table_lookup (heap->hash, mem)); return size; } gboolean HeapFree (gpointer handle, gint32 flags, gpointer mem) { HeapInfo *heap = (HeapInfo *) handle; g_hash_table_remove (heap->hash, GINT_TO_POINTER (mem)); g_free (mem); return TRUE; } gboolean HeapValidate (gpointer handle, gpointer mem) { return TRUE; } static void free_handles (gpointer key, gpointer value, gpointer user_data) { g_free (key); } gboolean HeapDestroy (gpointer handle) { HeapInfo *heap = (HeapInfo *) handle; /* Failure is zero */ if (handle == process_heap) return 0; g_hash_table_foreach (heap->hash, free_handles, NULL); g_hash_table_destroy (heap->hash); g_hash_table_remove (heaps, handle); g_free (heap); return 1; } gpointer GetProcessHeap (void); gpointer GetProcessHeap (void) { if (process_heap == NULL){ process_heap = g_new (HeapInfo, 1); process_heap->flags = 0; process_heap->initial_size = 1024; process_heap->max_size = 1024*1024*1024; } return process_heap; } /* end Heap* functions */