void * simple_segregated_storage<SizeType>::segregate( void * const block, const size_type sz, const size_type partition_sz, void * const end) { // Get pointer to last valid chunk, preventing overflow on size calculations // The division followed by the multiplication just makes sure that // old == block + partition_sz * i, for some integer i, even if the // block size (sz) is not a multiple of the partition size. char * old = static_cast<char *>(block) + ((sz - partition_sz) / partition_sz) * partition_sz; // Set it to point to the end nextof(old) = end; // Handle border case where sz == partition_sz (i.e., we're handling an array // of 1 element) if (old == block) return block; // Iterate backwards, building a singly-linked list of pointers for (char * iter = old - partition_sz; iter != block; old = iter, iter -= partition_sz) nextof(iter) = old; // Point the first pointer, too nextof(block) = old; return block; }
void init() { int i; ifree = 0; idata = NPTR; for( i=0; i < MAXN-1; i++) nextof(i) = i+1; nextof(i) = NPTR; }
// find element, return the prev node pointer. pointer find_prev(element val) { pointer p = idata; while( p != NPTR ) { if( dataof( nextof(p) ) == val ) return p; p = nextof(p); } return NPTR; }
// insert val to after p pointed node. bool insert_after(pointer p, element val) { if( ifree != NPTR && p != NPTR ) { pointer pn = _alloc(val); nextof(pn) = nextof(p); nextof(p) = pn; return true; } return false; }
void ddval (header *hd) { header *st=hd,*hdd,*hd1,*result; int r,c,cd; hdd=nextof(st); hd1=nextof(hdd); equal_params_3(&hd,&hdd,&hd1); if (error) return; getmatrix(hd,&r,&c,&divx); if (r!=1 || c<1) wrong_arg(); getmatrix(hdd,&r,&cd,&divdif); if (r!=1 || c!=cd) wrong_arg(); degree=c-1; if (isinterval(hd)) result=map1i(iddeval,hd1); else result=map1(rddeval,cddeval,hd1); if (error) return; moveresult(st,result); }
void * simple_segregated_storage<SizeType>::malloc_n(const size_type n, const size_type partition_size) { void * start = &first; void * iter; do { if (nextof(start) == 0) return 0; iter = try_malloc_n(start, n, partition_size); } while (iter == 0); void * const ret = nextof(start); nextof(start) = nextof(iter); return ret; }
// pop front element. void pop_front() { if( idata != NPTR ) { // 将 data list 最前面的节点 移到 free list 上 #if 0 pointer p = idata; idata = nextof(idata); // idata = nextof(idata); nextof(p) = ifree; // SLList[p].next = ifree; ifree = p; #else pointer p = idata; idata = nextof(idata); _free(p); #endif } }
void mbetai (header *hd) { header *result,*st=hd,*hda,*hdb; double x; hda=nextof(hd); hdb=nextof(hda); hd=getvalue(hd); if (error) return; hda=getvalue(hda); if (error) return; hdb=getvalue(hdb); if (error) return; if (hd->type!=s_real || hda->type!=s_real || hdb->type!=s_real) wrong_arg_in("betai"); x=betai(*realof(hd),*realof(hda),*realof(hdb)); if (error) return; result=new_real(x,""); if (error) return; moveresult(st,result); }
void do_forget (void) { char name[16]; header *hd; int r; if (udfon) { output("Cannot forget functions in a function!\n"); error=720; return; } while (1) { scan_space(); scan_name(name); r=xor(name); hd=(header *)ramstart; while ((char *)hd<udfend) { if (r==hd->xor && !strcmp(hd->name,name)) break; hd=nextof(hd); } if ((char *)hd>=udfend) { output1("Function %s not found!\n",name); error=160; return; } kill_udf(name); scan_space(); if (*next!=',') break; else next++; } }
// Same preconditions as 'segregate' // Post: !empty() void add_ordered_block(void * const block, const size_type nsz, const size_type npartition_sz) { // This (slower) version of add_block segregates the // block and merges its free list into our free list // in the proper order // Find where "block" would go in the free list void * const loc = find_prev(block); // Place either at beginning or in middle/end if (loc == 0) add_block(block, nsz, npartition_sz); else nextof(loc) = segregate(block, nsz, npartition_sz, nextof(loc)); }
void mzeros1 (header *hd) { header *st=hd,*hd1,*result; int r,c; double *m,xr,xi; hd1=nextof(hd); hd=getvalue(hd); if (error) return; if (hd->type==s_matrix) { make_complex(st); if (error) return; hd=getvalue(st); if (error) return; } hd1=getvalue(hd1); if (error) return; if (hd1->type==s_real) { xr=*realof(hd1); xi=0; } else if (hd1->type==s_complex) { xr=*realof(hd1); xi=*(realof(hd1)+1); } else { output("Need a starting value!\n"); error=300; return; } if (hd->type!=s_cmatrix || dimsof(hd)->r!=1 || dimsof(hd)->c<2) { output("Need a complex polynomial\n"); error=300; return; } getmatrix(hd,&r,&c,&m); result=new_complex(0,0,""); if (error) return; bauhuber(m,c-1,realof(result),0,xr,xi); moveresult(st,result); }
// pre: !empty() void * malloc() { void * const ret = first; // Increment the "first" pointer to point to the next chunk first = nextof(first); return ret; }
void show() { pointer p = idata; for( ; p != NPTR; p = nextof(p) ) { printf(" %3d ", dataof(p) ); } printf("\n"); }
// push val to end of list. bool push_back(element val) { if( idata == NPTR ) { // 空表,直接写入 idata = _alloc(val); nextof(idata) = NPTR; return true; } if( ifree != NPTR ) { // 非空,先找到最后一个节点 pointer last = idata, np; while( nextof(last) != NPTR ) last = nextof(last); np = _alloc(val); nextof(np) = NPTR; nextof(last) = np; return true; } return false; }
// pre: chunk was previously returned from a malloc() referring to the // same free list // post: !empty() void ordered_free(void * const chunk) { // This (slower) implementation of 'free' places the memory // back in the list in its proper order. // Find where "chunk" goes in the free list void * const loc = find_prev(chunk); // Place either at beginning or in middle/end if (loc == 0) free(chunk); else { nextof(chunk) = nextof(loc); nextof(loc) = chunk; } }
void * simple_segregated_storage<SizeType>::find_prev(void * const ptr) { // Handle border case if (first == 0 || std::greater<void *>()(first, ptr)) return 0; void * iter = first; while (true) { // if we're about to hit the end or // if we've found where "ptr" goes if (nextof(iter) == 0 || std::greater<void *>()(nextof(iter), ptr)) return iter; iter = nextof(iter); } }
void * simple_segregated_storage<SizeType>::try_malloc_n( void * & start, size_type n, const size_type partition_size) { void * iter = nextof(start); while (--n != 0) { void * next = nextof(iter); if (next != static_cast<char *>(iter) + partition_size) { // next == 0 (end-of-list) or non-contiguous chunk found start = iter; return 0; } iter = next; } return iter; }
// push val to front. bool push_front(element val) { pointer tmp, np; if( ifree != NPTR ) { np = _alloc(val); nextof(np) = idata; idata = np; return true; } return false; }
// insert to the position in front of p. bool insert(pointer ptr, element val) { if( ifree == NPTR ) return false; // 没有结点,直接返回 if( ptr == idata ) { // 有一个节点 pointer np = _alloc(val); nextof(np) = idata; idata = np; return true; } else { // 其他情况,先找 ptr 的前驱,再插入 pointer p = idata; while( p != NPTR ) { if( nextof(p) == ptr ) { // find p -- the prev node of ptr. return insert_after(p, val); // insert val after p. } p = nextof(p); } } return false; }
header *searchvar (char *name) /***** searchvar search a local variable, named "name". return 0, if not found. *****/ { int r; header *hd=(header *)startlocal; r=xor(name); while ((char *)hd<endlocal) { if (r==hd->xor && !strcmp(hd->name,name)) return hd; hd=nextof(hd); } if (udfon && searchglobal) { hd=(header *)udfend; while ((char *)hd<startlocal) { if (r==hd->xor && !strcmp(hd->name,name)) return hd; hd=nextof(hd); } } return 0; }
void polyval (header *hd) { header *st=hd,*hd1,*result; int r,c; hd1=nextof(hd); equal_params_2(&hd,&hd1); getmatrix(hd,&r,&c,&polynom); if (r!=1) wrong_arg(); degree=c-1; if (degree<0) wrong_arg(); if (isinterval(hd)) result=map1i(ipeval,hd1); else result=map1(peval,cpeval,hd1); moveresult(st,result); }
object_pool<T, UserAllocator>::~object_pool() { // handle trivial case if (!this->list.valid()) return; details::PODptr<size_type> iter = this->list; details::PODptr<size_type> next = iter; // Start 'freed_iter' at beginning of free list void * freed_iter = this->first; const size_type partition_size = this->alloc_size(); do { // increment next next = next.next(); // delete all contained objects that aren't freed // Iterate 'i' through all chunks in the memory block for (char * i = iter.begin(); i != iter.end(); i += partition_size) { // If this chunk is free if (i == freed_iter) { // Increment freed_iter to point to next in free list freed_iter = nextof(freed_iter); // Continue searching chunks in the memory block continue; } // This chunk is not free (allocated), so call its destructor static_cast<T *>(static_cast<void *>(i))->~T(); // and continue searching chunks in the memory block } // free storage UserAllocator::free(iter.begin()); // increment iter iter = next; } while (iter.valid()); // Make the block list empty so that the inherited destructor doesn't try to // free it again. this->list.invalidate(); }
void do_global (void) { char name[16]; int r; header *hd; while (1) { scan_space(); scan_name(name); r=xor(name); hd=(header *)udfend; if (hd==(header *)startlocal) break; while ((char *)hd<startlocal) { if (r==hd->xor && !strcmp(hd->name,name)) break; hd=nextof(hd); } if ((char *)hd>=startlocal) { output1("Variable %s not found!\n",name); error=160; return; } newram=endlocal; hd=new_reference(hd,name); newram=endlocal=(char *)nextof(hd); scan_space(); if (*next!=',') break; else next++; } }
void mbesselall (header *hdx) { header *st=hdx,*hd=nextof(hdx); double bj,by,bdj,bdy; hd=getvalue(hd); if (error) return; hdx=getvalue(hdx); if (error) return; if (hd->type!=s_real || hdx->type!=s_real) wrong_arg_in("besselall"); bessjy(*realof(hd),*realof(hdx),&bj,&by,&bdj,&bdy); if (error) return; newram=(char *)st; new_real(bj,""); if (error) return; new_real(by,""); if (error) return; new_real(bdj,""); if (error) return; new_real(bdy,""); }
void do_mdump (void) { header *hd; output1("ramstart : 0\nstartlocal : %ld\n",startlocal-ramstart); output1("endlocal : %ld\n",endlocal-ramstart); output1("newram : %ld\n",newram-ramstart); output1("ramend : %ld\n",ramend-ramstart); hd=(header *)ramstart; while ((char *)hd<newram) { output1("%6ld : %16s, ",(char *)hd-ramstart,hd->name); output1("size %6ld ",(long)hd->size); output1("type %d\n",hd->type); hd=nextof(hd); } }
void mopen (header *hd) { header *st=hd,*hd1,*result; if (fa) fclose(fa); hd1=nextof(hd); hd=getvalue(hd); if (error) return; hd1=getvalue(hd1); if (error) return; if (hd->type!=s_string || hd1->type!=s_string) wrong_arg_in("open"); fa=fopen(stringof(hd),stringof(hd1)); if (!fa) { error=1; output("Could not open the file!\n"); return; } result=new_real((double)ferror(fa),""); if (error) return; moveresult(st,result); }
void do_list (void) { header *hd; int lcount=0; output(" *** Builtin functions:\n"); print_builtin(); output(" *** Commands:\n"); print_commands(); output(" *** Your functions:\n"); hd=(header *)ramstart; while ((char *)hd<udfend) { if (hd->type!=s_udf) break; if (lcount+(int)strlen(hd->name)+2>=linelength) { lcount=0; output("\n"); } output1("%s ",hd->name); lcount+=(int)strlen(hd->name)+1; hd=nextof(hd); } output("\n"); }
void do_listvar (void) { header *hd=(header *)startlocal; while (hd<(header *)endlocal) { switch (hd->type) { case s_real : listvar1("Real",hd); break; case s_interval : listvar1("Interval",hd); break; case s_complex : listvar1("Complex",hd); break; case s_string : listvar1("String",hd); break; case s_matrix : listvar2("Real Matrix",hd); break; case s_cmatrix : listvar2("Complex Matrix",hd); break; case s_imatrix : listvar2("Interval Matrix",hd); break; case s_reference : listvar1("Reference",hd); break; case s_submatrix : listvar3("Real Submatrix",hd); break; case s_isubmatrix : listvar3("Interval Submatrix",hd); break; case s_csubmatrix : listvar3("Complex Submatrix",hd); break; default: listvar1("Unknown Type",hd); break; } hd=nextof(hd); if (test_key()==escape) break; } }
void do_trace(void) /**** do_trace toggles tracing or sets the trace bit of a udf. ****/ { header *f; char name[64]; scan_space(); if (!strncmp(next,"off",3)) { trace=0; next+=3; } else if (!strncmp(next,"alloff",6)) { next+=6; f=(header *)ramstart; while ((char *)f<udfend && f->type==s_udf) { f->flags&=~1; f=nextof(f); } trace=0; } else if (!strncmp(next,"on",2)) { trace=1; next+=2; } else if (*next==';' || *next==',' || *next==0) trace=!trace; else { if (*next=='"') next++; scan_name(name); if (error) return; if (*next=='"') next++; f=searchudf(name); if (!f || f->type!=s_udf) { output("Function not found!\n"); error=11021; return; } f->flags^=1; if (f->flags&1) output1("Tracing %s\n",name); else output1("No longer tracing %s\n",name); scan_space(); } if (*next==';' || *next==',') next++; }
// pop back element. void pop_back() { if( idata == NPTR ) return; if( nextof(idata) == NPTR ) { // only 1 node. nextof(idata) = ifree; ifree = idata; idata = NPTR; } else { // 找到最后一个节点 p,以及它的前驱 q. // TODO: find the last node p, and it's perv node q. pointer p = idata, q; while( nextof(p) != NPTR ) { q = p; p = nextof( p ); } // remove *p to free list, update nextof(q) to NPTR. nextof(p) = ifree; ifree = p; nextof(q) = NPTR; } }