void *mm_alloc(size_t size, int flags) { alloc_block *block; char *p_mem = NULL; int i; if (flags & MEM_FAST) { for (i = 0; i < NUM_MEM_LISTS; i++) { if ((512u << i) < size) continue; p_mem = ExAllocateFromNPagedLookasideList(&mem_lists[i]); break; } } if (p_mem == NULL) /* if memory not allocated, allocate from pool */ { if (flags & MEM_SUCCESS) p_mem = mm_alloc_success(APOOL_TYPE(flags), ALLOC_SIZE(size), '1_cd'); else p_mem = ExAllocatePoolWithTag(APOOL_TYPE(flags), ALLOC_SIZE(size), '1_cd'); if (p_mem == NULL) return NULL; flags &= ~MEM_FAST; } /* memory block must be 16byte aligned */ if (dSZ(p_mem) & (16-1)) p_mem += 8, flags |= MEM_PADDED; /* initialize alloc_block struct */ block = pv(p_mem); block->size = size; block->flags = flags; block->index = i; /* zero memory if needed */ if (flags & MEM_ZEROED) memset(block->data, 0, size); return &block->data; }
static int allocate_buffer(int req_size) { void *b; int size=ALLOC_SIZE(req_size); if (buffer[active_buffer].b == NULL) { if ((buffer[active_buffer].b=pkg_malloc(size))==NULL) return 0; buffer[active_buffer].size=size; buffer[active_buffer].offset=0; return 1; } active_buffer = (active_buffer?active_buffer:MAX_BUFFERS)-1; if (buffer[active_buffer].size >= req_size) { buffer[active_buffer].offset = 0; return 1; } if ((b=pkg_realloc(buffer[active_buffer].b,size))) { buffer[active_buffer].b=b; buffer[active_buffer].size=size; buffer[active_buffer].offset=0; return 1; } return 0; }
void mm_init() { int i; for (i = 0; i < NUM_MEM_LISTS; i++) { ExInitializeNPagedLookasideList(&mem_lists[i], NULL, NULL, 0, ALLOC_SIZE(512u << i), '2_cd', 0); } }
/* ******************************************************************************* * Internal functions ******************************************************************************* */ static void * int_nkn_memalloc_malloc(size_t size, size_t align, nkn_obj_type_t type) { size_t alloc_size; void *ptr; char *data; mem_alloc_hdr_t *mh; mem_slot_queue_t *pslot = NULL; int align_log2; int n; int ispool = MEM_SLOT_GLIB; if (size >= MH_MAX_MEMORY_SIZE || type >= MH_MAX_TYPE_VAL) { assert(0); } if (align) { // Note: align is assumed to be a pwr2 and multiple of sizeof(void*) for (n = 1; (n * align) < sizeof(mem_alloc_hdr_t); n++) ; } else { n = 0; } alloc_size = ALLOC_SIZE(size, (n * align)); if (align) { // compute log2(align) for (align_log2 = CHUNK_SIZE_LOG2; align > (size_t)(1 << align_log2); align_log2++) ; ptr = __libc_memalign(align, alloc_size); } else { align_log2 = 0; ptr = mem_get_memory(0, &alloc_size, &ispool, &pslot); // alloc_size may be // modified } if (ptr) { data = (char *)ptr + (align ? (n * align) : sizeof(mem_alloc_hdr_t)); mh = (mem_alloc_hdr_t *)(data - sizeof(mem_alloc_hdr_t)); mh->magicno = MH_MAGIC; mh->type = type; mh->size_chunk_units = (size_t)(alloc_size >> CHUNK_SIZE_LOG2); if (align_log2 >= MH_MAX_ALIGN_VAL) assert(0); mh->align_log2 = align_log2; mh->align_units = n; mh->flags = ispool; mh->pslot = pslot; // Update stats if (type < nkn_malloc_max_mem_types) { AO_fetch_and_add(obj_type_data[type].cnt, alloc_size); *obj_type_data[type].obj_size = alloc_size; if (ispool) AO_fetch_and_add1(obj_type_data[type].nlib); else { AO_fetch_and_add1(obj_type_data[type].glib); } } return MHDR_TO_MEM(mh); } else { return 0;
void * _malloc( unsigned long n) { struct mem_chunk *p, *q; long sz; extern void *_heapbase; extern short _split_mem; /* add a mem_chunk to required size and round up */ n = n + sizeof(struct mem_chunk); n = (7 + n) & ~7; /* look for first block big enough in free list */ p = &_mchunk_free_list; q = _mchunk_free_list.next; while ((q != NULL) && (q->size < n || q->valid == VAL_BORDER)) { p = q; q = q->next; } /* if not enough memory, get more from the system */ if (q == NULL) { sz = MAXHUNK; q = (struct mem_chunk * )Mxalloc(sz,MX_PREFTTRAM); if (!q) /* can't alloc any more? */ return(NULL); /* Note: q may be below the highest allocated chunk */ p = &_mchunk_free_list; while (p->next != NULL && q > p->next) p = p->next; if (_heapbase == NULL) { q->size = BORDER_EXTRA; sz -= BORDER_EXTRA; q->valid = VAL_BORDER; ALLOC_SIZE (q) = sz; q->next = (struct mem_chunk *) ((long) q + BORDER_EXTRA); q->next->next = p->next; p = p->next = q; q = q->next; } else { q->next = p->next; p->next = q; } q->size = sz; q->valid = VAL_FREE; } if (q->size > n + sizeof(struct mem_chunk)) { /* split, leave part of free list */ q->size -= n; q = (struct mem_chunk * )(((long) q) + q->size); q->size = n; q->valid = VAL_ALLOC; } else { /* just unlink it */ p->next = q->next; q->valid = VAL_ALLOC; } q->next = NULL; q++; /* hand back ptr to after chunk desc */ return((void * )q); }
void free( void *param) { struct mem_chunk *o, *p, *q, *s; struct mem_chunk *r = (struct mem_chunk *) param; /* free(NULL) should do nothing */ if (r == 0) return; /* move back to uncover the mem_chunk */ r--; /* there it is! */ if (r->valid != VAL_ALLOC) return; r->valid = VAL_FREE; /* stick it into free list, preserving ascending address order */ o = NULL; p = &_mchunk_free_list; q = _mchunk_free_list.next; while (q != NULL && q < r) { o = p; p = q; q = q->next; } /* merge after if possible */ s = (struct mem_chunk * )(((long) r) + r->size); if (q != NULL && s >= q && q->valid != VAL_BORDER) { r->size += q->size; q = q->next; s->size = 0; s->next = NULL; } r->next = q; /* merge before if possible, otherwise link it in */ s = (struct mem_chunk * )(((long) p) + p->size); if (s >= r && p != &_mchunk_free_list) /* remember: r may be below &_mchunk_free_list in memory */ { if (p->valid == VAL_BORDER) { if (ALLOC_SIZE (p) == r->size) { o->next = r->next; Mfree (p); } else p->next = r; return; } p->size += r->size; p->next = r->next; r->size = 0; r->next = NULL; s = (struct mem_chunk * )(((long) p) + p->size); if ((!_split_mem) && _heapbase != NULL && s >= (struct mem_chunk *) _heapbase && s < (struct mem_chunk *) ((char *)_heapbase + _stksize)) { _heapbase = (void *) p; _stksize += p->size; o->next = p->next; /* o is always != NULL here */ } else if (o->valid == VAL_BORDER && ALLOC_SIZE (o) == p->size) { q = &_mchunk_free_list; s = q->next; while (s != NULL && s < o) { q = s; s = q->next; } if (s) { q->next = p->next; Mfree (o); } } } else { s = (struct mem_chunk * )(((long) r) + r->size); if ((!_split_mem) && _heapbase != NULL && s >= (struct mem_chunk *) _heapbase && s < (struct mem_chunk *) ((char *)_heapbase + _stksize)) { _heapbase = (void *) r; _stksize += r->size; p->next = r->next; } else p->next = r; } }