static void wmem_test_allocator_jumbo(wmem_allocator_type_t type, wmem_verify_func verify) { wmem_allocator_t *allocator; char *ptr, *ptr1; allocator = wmem_allocator_force_new(type); ptr = (char*)wmem_alloc0(allocator, 4*1024*1024); wmem_free(allocator, ptr); wmem_gc(allocator); ptr = (char*)wmem_alloc0(allocator, 4*1024*1024); if (verify) (*verify)(allocator); wmem_free(allocator, ptr); wmem_gc(allocator); if (verify) (*verify)(allocator); ptr = (char *)wmem_alloc0(allocator, 10*1024*1024); ptr1 = (char *)wmem_alloc0(allocator, 13*1024*1024); ptr1 = (char *)wmem_realloc(allocator, ptr1, 10*1024*1024); memset(ptr1, 0, 10*1024*1024); ptr = (char *)wmem_realloc(allocator, ptr, 13*1024*1024); memset(ptr, 0, 13*1024*1024); if (verify) (*verify)(allocator); wmem_gc(allocator); if (verify) (*verify)(allocator); wmem_free(allocator, ptr1); if (verify) (*verify)(allocator); wmem_free_all(allocator); wmem_gc(allocator); if (verify) (*verify)(allocator); wmem_destroy_allocator(allocator); }
/* Reallocs special 'jumbo' blocks of sizes that won't fit normally. */ static void * wmem_block_realloc_jumbo(wmem_block_allocator_t *allocator, wmem_block_chunk_t *chunk, const size_t size) { wmem_block_hdr_t *block; block = WMEM_CHUNK_TO_BLOCK(chunk); block = (wmem_block_hdr_t *) wmem_realloc(NULL, block, size + WMEM_BLOCK_HEADER_SIZE + WMEM_CHUNK_HEADER_SIZE); if (block->next) { block->next->prev = block; } if (block->prev) { block->prev->next = block; } else { allocator->block_list = block; } return WMEM_CHUNK_TO_DATA(WMEM_BLOCK_TO_CHUNK(block)); }
static void wmem_test_allocator_det(wmem_allocator_t *allocator, wmem_verify_func verify, guint len) { int i; char *ptrs[MAX_SIMULTANEOUS_ALLOCS]; /* we use wmem_alloc0 in part because it tests slightly more code, but * primarily so that if the allocator doesn't give us enough memory or * gives us memory that includes its own metadata, we write to it and * things go wrong, causing the tests to fail */ for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) { ptrs[i] = (char *)wmem_alloc0(allocator, len); } for (i=MAX_SIMULTANEOUS_ALLOCS-1; i>=0; i--) { /* no wmem_realloc0 so just use memset manually */ ptrs[i] = (char *)wmem_realloc(allocator, ptrs[i], 4*len); memset(ptrs[i], 0, 4*len); } for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) { wmem_free(allocator, ptrs[i]); } if (verify) (*verify)(allocator); wmem_free_all(allocator); wmem_gc(allocator); if (verify) (*verify)(allocator); }
static inline void wmem_strbuf_grow(wmem_strbuf_t *strbuf, const gsize to_add) { gsize new_alloc_len, new_len; new_alloc_len = strbuf->alloc_len; new_len = strbuf->len + to_add; /* +1 for the null-terminator */ while (new_alloc_len < (new_len + 1)) { new_alloc_len *= 2; } /* max length only enforced if not 0 */ if (strbuf->max_len && new_alloc_len > strbuf->max_len) { new_alloc_len = strbuf->max_len; } if (new_alloc_len == strbuf->alloc_len) { return; } strbuf->str = (gchar *)wmem_realloc(strbuf->allocator, strbuf->str, new_alloc_len); strbuf->alloc_len = new_alloc_len; }
/* Truncates the allocated memory down to the minimal amount, frees the header * structure, and returns a non-const pointer to the raw string. The * wmem_strbuf_t structure cannot be used after this is called. */ char * wmem_strbuf_finalize(wmem_strbuf_t *strbuf) { char *ret; ret = (char *)wmem_realloc(strbuf->allocator, strbuf->str, strbuf->len+1); wmem_free(strbuf->allocator, strbuf); return ret; }
static void * wmem_simple_alloc(void *private_data, const size_t size) { wmem_simple_allocator_t *allocator; allocator = (wmem_simple_allocator_t*) private_data; if (G_UNLIKELY(allocator->count == allocator->size)) { allocator->size *= 2; allocator->ptrs = (void**)wmem_realloc(NULL, allocator->ptrs, sizeof(void*) * allocator->size); } return allocator->ptrs[allocator->count++] = wmem_alloc(NULL, size); }
static void * wmem_simple_realloc(void *private_data, void *ptr, const size_t size) { int i; wmem_simple_allocator_t *allocator; allocator = (wmem_simple_allocator_t*) private_data; for (i=allocator->count-1; i>=0; i--) { if (ptr == allocator->ptrs[i]) { return allocator->ptrs[i] = wmem_realloc(NULL, allocator->ptrs[i], size); } } g_assert_not_reached(); return NULL; }
static void * wmem_simple_realloc(void *private_data, void *ptr, const size_t size) { void *newptr; wmem_simple_allocator_t *allocator; allocator = (wmem_simple_allocator_t*) private_data; newptr = wmem_realloc(NULL, ptr, size); if (ptr != newptr) { /* Realloc actually moved the memory block, so we need to replace the * value in our hash table. Calling g_hash_table_remove() would trigger * a wmem_free() which is incorrect since realloc already reclaimed the old * block, so use g_hash_table_steal() instead. */ g_hash_table_steal(allocator->block_table, ptr); g_hash_table_insert(allocator->block_table, newptr, newptr); } return newptr; }
static int dissect_mount_dirpath_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) { const char *mountpoint=NULL; int offset = 0; if((!pinfo->fd->visited) && nfs_file_name_snooping){ rpc_call_info_value *civ=(rpc_call_info_value *)data; if(civ->request && (civ->proc==1)){ guint32 len_field; len_field = tvb_get_ntohl(tvb, offset); if (len_field < ITEM_LABEL_LENGTH) { gchar *name, *ptr; int addr_len, name_len; name = address_to_str(wmem_packet_scope(), &pinfo->dst); addr_len = (int)strlen(name); /* IP address, colon, path, terminating 0 */ name_len = addr_len + 1 + len_field + 1; name = (gchar *)wmem_realloc(wmem_packet_scope(), (void *)name, name_len); ptr = name + addr_len; *ptr++ = ':'; tvb_memcpy(tvb, ptr, offset+4, len_field); ptr += len_field; *ptr = 0; nfs_name_snoop_add_name(civ->xid, tvb, -1, name_len, 0, 0, name); } } } offset = dissect_rpc_string(tvb,tree,hf_mount_path,offset,&mountpoint); col_append_fstr(pinfo->cinfo, COL_INFO," %s", mountpoint); return offset; }
static void wmem_array_grow(wmem_array_t *array, const guint to_add) { guint new_alloc_count, new_count; new_alloc_count = array->alloc_count; new_count = array->elem_count + to_add; while (new_alloc_count < new_count) { new_alloc_count *= 2; } if (new_alloc_count == array->alloc_count) { return; } array->buf = (guint8 *)wmem_realloc(array->allocator, array->buf, new_alloc_count * array->elem_size); array->alloc_count = new_alloc_count; }
static void * wmem_block_fast_realloc(void *private_data, void *ptr, const size_t size) { wmem_block_fast_chunk_t *chunk; chunk = WMEM_DATA_TO_CHUNK(ptr); if (chunk->len == JUMBO_MAGIC) { wmem_block_fast_jumbo_t *block; block = ((wmem_block_fast_jumbo_t*)((guint8*)(chunk) - WMEM_JUMBO_HEADER_SIZE)); block = (wmem_block_fast_jumbo_t*)wmem_realloc(NULL, block, size + WMEM_JUMBO_HEADER_SIZE + WMEM_CHUNK_HEADER_SIZE); if (block->prev) { block->prev->next = block; } else { wmem_block_fast_allocator_t *allocator = (wmem_block_fast_allocator_t*) private_data; allocator->jumbo_list = block; } if (block->next) { block->next->prev = block; } return ((void*)((guint8*)(block) + WMEM_JUMBO_HEADER_SIZE + WMEM_CHUNK_HEADER_SIZE)); } else if (chunk->len < size) { /* grow */ void *newptr; /* need to alloc and copy; free is no-op, so don't call it */ newptr = wmem_block_fast_alloc(private_data, size); memcpy(newptr, ptr, chunk->len); return newptr; } /* shrink or same space - great we can do nothing */ return ptr; }
static void wmem_test_allocator(wmem_allocator_type_t type, wmem_verify_func verify, int iterations) { int i; char *ptrs[MAX_SIMULTANEOUS_ALLOCS]; wmem_allocator_t *allocator; allocator = wmem_allocator_force_new(type); if (verify) (*verify)(allocator); /* start with some fairly simple deterministic tests */ wmem_test_allocator_det(allocator, verify, 8); wmem_test_allocator_det(allocator, verify, 64); wmem_test_allocator_det(allocator, verify, 512); for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) { ptrs[i] = wmem_alloc0_array(allocator, char, 32); } if (verify) (*verify)(allocator); wmem_free_all(allocator); wmem_gc(allocator); if (verify) (*verify)(allocator); /* now do some random fuzz-like tests */ /* reset our ptr array */ for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) { ptrs[i] = NULL; } /* Run enough iterations to fill the array 32 times */ for (i=0; i<iterations; i++) { gint ptrs_index; gint new_size; /* returns value 0 <= x < MAX_SIMULTANEOUS_ALLOCS which is a valid * index into ptrs */ ptrs_index = g_test_rand_int_range(0, MAX_SIMULTANEOUS_ALLOCS); if (ptrs[ptrs_index] == NULL) { /* if that index is unused, allocate some random amount of memory * between 0 and MAX_ALLOC_SIZE */ new_size = g_test_rand_int_range(0, MAX_ALLOC_SIZE); ptrs[ptrs_index] = (char *) wmem_alloc0(allocator, new_size); } else if (g_test_rand_bit()) { /* the index is used, and our random bit has determined we will be * reallocating instead of freeing. Do so to some random size * between 0 and MAX_ALLOC_SIZE, then manually zero the * new memory */ new_size = g_test_rand_int_range(0, MAX_ALLOC_SIZE); ptrs[ptrs_index] = (char *) wmem_realloc(allocator, ptrs[ptrs_index], new_size); memset(ptrs[ptrs_index], 0, new_size); } else { /* the index is used, and our random bit has determined we will be * freeing instead of reallocating. Do so and NULL the pointer for * the next iteration. */ wmem_free(allocator, ptrs[ptrs_index]); ptrs[ptrs_index] = NULL; } if (verify) (*verify)(allocator); } wmem_destroy_allocator(allocator); }