Mercurial > repos > rhope
view runtime/context.c @ 180:c40e0faa1c92
Add Call to Dict and List
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 19 Jun 2011 10:43:11 -0700 |
parents | 7bbdc034e347 |
children | ba35ab624ec2 |
line wrap: on
line source
#include "context.h" #include "object.h" #include "thread.h" #include <stdlib.h> #include <stddef.h> #include <stdio.h> context * contextqueue[32]; int32_t cq_readloc=0; int32_t cq_writeloc=0; rh_mutex(cq_lock) void cqueue_init() { rh_mutex_init(cq_lock); } context * get_cqueue() { context * ret; rh_lock(cq_lock); if (cq_readloc == cq_writeloc) { rh_unlock(cq_lock); return NULL; } ret = contextqueue[cq_readloc++]; if (cq_readloc == 32) cq_readloc = 0; rh_unlock(cq_lock); return ret; } int32_t put_cqueue(context * ct) { rh_lock(cq_lock); if (((cq_writeloc+1)&31) == cq_readloc) { rh_unlock(cq_lock); return 0; } contextqueue[cq_writeloc++] = ct; if(cq_writeloc == 32) cq_writeloc = 0; rh_unlock(cq_lock); return 1; } stackchunk * new_stack() { stackchunk * st = malloc(sizeof(stackchunk)); st->prev = NULL; st->next = NULL; st->free_space = st->data; return st; } context * new_context() { context * c = malloc(sizeof(context)); c->stack_begin = new_stack(); c->current_stack = c->stack_begin; c->resume_cdata = c->runafter = c->transaction = NULL; c->resumeable = 0; return c; } void free_context(context * c) { stackchunk *next,*current = c->stack_begin; while(current) { next = current->next; free(current); current = next; } free(c); } void * alloc_stack(context * ct, uint32_t size) { void * ret; stackchunk * current = ct->current_stack; char * next_free = current->free_space + size; if (next_free <= (current->data + STACK_CHUNK_SIZE)) { ret = current->free_space; current->free_space = next_free; return ret; } if (!current->next) { current->next = new_stack(); current->next->prev = current; } current = current->next; ct->current_stack = current; current->free_space = current->data + size; return current->data; } calldata * alloc_cdata(context * ct, calldata * lastframe, uint32_t num_params) { //Make sure we have enough space for at least 32 return values calldata * retval = alloc_stack(ct, sizeof(calldata)+(31)*sizeof(object *)); //But only actually reserve space for the number requested free_stack(ct, retval->params + num_params); retval->lastframe = lastframe; retval->callspace = num_params; return retval; } void free_stack(context * ct, void * data) { char * cdata = data; while(cdata < ct->current_stack->data || cdata >= ct->current_stack->free_space) { if(ct->current_stack == ct->stack_begin) { fprintf(stderr, "Attempt to free memory at %X using free_stack, but %X doesn't appear to be stack allocated\n", data, data); exit(-1); } ct->current_stack = ct->current_stack->prev; } ct->current_stack->free_space = data; if(ct->current_stack->free_space == ct->current_stack->data && ct->current_stack->prev) ct->current_stack = ct->current_stack->prev; }