void* RingBufferAllocator::alloc(size_t size) { size_t allocSize = ALLOCSIZE(size); // ptrをheadにセット char* ptr = head; // 必要ならばアロケ番地まで進める(JUMP) if (ptr + allocSize > upper + 1){ jumpPoint = ptr; ptr = lower; // JUMP!! } // メタ情報を書き込み *(long long *)IDADDR(ptr) = nAlloc++; *(size_t *)SIZEADDR(ptr) = size; // 返り値を退避 char* ret = DATAADDR(ptr); // 次のアロケ開始番地まで進める ptr += allocSize; // head更新 head = ptr; return (void*) ret; }
bool RingBufferAllocator::canAlloc(size_t size){ size_t allocSize = ALLOCSIZE(size); bool ret = true; if(head - tail >= 0) { if (head + allocSize > upper + 1) { if (lower + allocSize > tail) { ret = false; } } } else { if (head + allocSize > tail) { ret = false; } } }
tmain() { Obj_t *o, *next; Void_t *huge; size_t hugesz; Vmstat_t sb; ssize_t k, p; srandom(0); hugesz = Z_HUGE; /* one huge block to be resized occasionally */ if(!(huge = vmalloc(Vmregion, hugesz)) ) terror("Can't allocate block"); for(k = 0; k < N_OBJ; ++k) { /* free/resize all on this list */ for(o = List[k]; o; o = next) { next = o->next; if((RAND()%2) == 0 ) /* flip a coin to see if freeing */ vmfree(Vmregion, o->obj); else /* resizing */ { o->size = ALLOCSIZE(); if(!(o->obj = vmresize(Vmregion,o->obj,o->size,VM_RSMOVE)) ) terror("Vmresize failed"); TIME(p, k, o->size); /* add to a future list */ o->next = List[p]; List[p] = o; } } if(COMPACT(k)) /* global compaction */ { if(vmstat(Vmregion, &sb) < 0) terror("Vmstat failed"); tinfo("Arena: busy=(%u,%u) free=(%u,%u) extent=%u #segs=%d", sb.n_busy,sb.s_busy, sb.n_free,sb.s_free, sb.extent, sb.n_seg); if(vmcompact(Vmregion) < 0 ) terror("Vmcompact failed"); if(vmstat(Vmregion, &sb) < 0) terror("Vmstat failed"); tinfo("Compact: busy=(%u,%u) free=(%u,%u) extent=%u #segs=%d", sb.n_busy,sb.s_busy, sb.n_free,sb.s_free, sb.extent, sb.n_seg); } if(RESIZE(k)) /* make the huge block bigger */ { hugesz += Z_HUGE; if(!(huge = vmresize(Vmregion, huge, hugesz, VM_RSMOVE)) ) terror("Bad resize of huge block"); } o = Obj+k; /* allocate a new block */ o->size = ALLOCSIZE(); if(!(o->obj = vmalloc(Vmregion, o->size)) ) terror("Vmalloc failed"); TIME(p, k, o->size); o->next = List[p]; List[p] = o; } if(vmdbcheck(Vmregion) < 0) terror("Corrupted region"); if(vmstat(Vmregion, &sb) < 0) terror("Vmstat failed"); tinfo("Full: Busy=(%u,%u) Free=(%u,%u) Extent=%u #segs=%d\n", sb.n_busy, sb.s_busy, sb.n_free, sb.s_free, sb.extent, sb.n_seg); if(vmcompact(Vmregion) < 0 ) terror("Vmcompact failed"); if(vmstat(Vmregion, &sb) < 0) terror("Vmstat failed"); tinfo("Compact: Busy=(%u,%u) Free=(%u,%u) Extent=%u #segs=%d\n", sb.n_busy, sb.s_busy, sb.n_free, sb.s_free, sb.extent, sb.n_seg); /* now free all left-overs */ for(o = List[N_OBJ]; o; o = o->next) vmfree(Vmregion,o->obj); vmfree(Vmregion,huge); if(vmstat(Vmregion, &sb) < 0) terror("Vmstat failed"); tinfo("Free: Busy=(%u,%u) Free=(%u,%u) Extent=%u #segs=%d\n", sb.n_busy, sb.s_busy, sb.n_free, sb.s_free, sb.extent, sb.n_seg); if(vmcompact(Vmregion) < 0 ) terror("Vmcompact failed2"); if(vmstat(Vmregion, &sb) < 0) terror("Vmstat failed"); tinfo("Compact: Busy=(%u,%u) Free=(%u,%u) Extent=%u #segs=%d\n", sb.n_busy, sb.s_busy, sb.n_free, sb.s_free, sb.extent, sb.n_seg); if(!(huge = vmalloc(Vmregion, 10))) terror("Vmalloc failed"); if(vmstat(Vmregion, &sb) < 0) terror("Vmstat failed"); tinfo("Small: Busy=(%u,%u) Free=(%u,%u) Extent=%u #segs=%d\n", sb.n_busy, sb.s_busy, sb.n_free, sb.s_free, sb.extent, sb.n_seg); texit(0); }
/* ** save_project - save project file in the ~/.eda/ directory, ** last used project name can be omitted */ int save_project (const char *projectname) { int ret=0, ri=0, section=0; char projfile[sizeof(cnf.myhome)+SHORTNAME]; FILE *fp=NULL; char *data=NULL; unsigned datasize=0, dlen=0, als=0; char str[CMDLINESIZE]; unsigned len=0, length[3]; if (projectname[0] == '\0' && cnf.project[0] == '\0') { tracemsg("no project name defined"); return (1); } /* access ~/.eda checked in main.c */ strncpy(projfile, cnf.myhome, sizeof(projfile)); if (projectname[0] != '\0') { strncat(projfile, projectname, SHORTNAME-6); } else { strncat(projfile, cnf.project, SHORTNAME-6); } strncat(projfile, ".proj", 6); length[0] = strlen(PROJECT_HEADER); length[1] = strlen(PROJECT_FILES); length[2] = strlen(PROJECT_CHDIR); if ((fp = fopen(projfile, "r")) != NULL) { fseek(fp, 0, SEEK_END); datasize = ftell(fp); als = ALLOCSIZE(datasize+1); if ((data = (char *) MALLOC(als)) == NULL) { ERRLOG(0xE02A); tracemsg ("failed to save project"); fclose(fp); return (-1); } fseek(fp, 0, SEEK_SET); memset(str, 0, sizeof(str)); while (ret==0) { if (fgets (str, sizeof(str)-1, fp) == NULL) { if (ferror(fp)) { ERRLOG(0xE092); ret = 8; } break; } len = strlen(str); if (section == 0) { if (strncmp(str, PROJECT_HEADER, length[0]) == 0) { section = 1; continue; } } else if (section == 1) { if (strncmp(str, PROJECT_FILES, length[1]) == 0) { section = 2; break; /* finished */ } else if (strncmp(str, PROJECT_CHDIR, length[2]) == 0) { continue; } } if (section && len > 1) { strncpy(data+dlen, str, len+1); dlen += len; } } *(data+dlen) = '\0'; fclose(fp); } if ((fp = fopen(projfile, "w")) == NULL) { tracemsg ("cannot write %s project file", projfile); ret = -1; } else { fprintf(fp, "%s\n%s %s\n", PROJECT_HEADER, PROJECT_CHDIR, cnf._pwd); if (dlen > 0) { if (fwrite (data, sizeof(char), dlen, fp) != dlen) { ERRLOG(0xE0A5); ret = 2; } } if (!ret) { fprintf(fp, "\n%s\n", PROJECT_FILES); } memset(str, 0, sizeof(str)); ri = cnf.ring_curr; do { if ((cnf.fdata[ri].fflag & FSTAT_OPEN) && ((cnf.fdata[ri].fflag & (FSTAT_SPECW | FSTAT_SCRATCH)) == 0)) { snprintf(str, sizeof(str)-1, "%s:%d\nfocus=%d\n", cnf.fdata[ri].fname, cnf.fdata[ri].lineno, cnf.fdata[ri].focus); len = strlen(str); if (fwrite (str, sizeof(char), len, fp) != len) { ERRLOG(0xE0A4); ret = 2; break; } } ri = (ri<RINGSIZE-1) ? ri+1 : 0; } while (ri != cnf.ring_curr); fclose(fp); } FREE(data); data = NULL; if (ret==0) { if (projectname[0] != '\0') { strncpy(cnf.project, projectname, sizeof(cnf.project)); cnf.project[sizeof(cnf.project)-1] = '\0'; } tracemsg ("project %s saved", cnf.project); } return (ret); }/* save_project */