📄 gmem.c
字号:
if (mem_chunk->mem_areas) mem_chunk->mem_areas->prev = mem_chunk->mem_area; mem_chunk->mem_areas = mem_chunk->mem_area; if (mem_chunk->type == G_ALLOC_AND_FREE) g_tree_insert (mem_chunk->mem_tree, mem_chunk->mem_area, mem_chunk->mem_area); } mem_chunk->mem_area->index = 0; mem_chunk->mem_area->free = mem_chunk->area_size; mem_chunk->mem_area->allocated = 0; mem_chunk->mem_area->mark = 0; } /* Get the memory and modify the state variables appropriately. */ mem = (gpointer) &mem_chunk->mem_area->mem[mem_chunk->mem_area->index]; mem_chunk->mem_area->index += mem_chunk->atom_size; mem_chunk->mem_area->free -= mem_chunk->atom_size; mem_chunk->mem_area->allocated += 1;outa_here: LEAVE_MEM_CHUNK_ROUTINE (); return mem;}gpointerg_mem_chunk_alloc0 (GMemChunk *mem_chunk){ gpointer mem; mem = g_mem_chunk_alloc (mem_chunk); if (mem) { memset (mem, 0, mem_chunk->atom_size); } return mem;}voidg_mem_chunk_free (GMemChunk *mem_chunk, gpointer mem){ GMemArea *temp_area; GFreeAtom *free_atom; g_return_if_fail (mem_chunk != NULL); g_return_if_fail (mem != NULL); ENTER_MEM_CHUNK_ROUTINE ();#ifdef ENABLE_GC_FRIENDLY memset (mem, 0, mem_chunk->atom_size);#endif /* ENABLE_GC_FRIENDLY */ /* Don't do anything if this is an ALLOC_ONLY chunk */ if (mem_chunk->type == G_ALLOC_AND_FREE) { /* Place the memory on the "free_atoms" list */ free_atom = (GFreeAtom*) mem; free_atom->next = mem_chunk->free_atoms; mem_chunk->free_atoms = free_atom; temp_area = g_tree_search (mem_chunk->mem_tree, (GCompareFunc) g_mem_chunk_area_search, mem); temp_area->allocated -= 1; if (temp_area->allocated == 0) { temp_area->mark = 1; mem_chunk->num_marked_areas += 1; } } LEAVE_MEM_CHUNK_ROUTINE ();}/* This doesn't free the free_area if there is one */voidg_mem_chunk_clean (GMemChunk *mem_chunk){ GMemArea *mem_area; GFreeAtom *prev_free_atom; GFreeAtom *temp_free_atom; gpointer mem; g_return_if_fail (mem_chunk != NULL); ENTER_MEM_CHUNK_ROUTINE (); if (mem_chunk->type == G_ALLOC_AND_FREE) { prev_free_atom = NULL; temp_free_atom = mem_chunk->free_atoms; while (temp_free_atom) { mem = (gpointer) temp_free_atom; mem_area = g_tree_search (mem_chunk->mem_tree, (GCompareFunc) g_mem_chunk_area_search, mem); /* If this mem area is marked for destruction then delete the * area and list node and decrement the free mem. */ if (mem_area->mark) { if (prev_free_atom) prev_free_atom->next = temp_free_atom->next; else mem_chunk->free_atoms = temp_free_atom->next; temp_free_atom = temp_free_atom->next; mem_area->free += mem_chunk->atom_size; if (mem_area->free == mem_chunk->area_size) { mem_chunk->num_mem_areas -= 1; mem_chunk->num_marked_areas -= 1; if (mem_area->next) mem_area->next->prev = mem_area->prev; if (mem_area->prev) mem_area->prev->next = mem_area->next; if (mem_area == mem_chunk->mem_areas) mem_chunk->mem_areas = mem_chunk->mem_areas->next; if (mem_area == mem_chunk->mem_area) mem_chunk->mem_area = NULL; if (mem_chunk->type == G_ALLOC_AND_FREE) g_tree_remove (mem_chunk->mem_tree, mem_area); g_free (mem_area); } } else { prev_free_atom = temp_free_atom; temp_free_atom = temp_free_atom->next; } } } LEAVE_MEM_CHUNK_ROUTINE ();}voidg_mem_chunk_reset (GMemChunk *mem_chunk){ GMemArea *mem_areas; GMemArea *temp_area; g_return_if_fail (mem_chunk != NULL); ENTER_MEM_CHUNK_ROUTINE (); mem_areas = mem_chunk->mem_areas; mem_chunk->num_mem_areas = 0; mem_chunk->mem_areas = NULL; mem_chunk->mem_area = NULL; while (mem_areas) { temp_area = mem_areas; mem_areas = mem_areas->next; g_free (temp_area); } mem_chunk->free_atoms = NULL; if (mem_chunk->mem_tree) { g_tree_destroy (mem_chunk->mem_tree); mem_chunk->mem_tree = g_tree_new ((GCompareFunc) g_mem_chunk_area_compare); } LEAVE_MEM_CHUNK_ROUTINE ();}voidg_mem_chunk_print (GMemChunk *mem_chunk){ GMemArea *mem_areas; gulong mem; g_return_if_fail (mem_chunk != NULL); mem_areas = mem_chunk->mem_areas; mem = 0; while (mem_areas) { mem += mem_chunk->area_size - mem_areas->free; mem_areas = mem_areas->next; } g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "%s: %ld bytes using %d mem areas", mem_chunk->name, mem, mem_chunk->num_mem_areas);}voidg_mem_chunk_info (void){ GMemChunk *mem_chunk; gint count; count = 0; g_mutex_lock (mem_chunks_lock); mem_chunk = mem_chunks; while (mem_chunk) { count += 1; mem_chunk = mem_chunk->next; } g_mutex_unlock (mem_chunks_lock); g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "%d mem chunks", count); g_mutex_lock (mem_chunks_lock); mem_chunk = mem_chunks; g_mutex_unlock (mem_chunks_lock); while (mem_chunk) { g_mem_chunk_print ((GMemChunk*) mem_chunk); mem_chunk = mem_chunk->next; } }voidg_blow_chunks (void){ GMemChunk *mem_chunk; g_mutex_lock (mem_chunks_lock); mem_chunk = mem_chunks; g_mutex_unlock (mem_chunks_lock); while (mem_chunk) { g_mem_chunk_clean ((GMemChunk*) mem_chunk); mem_chunk = mem_chunk->next; }}static gulongg_mem_chunk_compute_size (gulong size, gulong min_size){ gulong power_of_2; gulong lower, upper; power_of_2 = 16; while (power_of_2 < size) power_of_2 <<= 1; lower = power_of_2 >> 1; upper = power_of_2; if (size - lower < upper - size && lower >= min_size) return lower; else return upper;}static gintg_mem_chunk_area_compare (GMemArea *a, GMemArea *b){ if (a->mem > b->mem) return 1; else if (a->mem < b->mem) return -1; return 0;}static gintg_mem_chunk_area_search (GMemArea *a, gchar *addr){ if (a->mem <= addr) { if (addr < &a->mem[a->index]) return 0; return 1; } return -1;}#else /* DISABLE_MEM_POOLS */typedef struct { guint alloc_size; /* the size of an atom */} GMinimalMemChunk;GMemChunk*g_mem_chunk_new (const gchar *name, gint atom_size, gulong area_size, gint type){ GMinimalMemChunk *mem_chunk; g_return_val_if_fail (atom_size > 0, NULL); mem_chunk = g_new (GMinimalMemChunk, 1); mem_chunk->alloc_size = atom_size; return ((GMemChunk*) mem_chunk);}voidg_mem_chunk_destroy (GMemChunk *mem_chunk){ g_return_if_fail (mem_chunk != NULL); g_free (mem_chunk);}gpointerg_mem_chunk_alloc (GMemChunk *mem_chunk){ GMinimalMemChunk *minimal = (GMinimalMemChunk *)mem_chunk; g_return_val_if_fail (mem_chunk != NULL, NULL); return g_malloc (minimal->alloc_size);}gpointerg_mem_chunk_alloc0 (GMemChunk *mem_chunk){ GMinimalMemChunk *minimal = (GMinimalMemChunk *)mem_chunk; g_return_val_if_fail (mem_chunk != NULL, NULL); return g_malloc0 (minimal->alloc_size);}voidg_mem_chunk_free (GMemChunk *mem_chunk, gpointer mem){ g_return_if_fail (mem_chunk != NULL); g_free (mem);}void g_mem_chunk_clean (GMemChunk *mem_chunk) {}void g_mem_chunk_reset (GMemChunk *mem_chunk) {}void g_mem_chunk_print (GMemChunk *mem_chunk) {}void g_mem_chunk_info (void) {}void g_blow_chunks (void) {}#endif /* DISABLE_MEM_POOLS *//* generic allocators */struct _GAllocator /* from gmem.c */{ gchar *name; guint16 n_preallocs; guint is_unused : 1; guint type : 4; GAllocator *last; GMemChunk *mem_chunk; gpointer dummy; /* implementation specific */};GAllocator*g_allocator_new (const gchar *name, guint n_preallocs){ GAllocator *allocator; g_return_val_if_fail (name != NULL, NULL); allocator = g_new0 (GAllocator, 1); allocator->name = g_strdup (name); allocator->n_preallocs = CLAMP (n_preallocs, 1, 65535); allocator->is_unused = TRUE; allocator->type = 0; allocator->last = NULL; allocator->mem_chunk = NULL; allocator->dummy = NULL; return allocator;}voidg_allocator_free (GAllocator *allocator){ g_return_if_fail (allocator != NULL); g_return_if_fail (allocator->is_unused == TRUE); g_free (allocator->name); if (allocator->mem_chunk) g_mem_chunk_destroy (allocator->mem_chunk); g_free (allocator);}voidg_mem_init (void){#ifndef DISABLE_MEM_POOLS mem_chunks_lock = g_mutex_new ();#endif#ifndef G_DISABLE_CHECKS mem_chunk_recursion = g_private_new (NULL); g_profile_mutex = g_mutex_new ();#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -