void RDMAServerSocket::cm_events() const { eventThread.send([=]() { hydra::util::epoll poll; epoll_event poll_event; poll_event.events = EPOLLIN; poll_event.data.fd = ec->fd; poll.add(ec->fd, &poll_event); while (running) { rdma_cm_event *cm_event = nullptr; int ret = poll.wait(&poll_event, 1, 2000); if (ret) { if (poll_event.data.fd == ec->fd) { check_zero(rdma_get_cm_event(ec.get(), &cm_event)); check_zero(cm_event->status); if (cm_event->event == RDMA_CM_EVENT_CONNECT_REQUEST) { accept(client_t(cm_event->id)); } else if (cm_event->event == RDMA_CM_EVENT_DISCONNECTED) { rdma_disconnect(cm_event->id); } check_zero(rdma_ack_cm_event(cm_event)); } else { log_err() << "Unkown fd " << poll_event.data.fd << " set. Expected " << id->channel->fd; std::terminate(); } } } }); }
void RDMAServerSocket::accept(client_t client_id) const { ibv_qp_init_attr qp_attr = {}; qp_attr.qp_type = IBV_QPT_RC; qp_attr.cap.max_send_wr = 256; qp_attr.cap.max_recv_wr = 0; qp_attr.cap.max_send_sge = 1; qp_attr.cap.max_recv_sge = 0; qp_attr.cap.max_inline_data = 72; qp_attr.recv_cq = cq; qp_attr.send_cq = cq; qp_attr.srq = id->srq; qp_attr.sq_sig_all = 1; check_zero(rdma_create_qp(client_id.get(), NULL, &qp_attr)); check_zero(rdma_accept(client_id.get(), nullptr)); clients([client_id = std::move(client_id)](auto && clients) mutable { auto pos = std::lower_bound(std::begin(clients), std::end(clients), client_id->qp->qp_num, [](const auto &client, const qp_t &qp_num) { return client->qp->qp_num < qp_num; }); clients.insert(pos, std::move(client_id)); }); }
/* * search_ldso(): search for a symbol inside ld.so.1 */ int search_ldso(char *sym) { int addr; void *handle; Link_map *lm; /* open the executable object file */ if ((handle = dlmopen(LM_ID_LDSO, NULL, RTLD_LAZY)) == NULL) { perror("dlopen"); exit(1); } /* get dynamic load information */ if ((dlinfo(handle, RTLD_DI_LINKMAP, &lm)) == -1) { perror("dlinfo"); exit(1); } /* search for the address of the symbol */ if ((addr = (int)dlsym(handle, sym)) == NULL) { fprintf(stderr, "sorry, function %s() not found\n", sym); exit(1); } /* close the executable object file */ dlclose(handle); check_zero(addr - 4, sym); check_zero(addr - 8, sym); /* addr - 8 is the ret before strcpy() */ return(addr); }
static t_nbr *real_reduc(t_nbr *n) { t_nbr *pgcd, *temp, *nom, *denom; if (!((pgcd = my_pgcd(n))->nbr_len == 1 && *pgcd->nbr == *n->base->base)) { nom = alloc_reduc(n, 0); denom = alloc_reduc(n, 1); temp = div_ent_reduc(nom, pgcd); if (n->makefree) free(n->nbr); n->nbr = temp->nbr; n->nbr_len = temp->nbr_len; free(temp->frac); free(temp); free_nbr(nom); temp = div_ent_reduc(denom, pgcd); free(n->frac); n->frac = temp->nbr; n->frac_len = temp->nbr_len; free(temp->frac); free(temp); free_nbr(denom); } free_nbr(pgcd); check_zero(n, 0); check_zero(n, 1); return n; }
/** * Alloc 'bytes' from shader mempool. */ void * _slang_alloc(GLuint bytes) { #if USE_MALLOC_FREE return _mesa_calloc(bytes); #else slang_mempool *pool; GET_CURRENT_CONTEXT(ctx); pool = (slang_mempool *) ctx->Shader.MemPool; if (bytes == 0) bytes = 1; while (pool) { if (pool->Used + bytes <= pool->Size) { /* found room */ void *addr = (void *) (pool->Data + pool->Used); #ifdef DEBUG check_zero((char*) addr, bytes); #endif pool->Used += ROUND_UP(bytes); pool->Largest = MAX2(pool->Largest, bytes); pool->Count++; /*printf("alloc %u Used %u\n", bytes, pool->Used);*/ return addr; } else if (pool->Next) { /* try next block */ pool = pool->Next; } else { /* alloc new pool */ const GLuint sz = MAX2(bytes, pool->Size); pool->Next = _slang_new_mempool(sz); if (!pool->Next) { /* we're _really_ out of memory */ return NULL; } else { pool = pool->Next; pool->Largest = bytes; pool->Count++; pool->Used = ROUND_UP(bytes); #ifdef DEBUG check_zero((char*) pool->Data, bytes); #endif return (void *) pool->Data; } } } return NULL; #endif }
int dio_read(char *filename) { int fd; int r; void *bufptr; if (posix_memalign(&bufptr, 4096, 64*1024)) { perror("cannot malloc aligned memory"); return -1; } while ((fd = open(filename, O_DIRECT|O_RDONLY)) < 0) { } fprintf(stderr, "dio_truncate: child reading file\n"); while (1) { off_t offset; char *bufoff; /* read the file, checking for zeros */ offset = lseek(fd, SEEK_SET, 0); do { r = read(fd, bufptr, 64*1024); if (r > 0) { if ((bufoff = check_zero(bufptr, r))) { fprintf(stderr, "non-zero read at offset %p\n", offset + bufoff); exit(1); } offset += r; } } while (r > 0); } return 0; }
arma_inline typename T1::elem_type SpValProxy<T1>::operator--(const int) { if (val_ptr) { (*val_ptr) -= eT(1); parent.invalidate_cache(); check_zero(); } else { val_ptr = &parent.insert_element(row, col, eT(-1)); } if (val_ptr) // It may have changed to now be 0. { return *(val_ptr) + eT(1); } else { return eT(0); } }
int read_eof(char *filename) { int fd; int i; int r; char buf[4096]; while ((fd = open(filename, O_RDONLY)) < 0) { sleep(1); /* wait for file to be created */ } for (i = 0 ; i < 1000000; i++) { off_t offset; char * bufoff; offset = lseek(fd, SEEK_END, 0); r = read(fd, buf, 4096); if (r > 0) { if ((bufoff = check_zero(buf, r))) { fprintf(stderr, "non-zero read at offset %p\n",offset + bufoff); exit(1); } } } return 0; }
int main(void) { tests_start_mpfr (); if (check_zero ()) { printf ("Error in evaluation at 0\n"); exit (1); } if (check_INF ()) { printf ("Error in evaluation of INF\n"); exit (1); } if (check_NAN ()) { printf ("Error in evaluation of NAN\n"); exit (1); } tests_end_mpfr (); return 0; }
int read_eof(char *filename) { int fd; int i; int r; char buf[4096]; if ((fd = open(filename, O_RDWR)) < 0) { fprintf(stderr, "can't open file %s \n", filename); exit(1); } for (i = 0; i < 100000; i++) { off_t offset; char *bufoff; offset = lseek(fd, 4096, SEEK_END); r = write(fd, "A", 1); offset = lseek(fd, offset - 4096, SEEK_SET); r = read(fd, buf, 4096); if (r > 0) { if ((bufoff = check_zero(buf, r))) { fprintf(stderr, "non-zero read at offset %p\n", offset + bufoff); exit(1); } } } fprintf(stderr, "read_checkzero done\n"); return 0; }
arma_inline SpValProxy<T1>& SpValProxy<T1>::operator*=(const eT rhs) { if (rhs != eT(0)) { if (val_ptr) { // The value already exists and merely needs to be updated. *val_ptr *= rhs; check_zero(); } } else { if (val_ptr) { // Since we are multiplying by zero, the value can be deleted. parent.delete_element(row, col); val_ptr = NULL; } } return *this; }
int main() { int n,i,a[100]; scanf("%d",&n); for (i=0;i<n;i++) scanf("%d",&a[i]); for (i=0;i<n;i++) {check_zero(a[i]);} getch(); return 0; }
RDMAServerSocket::RDMAServerSocket(std::vector<std::string> hosts, const std::string &port, uint32_t max_wr, int cq_entries) : ec(createEventChannel()), id(createCmId(hosts.back(), port, true)), cc(id), cq(id, cc, cq_entries, 1, 0), running(true) { assert(max_wr); check_zero(rdma_migrate_id(id.get(), ec.get())); ibv_srq_init_attr srq_attr = { nullptr, { max_wr, 1, 0 } }; check_zero(rdma_create_srq(id.get(), nullptr, &srq_attr)); log_info() << "Created id " << id.get() << " " << (void *)this; hosts.pop_back(); for (const auto &host : hosts) { ibv_qp_init_attr attr = {}; attr.cap.max_send_wr = 256; attr.cap.max_recv_wr = 0; attr.cap.max_send_sge = 1; attr.cap.max_recv_sge = 0; attr.recv_cq = cq; attr.send_cq = cq; attr.srq = id->srq; attr.cap.max_inline_data = 72; attr.sq_sig_all = 1; auto client_id = createCmId(host, port, true, &attr, id->pd); check_zero(rdma_migrate_id(client_id.get(), ec.get())); ids.push_back(std::move(client_id)); log_info() << srq_attr; } cm_events(); if(id->verbs) { ibv_device_attr attr; check_zero(ibv_query_device(id->verbs, &attr)); log_info() << attr; } }
static void __spin_time_accum(u64 delta, u32 *array) { unsigned index = ilog2(delta); check_zero(); if (index < HISTO_BUCKETS) array[index]++; else array[HISTO_BUCKETS]++; }
va_list search_func_type_spe(va_list a_list, t_list* begin, const char* format, int* pt_count) { if (begin->value[0] == '0') { check_zero(format,pt_count, a_list); id_print_nbr(va_arg(a_list, int)); } else if (begin->value[0] == '.') a_list = check_point(format, a_list, pt_count); return a_list; }
arma_inline SpValProxy<T1>& SpValProxy<T1>::operator%=(const eT rhs) { if (val_ptr) { *val_ptr %= rhs; check_zero(); } return *this; }
arma_inline SpValProxy<T1>& SpValProxy<T1>::operator<<=(const eT rhs) { // Shifting 0 by any amount should do nothing. if (val_ptr) { *val_ptr <<= rhs; check_zero(); } return *this; }
int main (int argc, char *argv[]) { tests_start_mpfr (); check_large (); check_zero (); test_generic (2, 100, 5); tests_end_mpfr (); return 0; }
int check_err(t_a *arg) { if (check_zero(arg) == -1) return (-1); if (check_space(arg) == -1) return (-1); if (check_plus(arg) == -1) return (-1); if (check_diez(arg) == -1) return (-1); if (check_mod(arg) == -1) return (-1); return (0); }
int nbr_cmp(t_nbr *n1, t_nbr *n2, int frac) { int i; int len1, len2; char *nbr1, *nbr2; check_zero(n1, frac); check_zero(n2, frac); nbr1 = frac ? n1->frac : n1->nbr; len1 = frac ? n1->frac_len : n1->nbr_len; nbr2 = frac ? n2->frac : n2->nbr; len2 = frac ? n2->frac_len : n2->nbr_len; if (len1 > len2) return 1; if (len1 < len2) return -1; for (i = 0; i < len1; i++) if (bas(nbr1[i], n1->base) > bas(nbr2[i], n2->base)) return 1; else if (bas(nbr2[i], n2->base) > bas(nbr1[i], n1->base)) return -1; return 0; }
t_nbr *reduc(t_nbr *n) { t_nbr *un; un = alloc_nbr(n->base); un->nbr[0] = n->base->base[1]; un->nbr_len++; if (nbr_cmp(un, n, 1)) { free_nbr(un); return (real_reduc(n)); } check_zero(n, 0); free_nbr(un); return n; }
static void mc_add_stats(const struct mc_buffer *mc) { int i; check_zero(); mc_stats.issued++; mc_stats.hypercalls += mc->mcidx; mc_stats.arg_total += mc->argidx; mc_stats.histo[mc->mcidx]++; for(i = 0; i < mc->mcidx; i++) { unsigned op = mc->entries[i].op; if (op < NHYPERCALLS) mc_stats.histo_hypercalls[op]++; } }
arma_inline SpValProxy<T1>& SpValProxy<T1>::operator--() { if (val_ptr) { (*val_ptr) -= eT(1); check_zero(); } else { val_ptr = &parent.add_element(row, col, eT(-1)); } return *this; }
arma_inline SpValProxy<T1>& SpValProxy<T1>::operator++() { if (val_ptr) { (*val_ptr) += eT(1); parent.invalidate_cache(); check_zero(); } else { val_ptr = &parent.insert_element(row, col, eT(1)); } return *this; }
arma_inline SpValProxy<T1>& SpValProxy<T1>::operator/=(const eT rhs) { if (rhs != eT(0)) // I hope this is true! { if (val_ptr) { *val_ptr /= rhs; parent.invalidate_cache(); check_zero(); } } else { if (val_ptr) { *val_ptr /= rhs; // That is where it gets ugly. // Now check if it's 0. if (*val_ptr == eT(0)) { parent.delete_element(row, col); val_ptr = NULL; } } else { eT val = eT(0) / rhs; // This may vary depending on type and implementation. if (val != eT(0)) { // Ok, now we have to insert it. val_ptr = &parent.insert_element(row, col, val); } } } return *this; }
arma_inline SpValProxy<T1>& SpValProxy<T1>::operator+=(const eT rhs) { if (val_ptr) { // The value already exists and merely needs to be updated. *val_ptr += rhs; check_zero(); } else { if (rhs != eT(0)) { // The value does not exist and must be added. val_ptr = &parent.add_element(row, col, rhs); } } return *this; }
arma_inline SpValProxy<T1>& SpValProxy<T1>::operator-=(const eT rhs) { if (val_ptr) { // The value already exists and merely needs to be updated. *val_ptr -= rhs; parent.invalidate_cache(); check_zero(); } else { if (rhs != eT(0)) { // The value does not exist and must be inserted. val_ptr = &parent.insert_element(row, col, -rhs); } } return *this; }
arma_inline typename T1::elem_type SpValProxy<T1>::operator++(const int) { if (val_ptr) { (*val_ptr) += eT(1); check_zero(); } else { val_ptr = &parent.add_element(row, col, eT(1)); } if (val_ptr) // It may have changed to now be 0. { return *(val_ptr) - eT(1); } else { return eT(0); } }
int read_sparse(char *filename, int filesize) { int fd; int i; int j; int r; char buf[4096]; while ((fd = open(filename, O_RDONLY)) < 0) { sleep(1); /* wait for file to be created */ } for (i = 0 ; i < 100000000; i++) { off_t offset = 0; char *badbuf; if (debug > 1 && (i % 10) == 0) { fprintf(stderr, "child %d, read loop count %d\n", getpid(), i); } lseek(fd, SEEK_SET, 0); for (j = 0; j < filesize+1; j += sizeof(buf)) { r = read(fd, buf, sizeof(buf)); if (r > 0) { if ((badbuf = check_zero(buf, r))) { fprintf(stderr, "non-zero read at offset %ld\n", offset + badbuf - buf); kill(getppid(), SIGTERM); exit(10); } } offset += r; } } return 0; }
int gc_heap(CTXTdeclc int arity, int ifStringGC) { #ifdef GC CPtr p; double begin_marktime, end_marktime, end_slidetime, end_copy_time, begin_stringtime, end_stringtime; size_t marked = 0, marked_dregs = 0, i; int ii; size_t start_heap_size; size_t rnum_in_trieinstr_unif_stk = (trieinstr_unif_stkptr-trieinstr_unif_stk)+1; DECL_GC_PROFILE; garbage_collecting = 1; // flag for profiling that we are gc-ing // printf("start gc(%ld): e:%p,h:%p,hf:%p\n",(long)(cpu_time()*1000),ereg,hreg,hfreg); INIT_GC_PROFILE; if (pflags[GARBAGE_COLLECT] != NO_GC) { num_gc++ ; GC_PROFILE_PRE_REPORT; slide = (pflags[GARBAGE_COLLECT] == SLIDING_GC) | (pflags[GARBAGE_COLLECT] == INDIRECTION_SLIDE_GC); if (fragmentation_only) slide = FALSE; heap_early_reset = ls_early_reset = 0; GC_PROFILE_START_SUMMARY; begin_marktime = cpu_time(); start_heap_size = hreg+1-(CPtr)glstack.low; /* make sure the top choice point heap pointer that might not point into heap, does */ if (hreg == cp_hreg(breg)) { *hreg = makeint(666) ; hreg++; } #ifdef SLG_GC /* same for the freeze heap pointer */ if (hfreg == hreg && hreg == cp_hreg(bfreg)) { *hreg = makeint(66600); hreg++; } #endif /* copy the aregs to the top of the heap - only if sliding */ /* just hope there is enough space */ /* this happens best before the stack_boundaries are computed */ if (slide) { if (delayreg != NULL) { arity++; reg[arity] = (Cell)delayreg; } for (ii = 1; ii <= arity; ii++) { // printf("reg[%d] to heap: %lx\n",ii,(size_t)reg[i]); *hreg = reg[ii]; hreg++; } arity += (int)rnum_in_trieinstr_unif_stk; for (i = 0; i < rnum_in_trieinstr_unif_stk; i++) { // printf("trieinstr_unif_stk[%d] to heap: %lx\n",i,(size_t)trieinstr_unif_stk[i]); *hreg = trieinstr_unif_stk[i]; hreg++; } // printf("extended heap: hreg=%p, arity=%d, rnum_in=%d\n",hreg,arity, rnum_in_trieinstr_unif_stk); #ifdef SLG_GC /* in SLGWAM, copy hfreg to the heap */ // printf("hfreg to heap is %p at %p, rnum_in_trieinstr_unif_stk=%d,arity=%d,delay=%p\n",hfreg,hreg,rnum_in_trieinstr_unif_stk,arity,delayreg); *(hreg++) = (Cell) hfreg; #endif } if (top_of_localstk < hreg) { fprintf(stderr,"stack clobbered: no space for gc_heap\n"); xsb_exit( "stack clobbered"); } gc_strings = ifStringGC; /* default */ gc_strings = should_gc_strings(); // collect strings for any reason? marked = mark_heap(CTXTc arity, &marked_dregs); end_marktime = cpu_time(); if (fragmentation_only) { /* fragmentation is expressed as ratio not-marked/total heap in use this is internal fragmentation only. we print marked and total, so that postprocessing can do what it wants with this info. */ xsb_dbgmsg((LOG_GC, "marked_used_missed(%d,%d,%d,%d).", marked,hreg+1-(CPtr)glstack.low, heap_early_reset,ls_early_reset)); free_marks: #ifdef PRE_IMAGE_TRAIL /* re-tag pre image cells in trail */ for (p = tr_bot; p <= tr_top ; p++ ) { if (tr_pre_marked(p-tr_bot)) { *p = *p | PRE_IMAGE_MARK; tr_clear_pre_mark(p-tr_bot); } } #endif /* get rid of the marking areas - if they exist */ if (heap_marks) { mem_dealloc((heap_marks-1),heap_marks_size,GC_SPACE); heap_marks = NULL; } if (tr_marks) { mem_dealloc(tr_marks,tr_top-tr_bot+1,GC_SPACE); tr_marks = NULL; } if (ls_marks) { mem_dealloc(ls_marks,ls_bot - ls_top + 1,GC_SPACE); ls_marks = NULL; } if (cp_marks) { mem_dealloc(cp_marks,cp_bot - cp_top + 1,GC_SPACE); cp_marks = NULL; } if (slide_buf) { mem_dealloc(slide_buf,(slide_buf_size+1)*sizeof(CPtr),GC_SPACE); slide_buf = NULL; } goto end; } GC_PROFILE_MARK_SUMMARY; /* An attempt to add some gc/expansion policy; ideally this should be user-controlled */ #if (! defined(GC_TEST)) if (marked > ((hreg+1-(CPtr)glstack.low)*mark_threshold)) { GC_PROFILE_QUIT_MSG; if (slide) hreg -= arity; total_time_gc += (double) (end_marktime-begin_marktime); goto free_marks; /* clean-up temp areas and get out of here... */ } #endif total_collected += (start_heap_size - marked); if (slide) { GC_PROFILE_SLIDE_START_TIME; hreg = slide_heap(CTXTc marked) ; #ifdef DEBUG_VERBOSE if (hreg != (heap_bot+marked)) xsb_dbgmsg((LOG_GC, "heap sliding gc - inconsistent hreg")); #endif #ifdef SLG_GC /* copy hfreg back from the heap */ hreg--; hfreg = (CPtr) *hreg; #endif /* copy the aregs from the top of the heap back */ hreg -= arity; hbreg = cp_hreg(breg); p = hreg; arity -= (int)rnum_in_trieinstr_unif_stk; for (ii = 1; ii <= arity; ii++) { reg[ii] = *p++; // printf("heap to reg[%d]: %lx\n",ii,(size_t)reg[i]); } if (delayreg != NULL) delayreg = (CPtr)reg[arity--]; for (i = 0; i < rnum_in_trieinstr_unif_stk; i++) { trieinstr_unif_stk[i] = *p++; // printf("heap to trieinstr_unif_stk[%d]: %lx\n",i,(size_t)trieinstr_unif_stk[i]); } end_slidetime = cpu_time(); total_time_gc += (double) (end_slidetime - begin_marktime); GC_PROFILE_SLIDE_FINAL_SUMMARY; } else { /* else we call the copying collector a la Cheney */ CPtr begin_new_heap, end_new_heap; GC_PROFILE_COPY_START_TIME; begin_new_heap = (CPtr)mem_alloc(marked*sizeof(Cell),GC_SPACE); if (begin_new_heap == NULL) xsb_exit( "copying garbage collection could not allocate new heap"); end_new_heap = begin_new_heap+marked; hreg = copy_heap(CTXTc marked,begin_new_heap,end_new_heap,arity); mem_dealloc(begin_new_heap,marked*sizeof(Cell),GC_SPACE); adapt_hfreg_from_choicepoints(CTXTc hreg); hbreg = cp_hreg(breg); #ifdef SLG_GC hfreg = hreg; #endif end_copy_time = cpu_time(); total_time_gc += (double) (end_copy_time - begin_marktime); GC_PROFILE_COPY_FINAL_SUMMARY; } if (print_on_gc) print_all_stacks(CTXTc arity); /* get rid of the marking areas - if they exist */ if (heap_marks) { check_zero(heap_marks,(heap_top - heap_bot),"heap") ; mem_dealloc((heap_marks-1),heap_marks_size,GC_SPACE) ; /* see its calloc */ heap_marks = NULL ; } if (tr_marks) { check_zero(tr_marks,(tr_top - tr_bot + 1),"tr") ; mem_dealloc(tr_marks,tr_top-tr_bot+1,GC_SPACE) ; tr_marks = NULL ; } if (ls_marks) { check_zero(ls_marks,(ls_bot - ls_top + 1),"ls") ; mem_dealloc(ls_marks,ls_bot - ls_top + 1,GC_SPACE) ; ls_marks = NULL ; } if (cp_marks) { check_zero(cp_marks,(cp_bot - cp_top + 1),"cp") ; mem_dealloc(cp_marks,cp_bot - cp_top + 1,GC_SPACE) ; cp_marks = NULL ; } if (slide_buf) { mem_dealloc(slide_buf,(slide_buf_size+1)*sizeof(CPtr),GC_SPACE); slide_buf = NULL; } #ifdef SAFE_GC p = hreg; while (p < heap_top) *p++ = 0; #endif } /* if (pflags[GARBAGE_COLLECT]) */ #else /* for no-GC, there is no gc, but stack expansion can be done */ #endif #ifdef GC end: /*************** GC STRING-TABLE (already marked from heap) *******************/ #ifndef NO_STRING_GC #ifdef MULTI_THREAD if (flags[NUM_THREADS] == 1) { #endif if (gc_strings && (flags[STRING_GARBAGE_COLLECT] == 1)) { num_sgc++; begin_stringtime = cpu_time(); mark_nonheap_strings(CTXT); free_unused_strings(); // printf("String GC reclaimed: %d bytes\n",beg_string_space_size - pspacesize[STRING_SPACE]); gc_strings = FALSE; end_stringtime = cpu_time(); total_time_gc += end_stringtime - begin_stringtime; } /* update these even if no GC, to avoid too many calls just to gc strings */ last_string_space_size = pspacesize[STRING_SPACE]; last_assert_space_size = pspacesize[ASSERT_SPACE]; force_string_gc = FALSE; #ifdef MULTI_THREAD } #endif #endif /* ndef NO_STRING_GC */ GC_PROFILE_POST_REPORT; garbage_collecting = 0; #endif /* GC */ // printf(" end gc(%ld), hf:%p,h:%p, space=%d\n",(long)(cpu_time()*1000),hfreg,hreg,(pb)top_of_localstk - (pb)top_of_heap); return(TRUE); } /* gc_heap */