//Allocate new word with this tag of this length on this stack with this stackpointer word* allocate(unsigned int tag, unsigned int length, int s[], int sp) { int attempt = 1; do { word* free = freelist; word** prev = &freelist; while (free != 0) { int rest = Length(free[0]) - length; if (rest >= 0) { if (rest == 0) // Exact fit with free block *prev = (word*)free[1]; else if (rest == 1) { // Create orphan (unusable) block *prev = (word*)free[1]; free[length+1] = mkheader(0, rest-1, Blue); } else { // Make previous free block point to rest of this block *prev = &free[length+1]; free[length+1] = mkheader(0, rest-1, Blue); free[length+2] = free[1]; } free[0] = mkheader(tag, length, White); return free; } prev = (word**)&free[1]; free = (word*)free[1]; } // No free space, do a garbage collection and try again if (attempt==1) collect(s, sp); } while (attempt++ == 1); printf("Out of memory\n"); exit(1); }
void sweepPhase() { printf("sweeping ...\n"); word* heapPrev = heap; word* heapPtr = heap; word* next = freelist; while (heapPtr < afterHeap) { switch(Color(heapPtr[0])){ case Black: heapPtr[0] = Paint(heapPtr[0], White); break; case White: heapPtr[0] = Paint(heapPtr[0], Blue); if(freelist == 0){ next = freelist = heapPtr; next[1] = 0; } else if( Color(heapPrev[0]) == Blue){ next[0] = mkheader(0, 1 + Length(heapPtr[0]) + Length(next[0]), Blue); } else{ next[1] = (word*) heapPtr; next = heapPtr; next[1] = 0; } break; } heapPrev = heapPtr; heapPtr = heapPtr + Length(heapPtr[0]) + 1; } }
/** * print the one liner */ int log_oneline(int argc, char *argv[], Conf * conf){ char * logentry; char * header; logentry = strdup(""); header = (char *) xmalloc((STRINGSIZE + 1) * sizeof(char)); header = mkheader(header); DEBUG("Logging a oneliner\n"); int i; for(i = 1; i < argc; i++){ cat(&logentry, argv[i]); cat(&logentry, " "); } DEBUG("header in oneliner:\n%s", header); fprintf(conf->files.logfile, "%s", header); fprintf(conf->files.logfile, "%s\n\n", logentry); free(logentry); free(header); return 0; }
/* Cleans up the heap by adding free blocks to the freelist and changing header colors */ void sweepPhase() { printf("sweeping ...\n"); word* heapPtr = heap; //Go through the heap as long as the heap pointer is less than afterheap, which is a pointer to the last element in the heap while(heapPtr < afterHeap){ int length = Length(heapPtr[0]); switch(Color(heapPtr[0])){ case Black: //If the header is black heapPtr[0] = Paint(heapPtr[0], White); break; case White: //If the header is white if((heapPtr+length) < afterHeap && Color(heap[Length(heapPtr[0])+1]) == White){ //Is the adjacent block's header white? and within the size of the heap? heapPtr[0] = mkheader(0, (length+Length(heapPtr[length+1])+1), Blue); // Make new header joining the two adjacent blocks }else{ //Paint header blue heapPtr[0] = Paint(heapPtr[0], Blue); } //Set first element in the free block to point to freelist //and set freelist to point to the header of the free block heapPtr[1] = (word)freelist; freelist = &heapPtr[0]; break; } //Set heap pointer to next block if(Length(heapPtr[0])!=length){ heapPtr += Length(heapPtr[0]) + 1; }else{ heapPtr += length + 1; } } }
void sweepPhase() { printf("sweeping ...\n"); int blocks = 0, free = 0, orphans = 0, blocksSize = 0, freeSize = 0, largestFree = 0; word* heapPtr = heap; while (heapPtr < afterHeap) { word* nextBlock = heapPtr + Length(heapPtr[0]) + 1; if (Length(heapPtr[0]) > 0) { int color = Color(heapPtr[0]); switch (color) { case White: if((nextBlock <= afterHeap) && (Color(nextBlock[0]) == White)) { heapPtr[0] = mkheader(0, Length(heapPtr[0]) + Length(nextBlock[0]) + 1, Blue); } else { heapPtr[0] = Paint(heapPtr[0], Blue); } heapPtr[1] = freelist; freelist = heapPtr; break; case Black: heapPtr[0] = Paint(heapPtr[0], White); break; } } if (nextBlock > afterHeap) { printf("HEAP ERROR: block at heap[%d] extends beyond heap\n", heapPtr - heap); exit(-1); } heapPtr = nextBlock; } }
void initheap() { heap = (word*)malloc(sizeof(word)*HEAPSIZE); afterHeap = &heap[HEAPSIZE]; // Initially, entire heap is one block on the freelist: heap[0] = mkheader(0, HEAPSIZE-1, Blue); heap[1] = (word)0; freelist = &heap[0]; }
/** * Log the entry. Stop, when empty line is found */ int log_entry(Conf * conf){ char * logentry; char * line; char * header; int byte_read; int bytes_sofar = 0; size_t log_size = sizeof(char) * STRINGSIZE; size_t line_size = sizeof(char) * STRINGSIZE; logentry = (char *) xmalloc(line_size); line = (char *) xmalloc(line_size); header = (char *) xmalloc(line_size); strcpy(logentry, ""); header = mkheader(header); while(true){ byte_read = getline(&line, &line_size, stdin); if(byte_read > 0){ bytes_sofar += byte_read; if(byte_read < log_size){ cat(&logentry, line); } } if(strcmp(line,"\n") == 0){ if(strcmp(logentry, "\n") != 0){ fprintf(conf->files.logfile, "%s", header); fprintf(conf->files.logfile, "%s", logentry); free(line); free(header); free(logentry); return 0; } else { printf("Nothing logged.\n"); free(line); free(header); free(logentry); return 0; } } } // We should not be here free(line); free(header); free(logentry); return 1; }
void parse(void) { ic_ifc *ifc; next(); for(;;){ if(match("interface")) { ifc = interface(); mkheader(stdout,ifc); mkstub(stdout,ifc); } if(match("")) return; die("unexpected token '%s'",token); } }
/* immediatly send back an OK response to request req can be used for short transactions which require no further processing of the app */ int httpd_send_immediate_response(struct REQUEST *req) { time_t now; if (req->body != NULL) { now = time(NULL); req->lbody = strlen(req->body); /* 200 OK */ mkheader(req,200,now); } else { mkerror(req,500,1); } return 0; }
void osdep_cwd( void ) { char buf[FILENAME_MAX+1]; int k; k = GetCurrentDirectory( sizeof(buf), buf ); if (k == 0 || k >= sizeof(buf)) globals[G_RESULT] = FALSE_CONST; else { int nwords = roundup4(k)/4; word *p = alloc_from_heap( (nwords+1)*sizeof(word) ); *p = mkheader( k, BV_HDR ); memcpy( p+1, buf, k ); globals[G_RESULT] = tagptr(p,BVEC_TAG); } }
char * fwcf_pack(char *odata, size_t i, int algo, size_t *dstsz) { int j; size_t k; char *data, *cdata; if (i > 0xFFFFFF) errx(1, "inner size of %lu too large", (unsigned long)i); #ifdef DEBUG fprintf(stderr, "fwcf_pack: algo %02X packing %lu\n", algo, (unsigned long)i); #endif if ((j = compressor_get(algo)->compress(&cdata, odata, i)) == -1) errx(1, "%s compression failed", compressor_get(algo)->name); /* 12 bytes header, padding to 4-byte boundary, 4 bytes trailer */ k = ((j + 19) / 4) * 4; #if DEF_FLASHPART > 0xFFFFFF # error DEF_FLASHPART too large #endif if (k > DEF_FLASHPART) errx(1, "%lu bytes too large for flash partition of %lu KiB", (u_long)k, DEF_FLASHPART / 1024UL); /* padded to size of flash block */ #if (DEF_FLASHBLOCK & 3) # error DEF_FLASHBLOCK must be dword-aligned #endif *dstsz = ((k + (DEF_FLASHBLOCK - 1)) / DEF_FLASHBLOCK) * DEF_FLASHBLOCK; if ((data = malloc(*dstsz)) == NULL) err(1, "malloc"); mkheader(data, *dstsz, k, i, algo); memcpy(data + 12, cdata, j); free(cdata); k = j + 12; while (k & 3) data[k++] = 0; mktrailer(data, k); k += 4; pull_rndata((u_int8_t *)data + k, *dstsz - k); return (data); }
/* queue a OK response for request req */ int httpd_send_response(struct REQUEST *req, fd_sets_t *fds) { time_t now; if (req->body != NULL) { now = time(NULL); req->lbody = strlen(req->body); /* 200 OK */ mkheader(req,200,now); } else { mkerror(req,500,1); } if (req->state == STATE_WRITE_HEADER) { // switch to writing FD_CLR(req->fd, &fds->rset); FD_SET(req->fd, &fds->wset); } return 0; }
//Cleans up the heap by adding free blocks to the freelist and changing header colors void sweepPhase() { printf("sweeping ...\n"); word* heapPtr = heap; //Go through the heap as long as the heap pointer is less than afterheap, which is a pointer to the last element in the heap while(heapPtr < afterHeap){ int length = Length(heapPtr[0]); int len; switch(Color(heapPtr[0])){ case Black: //If the header is black heapPtr[0] = Paint(heapPtr[0], White); break; case White: //If the header is white len = 0; /* Sums up the length of the adjacent free blocks */ while((heapPtr+len) < afterHeap && Color(heapPtr[len])==White){ len+=Length(heapPtr[len]) + 1; //Adds the length of the current block } //Make new header if any adjacent free blocks or else paint the existing header blue if(len>length){ heapPtr[0] = mkheader(0, len-1, Blue); }else{ heapPtr[0] = Paint(heapPtr[0],Blue); } //Set first element in the free block to point to freelist //and set freelist to point to the header of the free block heapPtr[1] = (word)freelist; freelist = &heapPtr[0]; break; } //Set heap pointer to next block if(len>length){ heapPtr += len; }else{ heapPtr += length+1; } } }
void stk_flush( word *globals ) { word *stktop, *stkbot, *first, *prev; word retaddr, codeaddr, codeptr, proc, size; unsigned framecount; assert2( tagof( globals[ G_REG0 ]) == PROC_TAG ); stktop = (word*)globals[ G_STKP ]; stkbot = (word*)globals[ G_STKBOT ]; stack_state.words_flushed += (stkbot-stktop); first = prev = 0; framecount = 0; while (stktop < stkbot) { size = *(stktop+STK_CONTSIZE); retaddr = *(stktop+STK_RETADDR); /* convert header to vector header */ assert2( size % 4 == 0 ); /* size must be words, a fixnum */ assert2( (s_word)size >= 12 ); /* 3-word minimum, and nonnegative */ *(stktop+HC_HEADER) = mkheader( size, VEC_HDR ); /* convert return address */ proc = *(stktop+STK_REG0); if (proc != 0) { assert2( tagof( proc ) == PROC_TAG ); codeptr = *(ptrof( proc )+PROC_CODEPTR); if (tagof( codeptr ) == BVEC_TAG) { codeaddr = (word)ptrof( codeptr ); *(stktop+HC_RETOFFSET) = retaddr-(codeaddr+4); } else { *(stktop+HC_RETOFFSET) = retaddr; } } else { *(stktop+HC_RETOFFSET) = retaddr; } /* chain things together */ if (first == 0) first = stktop; else *(prev+HC_DYNLINK) = (word)tagptr( stktop, VEC_TAG ); prev = stktop; framecount++; size = roundup8( size+4 ); stktop += size / 4; #if 0 annoyingmsg("Flush: %d", size ); #endif } if (prev != 0) *(prev+HC_DYNLINK) = globals[ G_CONT ]; if (first != 0) globals[ G_CONT ] = (word)tagptr( first, VEC_TAG ); globals[ G_STKBOT ] = globals[ G_STKP ]; stack_state.frames_flushed += framecount; }
/* Sweeps the heap and */ void sweepPhase() { printf("sweeping ...\n"); int i; word w; for(i = 0; i < HEAPSIZE; i += Length(w) + 1) // Increase i by the length of the previous block + 1. { w = heap[i]; // The word in the heap. int extra_space; switch(Color(w)) { case White: extra_space = 0; word* next = &heap[i + Length(w) + 1]; // Get next word from heap. // While adjecent blocks are white, put them together. while(Color(*next) == White && next < afterHeap) // While the colour of the next block is white and the next block is still in the heap { // Increase length of free space extra_space += Length(*next) + 1; // Set block header to a junk value *next = Tag(9999); next = &heap[i + extra_space + Length(w) + 1]; } if(extra_space > 0) // If there are more than one white block in succession. { // Set first block to word length + extra length and paint blue heap[i] = mkheader(Tag(w), Length(w) + extra_space, Blue); } else { // Just paint blue heap[i] = Paint(w, Blue); } // Add word to freelist word* wo = (word*) &heap[i]; wo[1] = (int) freelist; freelist = &wo[0]; break; case Black: // Paint black blocks white w = Paint(w, White); break; case Blue: // Ignore blue blocks case Grey: // Should not happen break; default: // Should not happen break; } } }