void clearSegStack_(segstack *s) { segchunk *c = s->first; segchunk *n; if ( !c->allocated ) /* statically allocated first chunk */ { n = c->next; c->next = NULL; s->last = c; s->base = s->top = c->top; s->max = addPointer(c, c->size); for(c=n; c; c = n) { n = c->next; PL_free(c); } } else /* all dynamic chunks */ { for(; c; c = n) { n = c->next; PL_free(c); } memset(s, 0, sizeof(*s)); } }
void popTopOfSegStack(segstack *stack) { again: if ( stack->top >= stack->base + stack->unit_size ) { stack->top -= stack->unit_size; } else { segchunk *chunk = stack->last; if ( chunk ) { if ( chunk->previous ) { segchunk *del = chunk; stack->last = chunk->previous; stack->last->next = NULL; chunk = stack->last; stack->top = chunk->top; MemoryBarrier(); /* Sync with scanSegStack() */ stack->base = chunk->data; stack->max = addPointer(chunk, chunk->size); if ( del->allocated ) PL_free(del); goto again; } } assert(0); } }
int popSegStack_(segstack *stack, void *data) { again: if ( stack->top >= stack->base + stack->unit_size ) { stack->top -= stack->unit_size; memcpy(data, stack->top, stack->unit_size); return TRUE; } else { segchunk *chunk = stack->last; if ( chunk ) { if ( chunk->previous ) { stack->last = chunk->previous; stack->last->next = NULL; if ( chunk->allocated ) PL_free(chunk); chunk = stack->last; stack->base = chunk->data; stack->max = addPointer(chunk, chunk->size); stack->top = chunk->top; goto again; } } return FALSE; } }
void * topOfSegStack(segstack *stack) { again: if ( stack->top >= stack->base + stack->unit_size ) { return stack->top - stack->unit_size; } else { segchunk *chunk = stack->last; if ( chunk ) { if ( chunk->previous ) { PL_LOCK(L_AGC); /* See comment */ stack->last = chunk->previous; stack->last->next = NULL; if ( chunk->allocated ) PL_free(chunk); chunk = stack->last; stack->base = chunk->data; stack->max = addPointer(chunk, chunk->size); stack->top = chunk->top; PL_UNLOCK(L_AGC); goto again; } } return NULL; } }
int enableSpareStack(Stack s) { if ( s->spare ) { s->max = addPointer(s->max, s->spare); s->spare = 0; return TRUE; } return FALSE; }
void initSegStack(segstack *stack, size_t unit_size, size_t len, void *data) { memset(stack, 0, sizeof(*stack)); stack->unit_size = unit_size; if ( len ) { segchunk *chunk = data; assert(len > sizeof(*chunk)); memset(chunk, 0, sizeof(*chunk)); chunk->size = len; stack->base = stack->top = chunk->top = chunk->data; stack->last = stack->first = chunk; stack->max = addPointer(chunk, len); } }
void pushArgumentStack__LD(Word p ARG_LD) { Word *newbase; size_t newsize = nextStackSize((Stack)&LD->stacks.argument, 1); if ( newsize && (newbase = stack_realloc(aBase, newsize)) ) { intptr_t as = newbase - aBase; if ( as ) { QueryFrame qf; aTop += as; aBase = newbase; for(qf=LD->query; qf; qf = qf->parent) qf->aSave += as; } aMax = addPointer(newbase, newsize); *aTop++ = p; } else outOfStack((Stack)&LD->stacks.argument, STACK_OVERFLOW_THROW); }
int pushSegStack(segstack *stack, void *data) { if ( stack->top + stack->unit_size <= stack->max ) { memcpy(stack->top, data, stack->unit_size); stack->top += stack->unit_size; stack->count++; return TRUE; } else { segchunk *chunk = PL_malloc(SEGSTACK_CHUNKSIZE); if ( !chunk ) return FALSE; /* out of memory */ chunk->allocated = TRUE; chunk->size = SEGSTACK_CHUNKSIZE; chunk->next = NULL; chunk->previous = stack->last; chunk->top = chunk->data; /* async scanning */ if ( stack->last ) { stack->last->next = chunk; stack->last->top = stack->top; stack->top = chunk->top; /* async scanning */ stack->last = chunk; } else { stack->top = chunk->top; /* async scanning */ stack->last = stack->first = chunk; } stack->base = chunk->data; stack->max = addPointer(chunk, chunk->size); memcpy(chunk->data, data, stack->unit_size); stack->top = chunk->data + stack->unit_size; stack->count++; return TRUE; } }