bool init(kma_size_t size) { kpage_t* page = get_page(); *((kpage_t**)page->ptr) = page; if (page->size < size + PAGEHEADERSIZE) { // the requested size cannot fit in any page free_page(page); error("init: page size too small for requested size.", ""); return FALSE; } /* initialize central information */ budfls = page->ptr + PAGEHEADERSIZE; budfls->pagesUsed = 1; budfls->firstPagePtr = page->ptr; int i, bufSize = PAGESIZE / 2; for (i = 0; i < MAXBUFCLASS; i++) { (budfls->fl[i]).size = bufSize; (budfls->fl[i]).ptr = NULL; bufSize /= 2; } header_alloc(page->ptr, FIRSTPAGEHEADERSIZE); return TRUE; }
static int header_field_cb(http_parser *p, const char *buf, size_t len) { ssdp_packet_t* pkt = SSDP_PACKET_PTR(p); header_t* hdr = header_alloc(); if (hdr) { strncpy(hdr->field, buf, MIN(sizeof(hdr->field), len)); list_node_t* node = list_node_new(hdr); list_rpush(pkt->headers, node); } return 0; }
void* buddy_alloc(kma_size_t reqSize) { kma_size_t reqBufSize = get_roundup(reqSize); int reqBufClass = get_buf_class(reqBufSize); int bufClass = reqBufClass; void* bufPtr; /* find available buffer on free lists */ while ((budfls->fl[bufClass]).ptr == NULL && bufClass >= 0) { bufClass--; } /* buffer found */ if (bufClass == reqBufClass) { bufPtr = (budfls->fl[bufClass]).ptr; remove_buffer_from_free_list((budfls->fl[bufClass]).ptr, bufClass); update_bitmap(((bufferHeader_t*)bufPtr)->pagePtr, bufPtr, reqBufSize, USED); } else { if (bufClass < 0) { /* no buffer large enough for requested size, need new page */ kpage_t* page = get_page(); *((kpage_t**)page->ptr) = page; budfls->pagesUsed++; header_alloc(page->ptr, PAGEHEADERSIZE); return buddy_alloc(reqSize); } else { /* need to split a larger buffer */ bufPtr = (budfls->fl[bufClass]).ptr; remove_buffer_from_free_list((budfls->fl[bufClass]).ptr, bufClass); get_buffer_from_large_buffer(((bufferHeader_t*)bufPtr)->pagePtr, reqBufSize, (budfls->fl[bufClass]).size, (kma_size_t)(bufPtr - ((bufferHeader_t*)bufPtr)->pagePtr)); update_bitmap(((bufferHeader_t*)bufPtr)->pagePtr, bufPtr, reqBufSize, USED); } } /* update metadata */ ((pageHeader_t*)(((bufferHeader_t*)bufPtr)->pagePtr))->spaceUsed += reqBufSize; return bufPtr; }