Example #1
0
/**
 * extend_heap - Extend the heap by number of bytes adjusted_size.
 *
 * This differs from the example extend_heap function in that the parameter
 * passed is in BYTES rather than WORDS. Constantly converting between the two
 * is confusing and unnecessary.
 *
 * Furthermore, it should be a size already adjusted to fit byte and header
 * alignment. This function merely sets header/footer/successor as needed.
 */
static void *extend_heap(size_t adjusted_size)
{
	char *bp;
	size_t prev_alloc;

	TRACE("Entering extend_heap(adjusted_size=%u)\n", adjusted_size);

	if ((long)(bp = mem_sbrk(adjusted_size)) == -1)
		return NULL;

	/* Initialize free block header/footer and the epilogue header.
		heap_end points to one byte before the next payload, so reading
		the PREVALLOC field of heap_end + 1 will yield the actual prev-alloc
		for the block just before the end of the heap. */
	prev_alloc = GET_PREVALLOC(heap_end + 1);

	/* Free block header */
	PUTW(GET_BLOCKHDR(bp), PACK(adjusted_size, prev_alloc));

	/* Free block header */
	PUTW(GET_BLOCKFTR(bp), PACK(adjusted_size, prev_alloc));

	/* New epilogue header */
	PUTW(GET_BLOCKHDR(GET_NEXTBLOCK(bp)), PACK(0xEA7F00D0, THISALLOC));
	heap_end = mem_heap_hi();

	TRACE("<<<---Leaving extend_heap() with a call to coalesce()\n");
	/* Coalesce if the previous block was free */
	return coalesce(bp); /* coalesce handles adding block to free list */
}
Example #2
0
void DoFixOffs(FIXOFFS *fix)
{
    S32 value,newoffset;

    if(fix) {
        while(fix) {
            value = GetLabelObjectOffset(fix->data, fix->type);
            if(fix->size==FIXOFFS_NEAR) {
                newoffset = (S32)value-fix->org;
                if(newoffset<-128||newoffset>127) {
                    errorf(fix->filename,fix->line,ERR_FIXOFFSNEAR,GetLabelObjectName(fix->data, fix->type));
                } else
                    PUTB(fix->ptr, (U8)newoffset);
            } else if(fix->size==FIXOFFS_FAR) {
                PUTW(fix->ptr, (U16)value);
            } else if(fix->size==FIXOFFS_WORD) {
                PUTW(fix->ptr, (U16)value);
            } else if(fix->size==FIXOFFS_BYTE) {
                PUTB(fix->ptr, (U8)value);
            } else {
                newoffset = AccOpNum(fix->size-FIXOFFS_ARITH, (U16)value);
                PUTB(fix->ptr, (U8)newoffset);
            }
            fix = fix->prev;
        }
    }
}
Example #3
0
/**
 * free_block - Mark block at specified address as free.
 * Payload remains intact until later overwritten.
 */
static void free_block(void *bp, size_t adjusted_size)
{
	size_t size;
	size_t is_prev_alloc;

	TRACE(">>>Entering free_block(bp=0x%X, adjusted_size=%u)\n", (unsigned int)bp, adjusted_size);

	is_prev_alloc = GET_PREVALLOC(bp);
	size = GET_THISSIZE(bp);

	PUTW(GET_BLOCKHDR(bp), PACK(size, is_prev_alloc));
	PUTW(GET_BLOCKFTR(bp), PACK(size, is_prev_alloc));

	TRACE("<<<---Leaving free_block()\n");
}
Example #4
0
/**
 * allocate - Place block, i.e. write header and footer.
 */
static void allocate(void *bp, size_t adjusted_size)
{
	size_t csize = GET_THISSIZE(bp);
	size_t is_prev_alloc = GET_PREVALLOC(bp);

	TRACE(">>>Entering allocate(bp=0x%X, adjusted_size=%u)\n", (unsigned int)bp, adjusted_size);

	/* We will always need to remove tshi block from the free list */
	remove_from_list(bp, calc_list_index(csize));

	/* See if there's room to split this block into two */
	if ((csize - adjusted_size) >= (MIN_SIZE)) {
		PUTW(GET_BLOCKHDR(bp), PACK(adjusted_size, THISALLOC | is_prev_alloc));
		PUTW(GET_BLOCKFTR(bp), PACK(adjusted_size, THISALLOC | is_prev_alloc));

		/* Using the new header info, mark the newly created block as free */
		bp = GET_NEXTBLOCK(bp);
		PUTW(GET_BLOCKHDR(bp), PACK(csize - adjusted_size, PREVALLOC));
		PUTW(GET_BLOCKFTR(bp), PACK(csize - adjusted_size, PREVALLOC));

		/* And add it to the appropriate free list */
		coalesce(bp);
	}
	else {/* If there's not room to create split the block, just extend the
		 	amount to allocated */
		PUTW(GET_BLOCKHDR(bp), PACK(csize, THISALLOC | is_prev_alloc));
		PUTW(GET_BLOCKFTR(bp), PACK(csize, THISALLOC | is_prev_alloc));

		/* Make sure the next block's header has the prevalloc field marked */
		bp = GET_BLOCKHDR(GET_NEXTBLOCK(bp));
		PUTW(bp, GETW(bp) | PREVALLOC);
	}
	TRACE("<<<---Leaving allocate()\n");
}
Example #5
0
/**
 * coalesce - Concatenate adjacent blocks to prevent fragmentation.
 *
 * Should upkeep the free list. Assumes that bp is a free block.
 * Also assumes that bp has not yet been added to a free list.
 */
static void *coalesce(void *bp)
{
	size_t prev_alloc = GET_PREVALLOC(bp);
	size_t next_alloc = GET_NEXTALLOC(bp);
	size_t size = GET_THISSIZE(bp);
	char *next_block = GET_NEXTBLOCK(bp);
	char *prev_block = GET_PREVBLOCK(bp);

	TRACE(">>>Entering coalesce(bp=0x%X)\n", (unsigned int)bp);

	/* Case 1, Both blocks allocated, does not need its own if statement */
	if (prev_alloc && !next_alloc) { /* Case 2: only next_block is free */
		remove_from_list(next_block, calc_list_index(GET_THISSIZE(next_block)));

		/* Only need to update the size field */
		size += GET_SIZE(GET_BLOCKHDR(next_block));

		PUTW(GET_BLOCKHDR(bp), PACK(size, prev_alloc));
		PUTW(GET_BLOCKFTR(bp), PACK(size, prev_alloc));
	}

	else if (!prev_alloc && next_alloc) { /* Case 3: only prev_block is free */
		remove_from_list(prev_block, calc_list_index(GET_THISSIZE(prev_block)));

		/* Need to update the size and prev_alloc field */
		size += GET_THISSIZE(prev_block);
		prev_alloc = GET_PREVALLOC(prev_block);

		PUTW(GET_BLOCKFTR(bp), PACK(size, prev_alloc));
		PUTW(GET_BLOCKHDR(prev_block), PACK(size, prev_alloc));
		bp = prev_block;
	}

	else if (!prev_alloc && !next_alloc) { /* Case 4: Both blocks are free */
		remove_from_list(next_block, calc_list_index(GET_THISSIZE(next_block)));
		remove_from_list(prev_block, calc_list_index(GET_THISSIZE(prev_block)));

		/* Need to update the size and prev_alloc field */
		size += GET_THISSIZE(prev_block) + GET_THISSIZE(next_block);
		prev_alloc = GET_PREVALLOC(prev_block);

		PUTW(GET_BLOCKHDR(GET_PREVBLOCK(bp)), PACK(size, prev_alloc));
		PUTW(GET_BLOCKFTR(GET_NEXTBLOCK(bp)), PACK(size, prev_alloc));
		bp = GET_PREVBLOCK(bp);
	}

	/* coalesce() is always called after a block is marked free
		so it needs to add the block to the appropriate free list */
	add_to_list(bp, calc_list_index(size));
	TRACE("<<<---Leaving coalesce()\n");
	return bp;
}
Example #6
0
/**
 * mm_init - Initialize the malloc package.
 */
int mm_init(void)
{
	TRACE(">>>Entering mm_init()\n");
	mem_init();

	#ifdef DO_MM_CHECK
		/* initialize the ENTIRE heap provided by memlib to 0x00 */
		memset(mem_heap_lo(), 0, MAX_HEAP);
	#endif

	/*Each element in free_lists starts off as the empty head of a linked list*/
	memset(free_lists, (int)NULL, sizeof(free_lists));

	/* Initialize write-once variables */
	PAGE_SIZE = mem_pagesize();
	ADJUSTED_PAGESIZE = ADJUST_BYTESIZE((PAGE_SIZE*2));

	/* Initially allocate 1 page of memory plus room for
		the prologue and epilogue blocks and free block header */
	if((heap_start = mem_sbrk(ADJUSTED_PAGESIZE + (4 * WSIZE))) == NULL)
		return -1;

	heap_end = mem_heap_hi();

	/* Alignment word */
	PUTW(heap_start, 0x8BADF00D);

	/* Prologue header */
	PUTW(heap_start + (1 * WSIZE), PACK(DSIZE, THISALLOC | PREVALLOC));
	PUTW(heap_start + (2 * WSIZE), PACK(DSIZE, THISALLOC | PREVALLOC));

	/* Epilogue header */
	PUTW(heap_start + ADJUSTED_PAGESIZE + 3	* WSIZE, PACK(0xEA7F00D0, THISALLOC));

	/* Setup initial free block */
	PUTW(heap_start + (3 * WSIZE), PACK(ADJUSTED_PAGESIZE, PREVALLOC));
	PUTW((heap_end - WSIZE + 1) - WSIZE, PACK(ADJUSTED_PAGESIZE, PREVALLOC));
	add_to_list(heap_start + (4 * WSIZE), calc_list_index(ADJUSTED_PAGESIZE));

	RUN_MM_CHECK();
	TRACE("<<<---Leaving mm_init()\n");
	return 0;
}
Example #7
0
BOOL FASTCALL comProc_IfLoop(U16 flags, S16 *brackCnt)
{
    BOOL        BRACK=FALSE,FAR_BRANCH=FALSE,FLIPOP;
    S32         start,whilestart,offset;
    BANK        *bank;
    U8          *condPtr,*elsePtr;
    int         index,mode;

    CheckCurBank();

    if((mode=StrInStrint(szTemp,siIffys))!=-1) {

        if(mode==IFMODE_DOWHILE) {  
            bank        = curBank;
            start       = GetBankOffset();
            if(STRCMP(GetNextWord(),"while")) {
                // 'ist der code block!
                GetCode(flags|CF_BRACEOK, brackCnt);
                if(STRCMP(GetNextWord(),"while"))
                    error(ERR_WHILEEXP,szTemp);
            }
        }

        if(GetNextWord()[0]!='(')
            error(ERR_INVCOND,szTemp);
        else {
            GetNextWord();
            BRACK = TRUE;
        }

        USE_DEFS        = FALSE;
        if(!STRCMP(szTemp,"far")) {
            FAR_BRANCH = TRUE;
            GetNextWord();
        } else if(!STRCMP(szTemp,"near")) {
            GetNextWord();
        }

        // parse the "is" "is not" "not" "no", etc.
        FLIPOP = FALSE;
        while((index=StrInStrint(szTemp,siIsNot))!=-1) {
            if(!siIsNot[index].index)
                FLIPOP = !FLIPOP;
            GetNextWord();
        }
                            
        USE_DEFS        = TRUE;
        if(!PRECOMPILING) {   
            if((index=StrInStrint(szTemp,siConditions))==-1) {
                error(ERR_INVALIDCOND,szTemp);
                condPtr = NULL;
            } else {
                if(mode==IFMODE_IF || mode==IFMODE_WHILE)
                    FLIPOP = !FLIPOP;
                index = (FLIPOP)?
                    RelSwapOp(siConditions[index].index):
                    siConditions[index].index;

                if(mode==IFMODE_WHILE)
                    whilestart = GetBankOffset();

                if(FAR_BRANCH) {
                    WriteOpcodeB(RelSwapOp(index),3);
                    WriteOpcode(opJMP_ABS);
                    condPtr = curBank->ptr;
                    WriteCodeW(0);
                } else {
                    condPtr = curBank->ptr+1;
                    WriteOpcodeB(index,0);
                }
            }    
            if(mode!=IFMODE_DOWHILE) {
                bank    = curBank;
                start   = GetBankOffset();
            }
        }
                         
        if(BRACK && GetNextWord()[0]!=')') {
            error(ERR_IFCONDCLOSEEXP,szTemp);
        }
          
        if(mode!=IFMODE_DOWHILE)
            GetCode(flags|CF_BRACEOK|CF_GETNEXTWORD, brackCnt);

        elsePtr = NULL;
        if(!STRCMP(PeekNextWord(),"else")) {
            GetNextWord();
            if(mode!=IFMODE_IF)
                error(ERR_ONLYIFSELSE);
            else {         
                if(!PRECOMPILING)
                    WriteOpcode(opJMP_ABS);
                elsePtr = curBank->ptr;
                if(!PRECOMPILING)
                    WriteCodeW(0);
            }
        }

        if(!PRECOMPILING) {
            if(bank     != curBank)
                error(ERR_FOREVEROUTOFBANK,bank->label,curBank->label);
            else if(condPtr) {
                if(mode==IFMODE_WHILE) {
                    WriteOpcodeW(opJMP_ABS,whilestart);
                }
                if(FAR_BRANCH) {  
                    if(mode==IFMODE_DOWHILE) {
                        PUTW(condPtr,start);
                    } else {
                        PUTW(condPtr,GetBankOffset());
                    }
                } else {
                    offset = mode==IFMODE_DOWHILE?
                        start-GetBankOffset():
                        GetBankOffset()-start;

                    if((offset<-128 || offset>127))
                        error(ERR_BRANCHOUTOFRANGE);
                    else
                        PUTB(condPtr,(U8)offset);
                }
            }
        }
        if(elsePtr) {
            GetCode(flags|CF_BRACEOK|CF_GETNEXTWORD, brackCnt);
            if(!PRECOMPILING)
                PUTW(elsePtr,GetBankOffset());
        }

    } else if(!STRCMP(szTemp,"forever")) {

        bank    = curBank;
        start   = GetBankOffset();

        GetCode(flags|CF_BRACEOK|CF_GETNEXTWORD, brackCnt);

        if(bank != curBank)
            error(ERR_FOREVEROUTOFBANK,bank->label,curBank->label);
        else
            WriteOpcodeW(opJMP_ABS,start);

    } else
        return FALSE;
    return TRUE;
}
Example #8
0
/*******************************************************************
   KF 6/14/90
   write_pixmap_file(display, filename, pm, width, height)
        and
   write_pixmap_file_xy(display, filename, pm, x, y, width, height)
   has been merged into one function.

   INPUT: display dsp, screen s, file name fn to write the file in,
          window id wid where pixmap is,
          upper left corner x, y of original pixmap,
          width and height of pixmap
   OUTPUT: binary file with data
   PURPOSE: write_pixmap_file gets the image structure of the input
          pixmap, convert the image data with the permutation color
          vector, writes the image structure out to filename.

   Note that writing out a Z pixmap is 8x faster than XY pixmap.
   This is because XY writes out each pixel value per plane, thus
   number of bits; Z writes out each pixel, or 8 bits at a time.

   The XY format may have been chosen for a reason -- I don't know.

********************************************************************/
void
write_pixmap_file(Display *dsp, int scr, char  *fn, 
                  Window wid, int x, int y, int width,int height)
{
    XImage *xi;
    FILE *file;
    int *permVector;
    int num;
    int num_colors;

    /* get color map and permutation vector */
    if ((num_colors = makePermVector(dsp, scr,(unsigned long **)&permVector)) < 0) {
        printf("num_colors < 0!!\n");
        exit(-1);
    }

    /* reads image structure in ZPixmap format */
    xi = XGetImage(dsp, wid, x, y, width, height, AllPlanes, ZPixmap);
    file = fopen(fn, "wb");
    if (file == NULL) {
        perror("opening pixmap file for write");
        exit(-1);
    }

#define PUTW(a,b) putw(htonl(a),b)


    PUTW(xi->width, file);
    PUTW(xi->height, file);
    PUTW(xi->xoffset, file);
    PUTW(xi->format, file);
    PUTW(xi->byte_order, file);
    PUTW(xi->bitmap_unit, file);
    PUTW(xi->bitmap_bit_order, file);
    PUTW(xi->bitmap_pad, file);
    PUTW(xi->depth, file);
    PUTW(xi->bytes_per_line, file);
    PUTW(xi->bits_per_pixel, file);
    PUTW(xi->red_mask, file);
    PUTW(xi->green_mask, file);
    PUTW(xi->blue_mask, file);

    num = xi->bytes_per_line * height;  /* total number of pixels in pixmap */

    /* store value from permutation */
    {
        int ii, jj;

        for (ii = 0; ii < width; ii++)
            for (jj = 0; jj < height; jj++) {
                XPutPixel(xi, ii, jj, permVector[(int) XGetPixel(xi, ii, jj)]);
            }
    }
    fwrite(xi->data, 1, num, file);
    fclose(file);
}