/* * mm_insert - Insert a free block into the Binary Tree and return bp */ void *mm_insert(void *root, void* bp) { /* Determine if the tree is empty and initiate all nodes to NULL */ if(root == NULL) { SETLEFT(bp, NULL); SETRIGHT(bp, NULL); return bp; } else if(GETSIZE(bp) <= GETSIZE(root)) { SETLEFT(root, mm_insert(LEFT(root),bp)); return root; } else if(GETSIZE(bp) > GETSIZE(root)) { SETRIGHT(root, mm_insert(RIGHT(root),bp)); return root; } /* If there's an error, return -1 */ return -1; }
void place(char *bp, size_t size) //allocate to block and update free list,split block if necessary //place called after find_fit in MALLOC //size is block including header and footer { ASSERT(GETALLOC(HDRP(bp)) == 0) ; ASSERT(size <= GETSIZE(HDRP(bp))) ; ASSERT(size % ALIGNMENT == 0) ; //bp is empty block size_t bSize = GETSIZE(HDRP(bp)) ; if(bSize - size < MINBLOCKSIZE) { FL_remove(bp) ; PUT(HDRP(bp), PACK(bSize, 1)) ; PUT(FTRP(bp), PACK(bSize, 1)) ; //change header and footer alloc bit } else if(bSize - size >= MINBLOCKSIZE) { ASSERT((bSize-size) % ALIGNMENT == 0) ; // check if new block size will mess up alignment FL_remove(bp) ;//remove bp from free list PUT(HDRP(bp) ,PACK(size, 1)) ; PUT(FTRP(bp), PACK(size,1)) ; ASSERT(isValidBlock(bp)) ; bp = NEXT_BLKP(bp) ; PUT(HDRP(bp) ,PACK(bSize - size, 0)); PUT(FTRP(bp), PACK(bSize-size, 0)) ; ASSERT(isValidBlock(bp)) ; coalesce(bp) ; //insert split block back to free list } dmm_checkheap(278) ; //CHECKHEAP!!!!!!!!!!!!!!!!!!!!! return ; }
char *find_fit(size_t size) //FIXED ISSUE WHERE NULL curr or not enough space during loop //search free list to find first fit //return NULL if no fit found { dmm_checkheap(238) ; ASSERT(validFreeList(firstFBP)) ; dmm_checkheap(240) ; char *curr= firstFBP ; size_t bSize ; /*if(curr == NULL) //curr is empty { curr = extend_heap(size, EXT_INIT) ;//only single block added curr = firstFBP ; // return NULL ; //no free blocks i.e free list empty } */ //ASSERT(GETSIZE(HDRP(firstFBP)) >= size) ; while(curr != heapStart && curr != NULL) //while list not at end { unsigned nSize, pSize ; bSize = GETSIZE(HDRP(curr)) ; if(size <= bSize) { // implement good fit int count = 0; char* best = curr ; if(GETSIZE(HDRP(best)) == size) return best ;// best fit while(count < GOODAMT && curr != heapStart ) { pSize = GETSIZE(HDRP(curr)) ; //get size of prev block curr = (char*)(GET_NEXT(curr)) ; if(curr == heapStart) return best ; nSize = GETSIZE(HDRP(curr)) ; if( (nSize >= size) && (nSize < pSize) ) //nSize is better fit { best = curr ; if(nSize == size) return best ;//best fit achieved } count++ ; } dmm_checkheap(280) ; return best ; } ASSERT(GETALLOC(HDRP(curr)) == 0) ; curr = (char *)(GET_NEXT(curr)) ; } //need more space to alloc mem on heap //ASSERT(GETSIZE(HDRP(curr)) >= size) ; //ASSERT(size%4 == 0) ; //not rounding down of words for extend_heap curr = extend_heap((MAX(size,CHUNKSIZE)/WSIZE), EXT_EXT) ; //either curr NULL or nospace // dbg_printf("NO F*****G SPACE, firstFBPS = %d but size = %d\n",(int)GETSIZE(HDRP(firstFBP)), (int)size); return curr ; // NULL if no space found after search }
void *mm_realloc(void *currblock, size_t size) { void *new_currblock = currblock; size_t new_size = size; int remainder; int extendsize; int block_buffer; if (size == 0) return NULL; if (new_size <= DSIZE) { new_size = 2 * DSIZE; } else { new_size = DSIZE * ((new_size + (DSIZE) + (DSIZE - 1)) / DSIZE); } new_size += 16; block_buffer = GETSIZE(HEADER(currblock)) - new_size; if (block_buffer < 0) { if (!FULL(HEADER(NEXT(currblock))) || !GETSIZE(HEADER(NEXT(currblock)))) { remainder = GETSIZE(HEADER(currblock)) + GETSIZE(HEADER(NEXT(currblock))) - new_size; if (remainder < 0) { extendsize = ((-remainder)>CHUNKSIZE?(-remainder):CHUNKSIZE); if (extend_heap(extendsize) == NULL) return NULL; remainder += extendsize; } deletefree(NEXT(currblock)); CLEARTAG(HEADER(currblock), PACK(new_size + remainder, 1)); // Block header CLEARTAG(FOOTER(currblock), PACK(new_size + remainder, 1)); // Block footer } else { new_currblock = mm_malloc(new_size - DSIZE); line_count--; memmove(new_currblock, currblock,((size)<new_size?(size):new_size)); mm_free(currblock); line_count--; } block_buffer = GETSIZE(HEADER(new_currblock)) - new_size; } if (block_buffer < 2 * 16) SETRTAG(HEADER(NEXT(new_currblock))); line_count++; if (MMCHECK) { mm_check('r', currblock, size); } return new_currblock; }
int hdequalft(char *bp) //ensures header and footer are same { unsigned int *hdr =(unsigned int *)( HDRP(bp)) ; unsigned int *ftr = (unsigned int *)(FTRP(bp)) ; if( hdr != NULL && ftr != NULL && (*hdr != *ftr)) { dbg_printf("hdrS = %x , ftrS = %x \n",GETSIZE(hdr), GETSIZE(ftr)) ; } return ((hdr != NULL && ftr != NULL) && (GETALLOC(hdr) == GETALLOC(ftr)) && ( GETSIZE(hdr) == GETSIZE(ftr))) ; //hdr and ftr have same size and alloc }
/* remove an element from the freelist */ void fl_remove(void* ptr) { void** freelist = (void**)(master->ptr+WSIZE); unsigned int size = GETSIZE(ptr); int idx = log_two(size) - 4; /* void* curr = freelist[idx]; void* prev = NULL; while ((curr- ptr)!=0 && (curr != NULL)) { prev = curr; curr = GET_NEXT(curr); } */ //if (curr == NULL) return; //shouldn't really happen if (GET_NEXT(ptr) != NULL) PUT_PREV(GET_NEXT(ptr),GET_PREV(ptr)); if (GET_PREV(ptr) == NULL) //ptr is the first element { freelist[idx] = GET_NEXT(ptr); } else { PUT_NEXT(GET_PREV(ptr), GET_NEXT(ptr)); } //return; }
static void deletefree(void *currblock) { int listcounter = 0; size_t size = GETSIZE(HEADER(currblock)); for (;(listcounter < LISTS - 1) && (size > 1); listcounter++) { size >>= 1; } if (PREVFREE(currblock) != NULL) { if (NEXTFREE(currblock) != NULL) { SETPTR(NEXTPTR(PREVFREE(currblock)), NEXTFREE(currblock)); SETPTR(PREVPTR(NEXTFREE(currblock)), PREVFREE(currblock)); } else { SETPTR(NEXTPTR(PREVFREE(currblock)), NULL); free_lists[listcounter] = PREVFREE(currblock); } } else { if (NEXTFREE(currblock) != NULL) { SETPTR(PREVPTR(NEXTFREE(currblock)), NULL); } else { free_lists[listcounter] = NULL; } } return; }
/* * mm_ceiling - Locate a node that best fits in a free block and return its pointer */ void * mm_ceiling(void* root, int size) { void* best_fit; /* Retrieve the best fit, check its size and determine if it works */ if(root == NULL) return NULL; int root_size = GETSIZE(root); if(root_size == size) return root; else if(root_size > size) best_fit = mm_ceiling(LEFT(root), size); else if (root_size < size) best_fit = mm_ceiling(RIGHT(root), size); /* Determine size of child and see if the node is a good fit */ if(best_fit == NULL) { if(root_size < size) /* If it's too small, return NULL */ return NULL; else return root; } else return best_fit; }
static char *coalesce(char *bp) { ASSERT(bp != NULL) ; size_t prev_alloc = GETALLOC(FTRP(PREV_BLKP(bp))); size_t next_alloc = GETALLOC(HDRP(NEXT_BLKP(bp))); size_t size = GETSIZE(HDRP(bp)); if (prev_alloc && next_alloc) { /* Case 1 */ FL_insert(bp) ; } else if (prev_alloc && !next_alloc) { /* Case 2 , bottom free*/ FL_remove((char*)(NEXT_BLKP(bp))) ; //remove next block from free list size += GETSIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(bp), PACK(size, 0)); PUT(FTRP(bp), PACK(size,0)); FL_insert((char*)bp) ; // insert new block into free list } else if (!prev_alloc && next_alloc) { /* Case 3 */ //prev is free, next is alloc FL_remove((char*)(PREV_BLKP(bp))) ; // remove prev block from free list size += GETSIZE(HDRP(PREV_BLKP(bp))); PUT(FTRP(bp), PACK(size, 0)); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); FL_insert((char*)bp) ; // add new block to free list } else { /* Case 4 */ //remove both top and bottom from free list FL_remove((char*)(PREV_BLKP(bp))) ; FL_remove((char*)(NEXT_BLKP(bp))) ; size += GETSIZE(HDRP(PREV_BLKP(bp))) + GETSIZE(HDRP(NEXT_BLKP(bp))); PUT(HDRP(PREV_BLKP(bp)), PACK(size, 0)); PUT(FTRP(NEXT_BLKP(bp)), PACK(size, 0)); bp = PREV_BLKP(bp); FL_insert((char*)bp) ; // insert modified block back } ASSERT(bp == firstFBP) ; return (char*)bp ; }
int GLsetwidgetattr (Gwidget_t *widget, int attrn, Gwattr_t *attrp) { PIXsize_t ps; int ai; XColor c; int color; RESETARGS; for (ai = 0; ai < attrn; ai++) { switch (attrp[ai].id) { case G_ATTRSIZE: GETSIZE (attrp[ai].u.s, ps, MINLWSIZE); ADD2ARGS (XtNwidth, ps.x); ADD2ARGS (XtNheight, ps.y); break; case G_ATTRBORDERWIDTH: ADD2ARGS (XtNborderWidth, attrp[ai].u.i); break; case G_ATTRTEXT: ADD2ARGS (XtNlabel, attrp[ai].u.t); break; case G_ATTRCOLOR: color = attrp[ai].u.c.index; if (color != 0 && color != 1) { Gerr (POS, G_ERRBADCOLORINDEX, color); return -1; } c.red = attrp[ai].u.c.r * 257; c.green = attrp[ai].u.c.g * 257; c.blue = attrp[ai].u.c.b * 257; if (XAllocColor ( Gdisplay, DefaultColormap (Gdisplay, Gscreenn), &c )) { if (color == 0) ADD2ARGS (XtNbackground, c.pixel); else ADD2ARGS (XtNforeground, c.pixel); } break; case G_ATTRWINDOWID: Gerr (POS, G_ERRCANNOTSETATTR2, "windowid"); return -1; case G_ATTREVENTCB: WLU->func = (Glabelcb) attrp[ai].u.func; break; case G_ATTRUSERDATA: widget->udata = attrp[ai].u.u; break; default: Gerr (POS, G_ERRBADATTRID, attrp[ai].id); return -1; } } XtSetValues (widget->w, argp, argn); return 0; }
int GLcreatewidget ( Gwidget_t *parent, Gwidget_t *widget, int attrn, Gwattr_t *attrp ) { PIXsize_t ps; DWORD wflags; char *s; int ai; if (!parent) { Gerr (POS, G_ERRNOPARENTWIDGET); return -1; } wflags = WS_CHILDWINDOW; WLU->func = NULL; ps.x = ps.y = MINLWSIZE; s = ""; for (ai = 0; ai < attrn; ai++) { switch (attrp[ai].id) { case G_ATTRSIZE: GETSIZE (attrp[ai].u.s, ps, MINLWSIZE); break; case G_ATTRBORDERWIDTH: wflags |= WS_BORDER; break; case G_ATTRTEXT: s = attrp[ai].u.t; break; case G_ATTRWINDOWID: Gerr (POS, G_ERRCANNOTSETATTR1, "windowid"); return -1; case G_ATTREVENTCB: WLU->func = attrp[ai].u.func; break; case G_ATTRUSERDATA: widget->udata = attrp[ai].u.u; break; default: Gerr (POS, G_ERRBADATTRID, attrp[ai].id); return -1; } } Gadjustwrect (parent, &ps); if (!(widget->w = CreateWindow ( "LabelClass", s, wflags, 0, 0, ps.x, ps.y, parent->w, (HMENU) (widget - &Gwidgets[0]), hinstance, NULL ))) { Gerr (POS, G_ERRCANNOTCREATEWIDGET); return -1; } ShowWindow (widget->w, SW_SHOW); UpdateWindow (widget->w); if (parent && parent->type == G_ARRAYWIDGET) Gawinsertchild (parent, widget); return 0; }
int GVcreatewidget ( Gwidget_t *parent, Gwidget_t *widget, int attrn, Gwattr_t *attrp ) { PIXpoint_t po; PIXsize_t ps; DWORD wflags; char *s; int ai; WVU->func = NULL; WVU->closing = FALSE; wflags = WS_OVERLAPPEDWINDOW; s = "LEFTY"; po.x = po.y = CW_USEDEFAULT; ps.x = ps.y = MINVWSIZE; for (ai = 0; ai < attrn; ai++) { switch (attrp[ai].id) { case G_ATTRORIGIN: GETORIGIN (attrp[ai].u.p, po); break; case G_ATTRSIZE: GETSIZE (attrp[ai].u.s, ps, MINVWSIZE); break; case G_ATTRNAME: s = attrp[ai].u.t; break; case G_ATTRZORDER: Gerr (POS, G_ERRCANNOTSETATTR1, "zorder"); return -1; case G_ATTRWINDOWID: Gerr (POS, G_ERRCANNOTSETATTR1, "windowid"); return -1; case G_ATTREVENTCB: WVU->func = attrp[ai].u.func; break; case G_ATTRUSERDATA: widget->udata = attrp[ai].u.u; break; default: Gerr (POS, G_ERRBADATTRID, attrp[ai].id); return -1; } } if (!(widget->w = CreateWindow ( "LeftyClass", s, wflags, po.x, po.y, ps.x, ps.y, (HWND) 0, (HMENU) 0, hinstance, NULL ))) { Gerr (POS, G_ERRCANNOTCREATEWIDGET); return -1; } ShowWindow (widget->w, SW_SHOW); UpdateWindow (widget->w); return 0; }
int isAligned(char *bp) { //checks if bp address is aligned and size is aligned int size = GETSIZE(bp) ; ASSERT(!(size % ALIGNMENT)) ; if((size % ALIGNMENT) != 0) return 0 ; if(GETSIZE(HDRP(bp)) == 0) //at epilogue block { //dbg_printf("isAligned Failed") ; //if((long)bp % ALIGNMENT != WSIZE) dbg_printf("isAligned epillogue \n"); return (((long)bp % ALIGNMENT) == WSIZE) ; //expect epilogue to be 4 byte but not 8 byte aligned } ASSERT((long)bp % ALIGNMENT ==0) ; ASSERT((long)NEXT_BLKP(bp)%ALIGNMENT == 0) ; return (((long)bp % ALIGNMENT) == 0)&&((long)NEXT_BLKP(bp)%ALIGNMENT== 0); //current bp is aligned and next block bp is aligned }
/* add an element to the front of the freelist */ void fl_add(void* ptr) { void** freelist = (void**)(master->ptr + WSIZE); unsigned int size = GETSIZE(ptr); int idx = log_two(size)-4; PUT_PREV(ptr, NULL); PUT_NEXT(ptr,freelist[idx]); if (freelist[idx] != NULL) PUT_PREV(freelist[idx],ptr); freelist[idx] = ptr; //front = new //return; }
/* * mm_parent - Retrieve the parent node of a child node */ void *mm_parent(void *root, void *bp) { if(bp == root) return NULL; if(GETSIZE(bp) <= GETSIZE(root)) { if(LEFT(root) == bp) return root; else return mm_parent(LEFT(root),bp); } else { if(RIGHT(root) == bp) return root; else return mm_parent(RIGHT(root),bp); } }
/* * realloc - you may want to look at mm-naive.c */ void *realloc(void *oldptr, size_t size) { size_t oldsize; char *newptr; /* If size == 0 then this is just free, and we return NULL. */ if(size == 0) { free(oldptr); return 0; } /* If oldptr is NULL, then this is just malloc. */ if(oldptr == NULL) { return malloc(size); } ASSERT(GETALLOC(HDRP(oldptr)) == 1) ; ASSERT(isValidBlock((char*)oldptr)); newptr = (char*)malloc(size); /* If realloc() fails the original block is left untouched */ if(!newptr) { return 0; } /* Copy the old data. */ oldsize = GETSIZE(HDRP(oldptr)) - ALIGNMENT; //remove size of hdr and ftr size = MIN(oldsize, size) ; //ASSERT(GETSIZE(HDRP(newptr)) >= GETSIZE(HDRP(oldptr))) ; char* Oldptr = (char*)oldptr; ASSERT(size < GETSIZE(HDRP(newptr)) ) ; for(size_t i = 0; i < size; i++) { *(newptr +i) = *(Oldptr + i) ; // copy data } /* Free the old block. */ free(oldptr); return newptr; }
int isValidBlock(char *bp) { int size = GETSIZE(HDRP(bp)) ; int validLength = ((bp + size) == (NEXT_BLKP(bp))); // bp + size gives address of next block hdr validLength = validLength && (size >= MINBLOCKSIZE) ; ASSERT(isAligned(bp)) ; ASSERT(hdequalft(bp)) ; ASSERT(validCoalescing(bp)) ; ASSERT(validLength); return isAligned(bp) && hdequalft(bp) && validCoalescing(bp) && validLength; }
void mm_checkheap(int lineno) { #ifdef DEBUG if(prologue == NULL || epilogue == NULL) { dbg_printf("Pro / Ei is NULL at line %d\n", lineno); exit(1) ; } if((GETSIZE(epilogue)) != 0 || (GETALLOC(epilogue)) != 1) { dbg_printf("EPILOGUE not set correctly at line %d\n",lineno) ; dbg_printf("Epilogue Size = %d , Alloc = %d \n",GETSIZE(epilogue),GETALLOC(epilogue)); exit(1) ; } //if epilogue size is not 0 or alloc is not 1 char *proFtr = prologue + (GETSIZE(prologue))/2 ; //prologue should be only hdr and ftr by text book convention if(GETSIZE(prologue) != GETSIZE(proFtr)) { dbg_printf("Prlogue not set correctly at line %d\n",lineno); exit(1); } if(GETALLOC(prologue) != GETALLOC(proFtr)) { dbg_printf("Prologue Alloc not set correctly at line %d\n",lineno); exit(1) ; } char *bp = heapStart + (WSIZE * 4) ; // set to first bp on heap while(1) { if(HDRP(bp) == epilogue) return ; //reached end of heap if(! isValidBlock(bp)) { dbg_printf("Not Valid Block at line %d\n",lineno); exit(1) ; } bp = NEXT_BLKP(bp) ; } return ; #else return ; #endif }
void* kma_coalesce(void* ptr) { unsigned int size = GETSIZE(ptr); /* for debugging use void* base_addr = BASEADDR(ptr); unsigned int offset = (ptr - base_addr)/size; printf("%d", offset); */ int bud = WHERE_BUD(ptr, size); //0 if bud on the right, 1 if bud on the left /* corner condition: size == PAGESIZE */ if (size == PAGESIZE) return ptr; /* find bud location */ void* bud_addr; if (bud) bud_addr = ptr - size; //bud on the left else bud_addr = ptr + size; //bud on the right bool can_coalesce; can_coalesce = (!IF_ALLOC(bud_addr)) && (GETSIZE(ptr) == GETSIZE(bud_addr)); if (!can_coalesce) { //bud allocated - do nothing,simply return, this is great! fl_add(ptr); return ptr; } //we need to coalesce! if (bud) { fl_remove(bud_addr); PUT(bud_addr, PACK(size<<1,0)); //bud on the left, update bud header return kma_coalesce(bud_addr); } fl_remove(bud_addr); PUT(ptr, PACK(size<<1,0)); //bud on the right, update our header return kma_coalesce(ptr); }
void kma_free(void* ptr, kma_size_t size) { void* blk_hdr = ptr - BLKHDR; unsigned int blk_size = GETSIZE(blk_hdr); //read block size PUT(blk_hdr, PACK(blk_size,0)); //set to unallocated void* temp = kma_coalesce(blk_hdr); //coalesce with neighbors //check if necessary to free page if (GETSIZE(temp) == PAGESIZE) { //loop through master page and find the kma_page_t corresponding to this page unsigned int num_page = GET(master->ptr); void* curr = master->ptr + 11*WSIZE; int itr = 1; while ((((*(kma_page_t**)curr)->ptr - temp) != 0) && (itr <= num_page)) { curr = curr + sizeof(kma_page_t*); itr++; } free_page((*(kma_page_t**)curr)); //delete from the list, move all following kma_page_t* one element forward unsigned int k = (curr- master->ptr -WSIZE_11)/sizeof(kma_page_t*); while (k+1 < num_page) { kma_page_t** prev = (kma_page_t**)(master->ptr + WSIZE_11 + k*sizeof(kma_page_t*)); kma_page_t* next_p = *(kma_page_t**)(master->ptr +WSIZE_11 + (k+1)*sizeof(kma_page_t*)); *prev = next_p; k++; } num_page--; PUT(master->ptr,num_page); //decrease page count in master page //if no page in master page, free master page too if (num_page == 0) { free_page(master); master = NULL; } } //return; }
static void *coalesce(void *currblock) { size_t prev_alloc = FULL(HEADER(PREV(currblock))); size_t next_alloc = FULL(HEADER(NEXT(currblock))); size_t size = GETSIZE(HEADER(currblock)); if (prev_alloc && next_alloc) { return currblock; } if (RTAG(HEADER(PREV(currblock)))) prev_alloc = 1; deletefree(currblock); if (prev_alloc && !next_alloc) { deletefree(NEXT(currblock)); size += GETSIZE(HEADER(NEXT(currblock))); PUT(HEADER(currblock), PACK(size, 0)); PUT(FOOTER(currblock), PACK(size, 0)); } else if (!prev_alloc && next_alloc) { deletefree(PREV(currblock)); size += GETSIZE(HEADER(PREV(currblock))); PUT(FOOTER(currblock), PACK(size, 0)); PUT(HEADER(PREV(currblock)), PACK(size, 0)); currblock = PREV(currblock); } else { deletefree(PREV(currblock)); deletefree(NEXT(currblock)); size += GETSIZE(HEADER(PREV(currblock))) + GETSIZE(HEADER(NEXT(currblock))); PUT(HEADER(PREV(currblock)), PACK(size, 0)); PUT(FOOTER(NEXT(currblock)), PACK(size, 0)); currblock = PREV(currblock); } insertfree(currblock, size); return coalesce(currblock); }
int GVsetwidgetattr (Gwidget_t *widget, int attrn, Gwattr_t *attrp) { PIXpoint_t po; PIXsize_t ps; DWORD wflags1, wflags2, wflags3, wflags4; int ai; wflags1 = SWP_NOMOVE | SWP_NOZORDER; wflags2 = SWP_NOSIZE | SWP_NOZORDER; wflags3 = SWP_NOSIZE | SWP_NOMOVE; wflags4 = SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE; for (ai = 0; ai < attrn; ai++) { switch (attrp[ai].id) { case G_ATTRORIGIN: GETORIGIN (attrp[ai].u.p, po); SetWindowPos (widget->w, (HWND) NULL, po.x, po.y, 0, 0, wflags2); break; case G_ATTRSIZE: GETSIZE (attrp[ai].u.s, ps, MINVWSIZE); SetWindowPos (widget->w, (HWND) NULL, 0, 0, ps.x, ps.y, wflags1); break; case G_ATTRNAME: SetWindowText (widget->w, attrp[ai].u.t); return -1; case G_ATTRZORDER: if (strcmp (attrp[ai].u.t, "top") == 0) SetWindowPos (widget->w, (HWND) HWND_TOP, 0, 0, 0, 0, wflags3); else if (strcmp (attrp[ai].u.t, "bottom") == 0) SetWindowPos ( widget->w, (HWND) HWND_BOTTOM, 0, 0, 0, 0, wflags4 ); else { Gerr (POS, G_ERRBADATTRVALUE, attrp[ai].u.t); return -1; } break; case G_ATTRWINDOWID: Gerr (POS, G_ERRCANNOTSETATTR1, "windowid"); return -1; case G_ATTREVENTCB: WVU->func = attrp[ai].u.func; break; case G_ATTRUSERDATA: widget->udata = attrp[ai].u.u; break; default: Gerr (POS, G_ERRBADATTRID, attrp[ai].id); return -1; } } return 0; }
int GLcreatewidget(Gwidget_t * parent, Gwidget_t * widget, int attrn, Gwattr_t * attrp) { PIXsize_t ps; int ai; GdkColor c; int color; if (!parent) { Gerr(POS, G_ERRNOPARENTWIDGET); return -1; } WLU->func = NULL; ps.x = ps.y = MINLWSIZE; for (ai = 0; ai < attrn; ai++) { switch (attrp[ai].id) { case G_ATTRSIZE: GETSIZE(attrp[ai].u.s, ps, MINLWSIZE); break; case G_ATTRBORDERWIDTH: break; case G_ATTRTEXT: break; case G_ATTRCOLOR: color = attrp[ai].u.c.index; if (color != 0 && color != 1) { Gerr(POS, G_ERRBADCOLORINDEX, color); return -1; } break; case G_ATTRWINDOWID: Gerr(POS, G_ERRCANNOTSETATTR1, "windowid"); return -1; case G_ATTREVENTCB: WLU->func = (Glabelcb) attrp[ai].u.func; break; case G_ATTRUSERDATA: widget->udata = attrp[ai].u.u; break; default: Gerr(POS, G_ERRBADATTRID, attrp[ai].id); return -1; } } widget->w = gtk_label_new(NULL); return 0; }
/* * free */ void free (void *ptr) { if(ptr == NULL) return; else if((char*)ptr < (prologue + ALIGNMENT) || (char*)ptr >= epilogue) return ; //pointer out of current heap bounds char *bp = (char*)ptr ; size_t size = GETSIZE(HDRP(bp)) ; if(GETALLOC(HDRP(bp)) == 0) return ; ASSERT(GETALLOC(HDRP(bp)) == 1) ; PUT(HDRP(bp) , PACK(size, 0)) ; PUT(FTRP(bp), PACK(size,0)); coalesce(bp) ; dmm_checkheap(361) ;//CHECKHEAP!!!!!!!!!!!!!!!!!!!!!! return ; }
int GAsetwidgetattr (Gwidget_t *widget, int attrn, Gwattr_t *attrp) { Gwidget_t *parent; PIXsize_t ps; DWORD wflags1; int ai; parent = (widget->pwi == -1) ? NULL : &Gwidgets[widget->pwi]; wflags1 = SWP_NOMOVE | SWP_NOZORDER; for (ai = 0; ai < attrn; ai++) { switch (attrp[ai].id) { case G_ATTRSIZE: GETSIZE (attrp[ai].u.s, ps, MINAWSIZE); /* Gadjustwrect (parent, &ps);*/ SetWindowPos (widget->w, (HWND) NULL, 0, 0, ps.x, ps.y, wflags1); break; case G_ATTRBORDERWIDTH: Gerr (POS, G_ERRCANNOTSETATTR2, "borderwidth"); return -1; case G_ATTRMODE: Gerr (POS, G_ERRCANNOTSETATTR2, "mode"); return -1; case G_ATTRLAYOUT: if (strcmp ("on", attrp[ai].u.t) == 0) Gawsetmode (widget, FALSE); else if (strcmp ("off", attrp[ai].u.t) == 0) Gawsetmode (widget, TRUE); else { Gerr (POS, G_ERRBADATTRVALUE, attrp[ai].u.t); return -1; } break; case G_ATTRWINDOWID: Gerr (POS, G_ERRCANNOTSETATTR2, "windowid"); return -1; case G_ATTRRESIZECB: WAU->func = attrp[ai].u.func; break; case G_ATTRUSERDATA: widget->udata = attrp[ai].u.u; break; default: Gerr (POS, G_ERRBADATTRID, attrp[ai].id); return -1; } } return 0; }
int GTsetwidgetattr(Gwidget_t * widget, int attrn, Gwattr_t * attrp) { PIXsize_t ps; int ai, li; GdkColor c; int color; for (ai = 0; ai < attrn; ai++) { switch (attrp[ai].id) { case G_ATTRSIZE: GETSIZE(attrp[ai].u.s, ps, MINTWSIZE); break; case G_ATTRBORDERWIDTH: break; case G_ATTRTEXT: break; case G_ATTRAPPENDTEXT: break; case G_ATTRMODE: break; case G_ATTRCOLOR: break; case G_ATTRWINDOWID: Gerr(POS, G_ERRCANNOTSETATTR2, "windowid"); return -1; case G_ATTRNEWLINECB: WTU->func = (Gtwnewlinecb) attrp[ai].u.func; break; case G_ATTRUSERDATA: widget->udata = attrp[ai].u.u; break; default: Gerr(POS, G_ERRBADATTRID, attrp[ai].id); return -1; } } return 0; }
int GLsetwidgetattr (Gwidget_t *widget, int attrn, Gwattr_t *attrp) { Gwidget_t *parent; PIXsize_t ps; RECT r; DWORD wflags1; int ai; parent = (widget->pwi == -1) ? NULL : &Gwidgets[widget->pwi]; wflags1 = SWP_NOMOVE | SWP_NOZORDER; for (ai = 0; ai < attrn; ai++) { switch (attrp[ai].id) { case G_ATTRSIZE: GETSIZE (attrp[ai].u.s, ps, MINLWSIZE); Gadjustwrect (parent, &ps); SetWindowPos (widget->w, (HWND) NULL, 0, 0, ps.x, ps.y, wflags1); r.top = r.left = 0; r.bottom = ps.y, r.right = ps.x; InvalidateRect (widget->w, NULL, FALSE); break; case G_ATTRBORDERWIDTH: Gerr (POS, G_ERRCANNOTSETATTR2, "borderwidth"); return -1; case G_ATTRTEXT: SetWindowText (widget->w, attrp[ai].u.t); GetClientRect (widget->w, &r); InvalidateRect (widget->w, &r, TRUE); break; case G_ATTRWINDOWID: Gerr (POS, G_ERRCANNOTSETATTR2, "windowid"); return -1; case G_ATTREVENTCB: attrp[ai].u.func = WLU->func; break; case G_ATTRUSERDATA: widget->udata = attrp[ai].u.u; break; default: Gerr (POS, G_ERRBADATTRID, attrp[ai].id); return -1; } } return 0; }
static void placeblock(void *currblock, size_t asize) { size_t currblock_size = GETSIZE(HEADER(currblock)); size_t remainder = currblock_size - asize; deletefree(currblock); if (remainder >= 16) { PUT(HEADER(currblock), PACK(asize, 1)); PUT(FOOTER(currblock), PACK(asize, 1)); CLEARTAG(HEADER(NEXT(currblock)), PACK(remainder, 0)); CLEARTAG(FOOTER(NEXT(currblock)), PACK(remainder, 0)); insertfree(NEXT(currblock), remainder); } else { PUT(HEADER(currblock), PACK(currblock_size, 1)); PUT(FOOTER(currblock), PACK(currblock_size, 1)); } return; }
void* kma_split(void* ptr, kma_size_t size) { unsigned int blk_size= GETSIZE(ptr); unsigned int half = blk_size >> 1; if (((half - BLKHDR) < size) || (blk_size == MINSIZE)) { // cannot split any more and need to allocate the block; PUT(ptr, PACK(blk_size,1)); return ptr; } // split! PUT(ptr, PACK(half,0)); //update header void* next_half = ptr+half; PUT(next_half, PACK(half,0)); //insert the second header //insert next_half to free list fl_add(next_half); return kma_split(ptr, size); //recurse }
static void insertfree(void *currblock, size_t size) { int listcounter = 0; void *search_currblock = currblock; void *insert_currblock = NULL; for(;(listcounter < LISTS - 1) && (size > 1); listcounter++) { size >>= 1; } search_currblock = free_lists[listcounter]; while ((search_currblock != NULL) && (size > GETSIZE(HEADER(search_currblock)))) { insert_currblock = search_currblock; search_currblock = PREVFREE(search_currblock); } if (search_currblock != NULL) { if (insert_currblock != NULL) { SETPTR(PREVPTR(currblock), search_currblock); SETPTR(NEXTPTR(search_currblock), currblock); SETPTR(NEXTPTR(currblock), insert_currblock); SETPTR(PREVPTR(insert_currblock), currblock); } else { SETPTR(PREVPTR(currblock), search_currblock); SETPTR(NEXTPTR(search_currblock), currblock); SETPTR(NEXTPTR(currblock), NULL); free_lists[listcounter] = currblock; } } else { if (insert_currblock != NULL) { SETPTR(PREVPTR(currblock), NULL); SETPTR(NEXTPTR(currblock), insert_currblock); SETPTR(PREVPTR(insert_currblock), currblock); } else { SETPTR(PREVPTR(currblock), NULL); SETPTR(NEXTPTR(currblock), NULL); free_lists[listcounter] = currblock; } } return; }