int VALID_EDGE(room_rnum x, int y) { if (world[x].dir_option[y] == NULL || TOROOM(x, y) == NOWHERE) return 0; if (track_through_doors == FALSE && IS_CLOSED(x, y)) return 0; if (ROOM_FLAGGED(TOROOM(x, y), ROOM_NOTRACK) || IS_MARKED(TOROOM(x, y))) return 0; return 1; }
static int VALID_EDGE(room_rnum x, int y) { if (world[x].dir_option[y] == NULL || TOROOM(x, y) == NOWHERE) return 0; if (CONFIG_TRACK_T_DOORS == FALSE && IS_CLOSED(x, y)) return 0; if (ROOM_FLAGGED(TOROOM(x, y), ROOM_NOTRACK) || IS_MARKED(TOROOM(x, y))) return 0; return 1; }
int lf_ordlist_remove(struct lf_ordlist *lst, void *value) { struct lf_ordlist_node *right_node, *right_node_next, *left_node; for ( ; ; ) { right_node = search(lst, value, &left_node); if ((right_node == lst->tail) || lst->cmp(right_node->value, value) != 0) { mem_release(lst->fl, right_node); mem_release(lst->fl, left_node); return 0; } right_node_next = mem_safe_read(lst->fl, &NEXT(right_node)); if (!IS_MARKED(right_node_next)) { assert(right_node != lst->tail); if (compare_and_swap(&NEXT(right_node), (intptr_t) right_node_next, (intptr_t) GET_MARKED(right_node_next))) break; } mem_release(lst->fl, right_node_next); mem_release(lst->fl, right_node); mem_release(lst->fl, left_node); } /* if the CAS succeeds, NEXT(left_node) gets our ref to * 'right_node_next' */ assert(left_node != lst->tail); if (!compare_and_swap(&NEXT(left_node), (intptr_t) right_node, (intptr_t) right_node_next)) { mem_release(lst->fl, right_node_next); mem_release(lst->fl, right_node); mem_release(lst->fl, left_node); /* delete it via a search. */ right_node = search(lst, value, &left_node); mem_release(lst->fl, right_node); mem_release(lst->fl, left_node); } else { /* safely deleted. */ mem_release(lst->fl, right_node); /* our ref */ mem_release(lst->fl, right_node); /* NEXT(left_node) ref */ mem_release(lst->fl, left_node); } return 1; }
int vector_gc_children_mark(sObject* self) { int count = 0; int i; for(i=0; i<SVECTOR(self).mCount; i++) { sObject* item = SVECTOR(self).mTable[i]; if(item && IS_MARKED(item) == 0) { SET_MARK(item); count++; count += object_gc_children_mark(item); } } return count; }
int VALID_EDGE(room_rnum x, int y, int edge_range, int through_doors) { if (world[x]->dir_option[y] == NULL || TOROOM(x, y) == NOWHERE) return 0; // Попытка уползти в другую зону if (edge_range == EDGE_ZONE && (world[x]->zone != world[TOROOM(x, y)]->zone)) return 0; if (through_doors == FALSE && IS_CLOSED(x, y)) return 0; if (ROOM_FLAGGED(TOROOM(x, y), ROOM_NOTRACK) || IS_MARKED(TOROOM(x, y))) return 0; return 1; }
int fraser_search_no_cleanup(sl_intset_t *set, skey_t key, sl_node_t **left_list, sl_node_t **right_list) { PARSE_TRY(); int i; sl_node_t *left, *left_next, *right = NULL; left = set->head; for (i = levelmax - 1; i >= 0; i--) { left_next = GET_UNMARKED(left->next[i]); right = left_next; while (1) { if (likely(!IS_MARKED(right->next[i]))) { if (right->key >= key) { break; } left = right; } right = GET_UNMARKED(right->next[i]); } /* if (left_list != NULL) */ /* { */ left_list[i] = left; /* } */ /* if (right_list != NULL) */ /* { */ right_list[i] = right; /* } */ } return (right->key == key); }
sval_t prioritySL_deleteMin(sl_intset_t *set) { sval_t result = 0; sl_node_t *node; PARSE_START_TS(4); node = GET_UNMARKED(set->head->next[0]); while(node->next[0]!=NULL) { if (!IS_MARKED(node->next[node->toplevel-1])) { int my_delete = mark_node_ptrs(node); if (my_delete) { result = node->val; fraser_search(set, node->key, NULL, NULL); break; } } node = GET_UNMARKED(node->next[0]); } PARSE_END_TS(4, lat_parsing_cleaner++); return result; }
void minor_sweep_phase_young() { int size, perc; int reclaiming = 0; int alive = 0; old_bytes_in_young_blocks_since_last_major = 0; for(size=MIN_TERM_SIZE; size<MAX_TERM_SIZE; size++) { Block *prev_block = NULL; Block *next_block; ATerm old_freelist; Block *block = at_blocks[size]; header_type *end = top_at_blocks[size]; /* empty the freelist*/ at_freelist[size] = NULL; while(block) { /* set empty = 0 to avoid recycling*/ int empty = 1; int alive_in_block = 0; int dead_in_block = 0; int free_in_block = 0; int old_in_block = 0; int capacity = (end-(block->data))/size; header_type *cur; assert(block->size == size); old_freelist = at_freelist[size]; for(cur=block->data ; cur<end ; cur+=size) { ATerm t = (ATerm)cur; if(IS_MARKED(t->header) || IS_OLD(t->header)) { if(IS_OLD(t->header)) { old_in_block++; } CLR_MARK(t->header); alive_in_block++; empty = 0; assert(!IS_MARKED(t->header)); } else { switch(ATgetType(t)) { case AT_FREE: /* AT_freelist[size] is not empty: so DO NOT ADD t*/ t->aterm.next = at_freelist[size]; at_freelist[size] = t; free_in_block++; break; case AT_INT: case AT_REAL: case AT_APPL: case AT_LIST: case AT_PLACEHOLDER: case AT_BLOB: AT_freeTerm(size, t); t->header = FREE_HEADER; t->aterm.next = at_freelist[size]; at_freelist[size] = t; dead_in_block++; break; case AT_SYMBOL: AT_freeSymbol((SymEntry)t); t->header = FREE_HEADER; t->aterm.next = at_freelist[size]; at_freelist[size] = t; dead_in_block++; break; default: ATabort("panic in sweep phase\n"); } assert(!IS_MARKED(t->header)); } } assert(alive_in_block + dead_in_block + free_in_block == capacity); next_block = block->next_by_size; #ifndef NDEBUG if(empty) { for(cur=block->data; cur<end; cur+=size) { assert(ATgetType((ATerm)cur) == AT_FREE); } } #endif /* Do not reclaim frozen blocks */ if(IS_FROZEN(block)) { at_freelist[size] = old_freelist; } /* TODO: create freeList Old*/ if(0 && empty) { at_freelist[size] = old_freelist; reclaim_empty_block(at_blocks, size, block, prev_block); } else if(0 && 100*old_in_block/capacity >= TO_OLD_RATIO) { promote_block_to_old(size, block, prev_block); } else { old_bytes_in_young_blocks_since_last_major += (old_in_block*SIZE_TO_BYTES(size)); prev_block = block; } block = next_block; if(block) { end = block->end; } alive += alive_in_block; reclaiming += dead_in_block; } #ifndef NDEBUG if(at_freelist[size]) { ATerm data; /*fprintf(stderr,"minor_sweep_phase_young: ensure empty freelist[%d]\n",size);*/ for(data = at_freelist[size] ; data ; data=data->aterm.next) { if(!EQUAL_HEADER(data->header,FREE_HEADER)) { fprintf(stderr,"data = %p header = %x\n",data,(unsigned int) data->header); } assert(EQUAL_HEADER(data->header,FREE_HEADER)); assert(ATgetType(data) == AT_FREE); } } #endif } if(alive) { perc = (100*reclaiming)/alive; STATS(reclaim_perc, perc); } }
void major_sweep_phase_young() { int perc; int reclaiming = 0; int alive = 0; int size; old_bytes_in_young_blocks_since_last_major = 0; for(size=MIN_TERM_SIZE; size<MAX_TERM_SIZE; size++) { Block *prev_block = NULL; Block *next_block; ATerm old_freelist; Block *block = at_blocks[size]; header_type *end = top_at_blocks[size]; while(block) { int empty = 1; int alive_in_block = 0; int dead_in_block = 0; int free_in_block = 0; int old_in_block = 0; int young_in_block = 0; int capacity = (end-(block->data))/size; header_type *cur; assert(block->size == size); old_freelist = at_freelist[size]; for(cur=block->data ; cur<end ; cur+=size) { ATerm t = (ATerm)cur; if(IS_MARKED(t->header)) { CLR_MARK(t->header); alive_in_block++; empty = 0; if(IS_OLD(t->header)) { old_in_block++; } else { young_in_block++; } } else { switch(ATgetType(t)) { case AT_FREE: t->aterm.next = at_freelist[size]; at_freelist[size] = t; free_in_block++; break; case AT_INT: case AT_REAL: case AT_APPL: case AT_LIST: case AT_PLACEHOLDER: case AT_BLOB: AT_freeTerm(size, t); t->header = FREE_HEADER; t->aterm.next = at_freelist[size]; at_freelist[size] = t; dead_in_block++; break; case AT_SYMBOL: AT_freeSymbol((SymEntry)t); t->header = FREE_HEADER; t->aterm.next = at_freelist[size]; at_freelist[size] = t; dead_in_block++; break; default: ATabort("panic in sweep phase\n"); } } } assert(alive_in_block + dead_in_block + free_in_block == capacity); next_block = block->next_by_size; #ifndef NDEBUG if(empty) { for(cur=block->data; cur<end; cur+=size) { assert(ATgetType((ATerm)cur) == AT_FREE); } } #endif #ifdef GC_VERBOSE /*fprintf(stderr,"old_cell_in_young_block ratio = %d\n",100*old_in_block/capacity);*/ #endif if(end==block->end && empty) { #ifdef GC_VERBOSE fprintf(stderr,"MAJOR YOUNG: reclaim empty block %p\n",block); #endif at_freelist[size] = old_freelist; reclaim_empty_block(at_blocks, size, block, prev_block); } else if(end==block->end && 100*old_in_block/capacity >= TO_OLD_RATIO) { if(young_in_block == 0) { #ifdef GC_VERBOSE fprintf(stderr,"MAJOR YOUNG: promote block %p to old\n",block); #endif at_freelist[size] = old_freelist; promote_block_to_old(size, block, prev_block); old_bytes_in_old_blocks_after_last_major += (old_in_block*SIZE_TO_BYTES(size)); } else { #ifdef GC_VERBOSE fprintf(stderr,"MAJOR YOUNG: freeze block %p\n",block); #endif SET_FROZEN(block); old_bytes_in_young_blocks_after_last_major += (old_in_block*SIZE_TO_BYTES(size)); at_freelist[size] = old_freelist; prev_block = block; } } else { old_bytes_in_young_blocks_after_last_major += (old_in_block*SIZE_TO_BYTES(size)); prev_block = block; } block = next_block; if(block) { end = block->end; } alive += alive_in_block; reclaiming += dead_in_block; } #ifndef NDEBUG if(at_freelist[size]) { ATerm data; for(data = at_freelist[size] ; data ; data=data->aterm.next) { assert(EQUAL_HEADER(data->header,FREE_HEADER)); assert(ATgetType(data) == AT_FREE); } } #endif } if(alive) { perc = (100*reclaiming)/alive; STATS(reclaim_perc, perc); } }
void major_sweep_phase_old() { int size, perc; int reclaiming = 0; int alive = 0; for(size=MIN_TERM_SIZE; size<MAX_TERM_SIZE; size++) { Block *prev_block = NULL; Block *next_block; Block *block = at_old_blocks[size]; while(block) { /* set empty = 0 to avoid recycling*/ int empty = 1; int alive_in_block = 0; int dead_in_block = 0; int free_in_block = 0; int capacity = ((block->end)-(block->data))/size; header_type *cur; assert(block->size == size); for(cur=block->data ; cur<block->end ; cur+=size) { /* TODO: Optimisation*/ ATerm t = (ATerm)cur; if(IS_MARKED(t->header)) { CLR_MARK(t->header); alive_in_block++; empty = 0; assert(IS_OLD(t->header)); } else { switch(ATgetType(t)) { case AT_FREE: assert(IS_YOUNG(t->header)); free_in_block++; break; case AT_INT: case AT_REAL: case AT_APPL: case AT_LIST: case AT_PLACEHOLDER: case AT_BLOB: assert(IS_OLD(t->header)); AT_freeTerm(size, t); t->header=FREE_HEADER; dead_in_block++; break; case AT_SYMBOL: assert(IS_OLD(t->header)); AT_freeSymbol((SymEntry)t); t->header=FREE_HEADER; dead_in_block++; break; default: ATabort("panic in sweep phase\n"); } } } assert(alive_in_block + dead_in_block + free_in_block == capacity); next_block = block->next_by_size; #ifndef NDEBUG if(empty) { for(cur=block->data; cur<block->end; cur+=size) { assert(ATgetType((ATerm)cur) == AT_FREE); } } #endif if(empty) { /* DO NOT RESTORE THE FREE LIST: free cells have not been inserted*/ /* at_freelist[size] = old_freelist;*/ assert(top_at_blocks[size] < block->data || top_at_blocks[size] > block->end); #ifdef GC_VERBOSE fprintf(stderr,"MAJOR OLD: reclaim empty block %p\n",block); #endif reclaim_empty_block(at_old_blocks, size, block, prev_block); } else if(0 && 100*alive_in_block/capacity <= TO_YOUNG_RATIO) { promote_block_to_young(size, block, prev_block); old_bytes_in_young_blocks_after_last_major += (alive_in_block*SIZE_TO_BYTES(size)); } else { old_bytes_in_old_blocks_after_last_major += (alive_in_block*SIZE_TO_BYTES(size)); /* DO NOT FORGET THIS LINE*/ /* update the previous block*/ prev_block = block; } block = next_block; alive += alive_in_block; reclaiming += dead_in_block; } } if(alive) { perc = (100*reclaiming)/alive; STATS(reclaim_perc, perc); } }
int *epsclosure (int *t, int *ns_addr, int accset[], int *nacc_addr, int *hv_addr) { int stkpos, ns, tsp; int numstates = *ns_addr, nacc, hashval, transsym, nfaccnum; int stkend, nstate; static int did_stk_init = false, *stk; #define MARK_STATE(state) \ do{ trans1[state] = trans1[state] - MARKER_DIFFERENCE;} while(0) #define IS_MARKED(state) (trans1[state] < 0) #define UNMARK_STATE(state) \ do{ trans1[state] = trans1[state] + MARKER_DIFFERENCE;} while(0) #define CHECK_ACCEPT(state) \ do{ \ nfaccnum = accptnum[state]; \ if ( nfaccnum != NIL ) \ accset[++nacc] = nfaccnum; \ }while(0) #define DO_REALLOCATION() \ do { \ current_max_dfa_size += MAX_DFA_SIZE_INCREMENT; \ ++num_reallocs; \ t = reallocate_integer_array( t, current_max_dfa_size ); \ stk = reallocate_integer_array( stk, current_max_dfa_size ); \ }while(0) \ #define PUT_ON_STACK(state) \ do { \ if ( ++stkend >= current_max_dfa_size ) \ DO_REALLOCATION(); \ stk[stkend] = state; \ MARK_STATE(state); \ }while(0) #define ADD_STATE(state) \ do { \ if ( ++numstates >= current_max_dfa_size ) \ DO_REALLOCATION(); \ t[numstates] = state; \ hashval += state; \ }while(0) #define STACK_STATE(state) \ do { \ PUT_ON_STACK(state); \ CHECK_ACCEPT(state); \ if ( nfaccnum != NIL || transchar[state] != SYM_EPSILON ) \ ADD_STATE(state); \ }while(0) if (!did_stk_init) { stk = allocate_integer_array (current_max_dfa_size); did_stk_init = true; } nacc = stkend = hashval = 0; for (nstate = 1; nstate <= numstates; ++nstate) { ns = t[nstate]; /* The state could be marked if we've already pushed it onto * the stack. */ if (!IS_MARKED (ns)) { PUT_ON_STACK (ns); CHECK_ACCEPT (ns); hashval += ns; } } for (stkpos = 1; stkpos <= stkend; ++stkpos) { ns = stk[stkpos]; transsym = transchar[ns]; if (transsym == SYM_EPSILON) { tsp = trans1[ns] + MARKER_DIFFERENCE; if (tsp != NO_TRANSITION) { if (!IS_MARKED (tsp)) STACK_STATE (tsp); tsp = trans2[ns]; if (tsp != NO_TRANSITION && !IS_MARKED (tsp)) STACK_STATE (tsp); } } } /* Clear out "visit" markers. */ for (stkpos = 1; stkpos <= stkend; ++stkpos) { if (IS_MARKED (stk[stkpos])) UNMARK_STATE (stk[stkpos]); else flexfatal (_ ("consistency check failed in epsclosure()")); } *ns_addr = numstates; *hv_addr = hashval; *nacc_addr = nacc; return t; }
/** * Search for a key's position in the ordered list. Upon return, * *left_node points to the left node (and it has a reference) and the * return value points to a node that is referenced too. */ static struct lf_ordlist_node *search(struct lf_ordlist *lst, void *key, struct lf_ordlist_node **left_node) { struct lf_ordlist_node *left_node_next, *right_node; struct lf_ordlist_node *t, *t_next; search_again: for ( ; ; ) { *left_node = left_node_next = NULL; t = mem_safe_read(lst->fl, &lst->head); t_next = mem_safe_read(lst->fl, &NEXT(lst->head)); /* 1: Find left_node and right_node * * Entering this loop: t and t_next are referenced. * * Leaving this loop: t is referenced, and if t_next * is not marked then *left_node * and left_node_next are set and * have their own references. If t * != lst->tail, then t_next is * also referenced. */ do { if (!IS_MARKED(t_next)) { /* these refs may have been copied * before, but we had to loop again */ if (*left_node) { mem_release(lst->fl, *left_node); *left_node = NULL; } if (left_node_next) { mem_release(lst->fl, left_node_next); left_node_next = NULL; } /* copy both t and t_next's refs */ mem_incr_ref(t); (*left_node) = t; mem_incr_ref(t_next); left_node_next = t_next; } mem_release(lst->fl, t); t = GET_UNMARKED(t_next); /* take t_next's ref */ if (t == lst->tail) break; t_next = mem_safe_read(lst->fl, &NEXT(t)); } while (IS_MARKED(t_next) || lst->cmp(t->value, key) < 0); if (t != lst->tail) mem_release(lst->fl, t_next); /* done with t_next */ right_node = t; /* takes t's reference */ /* * At this point, right_node, *left_node and * left_node_next all have references. */ /* 2: Check nodes are adjacent */ if (left_node_next == right_node) { mem_release(lst->fl, left_node_next); if (right_node != lst->tail && IS_MARKED(NEXT(right_node))) { mem_release(lst->fl, right_node); mem_release(lst->fl, *left_node); goto search_again; } else { return right_node; } } /* 3: Remove one or more marked nodes * * Here, left_node_next, right_node and *left_node are * referenced. */ /* in case CAS succeeds. */ mem_incr_ref(right_node); assert(*left_node != lst->tail); if (compare_and_swap(&NEXT(*left_node), (intptr_t) left_node_next, (intptr_t) right_node)) { /* one for NEXT(*left_node), one for * 'left_node_next' */ mem_release(lst->fl, left_node_next); mem_release(lst->fl, left_node_next); if ((right_node != lst->tail) && IS_MARKED(NEXT(right_node))) { mem_release(lst->fl, right_node); mem_release(lst->fl, *left_node); goto search_again; } else { return right_node; } } /* one for the CAS prep. ref and one for * 'right_node' */ mem_release(lst->fl, right_node); mem_release(lst->fl, right_node); mem_release(lst->fl, *left_node); mem_release(lst->fl, left_node_next); } /* for( ; ; ) */ /* should not reach here */ assert(0); }