void *mm_malloc_nolock(MM *mm, size_t size) {
if (size > 0) {
mm_mem_head *x = NULL;
size_t realsize = (size_t) MM_ALIGN(MM_SIZE(size));
if (realsize <= mm->available) {
/* Search for free bucket */
mm_free_bucket *p = mm->free_list;
mm_free_bucket *q = NULL;
mm_free_bucket *best = NULL;
mm_free_bucket *best_prev = NULL;
while (p != NULL) {
if (p->size == realsize) {
/* Found free bucket with the same size */
if (q == NULL) {
mm->free_list = p->next;
x = (mm_mem_head *)p;
} else {
q->next = p->next;
x = (mm_mem_head *)p;
}
break;
} else if (p->size > realsize && (best == NULL || best->size > p->size)) {
/* Found best bucket (smallest bucket with the grater size) */
best = p;
best_prev = q;
}
q = p;
p = p->next;
}
if (x == NULL && best != NULL) {
if (best->size-realsize < sizeof(mm_free_bucket)) {
realsize = best->size;
x = (mm_mem_head *)best;
if (best_prev == NULL) {
mm->free_list = best->next;
} else {
best_prev->next = best->next;
}
} else {
if (best_prev == NULL) {
mm->free_list = (mm_free_bucket *)((char *)best + realsize);
mm->free_list->size = best->size-realsize;
mm->free_list->next = best->next;
} else {
best_prev->next = (mm_free_bucket *)((char *)best + realsize);
best_prev->next->size = best->size-realsize;
best_prev->next->next = best->next;
}
best->size = realsize;
x = (mm_mem_head *)best;
}
}
if (x != NULL) {
mm->available -= realsize;
}
}
if (x != NULL) {
return HEAD_TO_PTR(x);
}
}
return NULL;
时间:2009-06-13 20:29
来源:chinaunix
作者:hightman
原文链接