/* srun_Monitor() * We use the debug hook to drive the garbage collector. * Although this is a simple and portable interface, it is not a terribly * good idea to run the garbage collector from the debug hook, because: * o The debug hook can only monitor a single abstract machine, whereas * you are likely to have multiple concurrent abstract machines in real * projects. * o To call the garbage collector at a regular interval, monitoring the * DBG_LINE opcode is the best option. However, this debug code will never * be sent when the script was compiled without debug information. * o The debug hook does not consider system load, whereas you would want the * garbage collection to take place especially when the system is not busy. * o The debug hook carries some overhead (though just a little). */ int AMXAPI srun_Monitor(AMX *amx) { static int linecount; switch (amx->dbgcode) { case DBG_INIT: return AMX_ERR_NONE; case DBG_LINE: if (--linecount > 0) return AMX_ERR_NONE; linecount = 100; /* drop through */ case DBG_RETURN: garbagecollect(amx, 1); return AMX_ERR_NONE; default: return AMX_ERR_DEBUG; } /* switch */ }
main(int argc, char *argv[]) { int error; int i,fd; int pagenum,*buf; int *buf1,*buf2; int fd1,fd2; int nowrites; //int stale_file[2][]; if( argc == 3 ) { printf("output The argument supplied are %s, %s\n", argv[1], argv[2]); //char temp[] = *argv[1]; //nowrites = *argv[2]; sscanf(argv[1], "%d", &filesize); sscanf(argv[2], "%d", &nowrites); filesize = filesize*PF_MAX_BUFS; printf("output final The argument supplied are %d, %d\n", filesize, nowrites); } else { printf("One argument expected.\n"); filesize = 2*PF_MAX_BUFS; nowrites = 20; } /* create a few files */ if ((error=PF_CreateFile(FILE1))!= PFE_OK){ PF_PrintError("file1"); exit(1); } printf("file size - %d", filesize); int stale_file1[20000]; for (i=0; i<filesize; i++) { stale_file1[i] = 0; } printf("file1 created\n"); if ((error=PF_CreateFile(FILE2))!= PFE_OK){ PF_PrintError("file2"); exit(1); } int stale_file2[20000]; for (i=0; i<filesize; i++) { stale_file2[i] = 0; } printf("file2 created\n"); /* write to file1 */ writefile(FILE1,stale_file1); /* print it out */ readfile(FILE1,stale_file1); //Sequential Updates reads = 0; writes = 0; erases = 0; if ((fd=PF_OpenFile(FILE1))<0){ PF_PrintError("open file"); exit(1); } pagenum = -1; int temp = 0; printf("\noutput final Sequential Updates\n"); while (temp<nowrites && (error=PF_GetNextPage(fd,&pagenum,&buf))== PFE_OK) //for(i=0; i<nowrites; i++) { i = pagenum; temp++; if ((error=PF_UnfixPage(fd,pagenum,FALSE))!= PFE_OK){ PF_PrintError("unfix"); exit(1); } updatefile(FILE1,stale_file1,i); } printf("reads - %d\n", reads); printf("erases - %d\n", erases); printf("writes - %d\n", writes); garbagecollect(FILE1,stale_file1); printf("output file size - %d\n", filesize); printf("output Number of updates - %d\n", nowrites); printf("output Number of pages in block - %d\n", PAGEINBLOCK); printf("output After garbage collection\n"); printf("output final reads - %d\n", reads); printf("output final erases(in units of blocks) - %d\n", erases/PAGEINBLOCK); printf("output final writes - %d\n", writes); if ((error=PF_CloseFile(fd))!= PFE_OK){ PF_PrintError("close file"); exit(1); } readfile(FILE1, stale_file1); /* write to file2 */ writefile(FILE2,stale_file2); /* print it out */ readfile(FILE2,stale_file2); //Random Updates reads = 0; writes = 0; erases = 0; if ((fd=PF_OpenFile(FILE2))<0){ PF_PrintError("open file"); exit(1); } pagenum = -1; temp = 0; printf("\noutput final Random Updates\n"); while (temp<nowrites && ((error=PF_GetNextPage(fd,&pagenum,&buf))== PFE_OK || error == PFE_EOF) ) //for(i=0; i<nowrites; i++) { if(error == PFE_EOF) { printf("output EOF reached\n"); pagenum = -1; continue; } i = pagenum; if ((error=PF_UnfixPage(fd,pagenum,FALSE))!= PFE_OK){ printf("outputerror - %d\n", error); PF_PrintError("unfix"); exit(1); } int j = rand(); if(j%2 == 0) continue; temp++; //printf("output i : %d", i); //int j = rand() % filesize; updatefile(FILE2,stale_file2,i); if(temp==nowrites/2) { printf("output Before garbage collection1:-\n"); printf("output reads - %d\n", reads); printf("output erases(in units of blocks) - %d\n", erases/PAGEINBLOCK); printf("output writes - %d\n", writes); numpages(FILE2,stale_file2); printf("output total number of pages - %d, stale pages is - %d\n", numtotal,numstale); garbagecollect(FILE2,stale_file2); printf("output After garbage collection1:-\n"); printf("output reads - %d\n", reads); printf("output erases(in units of blocks) - %d\n", erases/PAGEINBLOCK); printf("output writes - %d\n", writes); numpages(FILE2,stale_file2); printf("output total number of pages - %d, stale pages is - %d\n", numtotal,numstale); } } if(error != PFE_OK) { PF_PrintError("output"); } printf("output Before garbage collection2\n"); printf("output reads - %d\n", reads); printf("output erases(in units of blocks) - %d\n", erases/PAGEINBLOCK); printf("output writes - %d\n", writes); numpages(FILE2,stale_file2); printf("output total number of pages - %d, stale pages is - %d\n", numtotal,numstale); garbagecollect(FILE2,stale_file2); printf("output file size - %d\n", filesize); printf("output Number of updates - %d, %d\n", temp, nowrites); printf("output Number of pages in block - %d\n", PAGEINBLOCK); printf("output After garbage collection2\n"); printf("output final reads - %d\n", reads); printf("output final erases(in units of blocks) - %d\n", erases/PAGEINBLOCK); printf("output final writes - %d\n", writes); numpages(FILE2,stale_file2); printf("output total number of pages - %d, stale pages is - %d\n", numtotal,numstale); if ((error=PF_CloseFile(fd))!= PFE_OK){ PF_PrintError("close file"); exit(1); } readfile(FILE2, stale_file2); //readfile(FILE1,stale_file1); //garbagecollect(FILE1,stale_file1); //readfile(FILE1,stale_file1); }
static void * allocpages(int numpgs) { struct pageinfo *prev = NULL; struct pageinfo *freepage = g.freepagelist; void *ptr; FPRINTF((stderr, "allocpages(%d)\n", numpgs)); /* search for pages */ for (; freepage != NULL; (prev = freepage), freepage = freepage->link) if (freepage->count >= numpgs) break; #ifdef DO_GC if (freepage == NULL && g.gc && !g.ingc && g.pagecount <= 0) { garbagecollect(); for (freepage = g.freepagelist; freepage != NULL; (prev = freepage), freepage = freepage->link) if (freepage->count >= numpgs) break; } #endif /* check if any pages were found */ if (freepage == NULL) { if (!expandarena(numpgs)) { FPRINTF((stderr, "allocpages(%d), cannot expand data area\n", numpgs)); return NULL; } for ((prev = NULL), freepage = g.freepagelist; freepage != NULL; (prev = freepage), freepage = freepage->link) if (freepage->count >= numpgs) break; /* everything failed! */ if (freepage == NULL) { FPRINTF((stderr, "allocpages(%d), no block large enough after expand\n", numpgs)); return NULL; } } /* remove pages from freepage list */ if (freepage->count == numpgs) { if (prev == NULL) g.freepagelist = freepage->link; else prev->link = freepage->link; ptr = freepage; } else { #ifdef ALLOCENDPAGES freepage->count -= numpgs; ptr = (char *)freepage + freepage->count * BYTESPERPAGE; #else void *npage; int count; struct pageinfo *link; ptr = freepage; npage = (char *)ptr + numpgs * BYTESPERPAGE; count = freepage->count - numpgs; link = freepage->link; freepage = (struct pageinfo *)npage; freepage->link = link; freepage->count = count; if (prev == NULL) g.freepagelist = freepage; else prev->link = freepage; #endif } g.numfreepages -= numpgs; FPRINTF((stderr, "allocpages(%d), page = %p\n", numpgs, ptr)); return ptr; }