VM* init_vm(int stack_size, size_t heap_size, int max_threads // not implemented yet ) { VM* vm = malloc(sizeof(VM)); STATS_INIT_STATS(vm->stats) STATS_ENTER_INIT(vm->stats) VAL* valstack = malloc(stack_size * sizeof(VAL)); vm->active = 1; vm->valstack = valstack; vm->valstack_top = valstack; vm->valstack_base = valstack; vm->stack_max = valstack + stack_size; alloc_heap(&(vm->heap), heap_size, heap_size, NULL); c_heap_init(&vm->c_heap); vm->ret = NULL; vm->reg1 = NULL; #ifdef HAS_PTHREAD vm->inbox = malloc(1024*sizeof(VAL)); memset(vm->inbox, 0, 1024*sizeof(VAL)); vm->inbox_end = vm->inbox + 1024; vm->inbox_write = vm->inbox; vm->inbox_nextid = 1; // The allocation lock must be reentrant. The lock exists to ensure that // no memory is allocated during the message sending process, but we also // check the lock in calls to allocate. // The problem comes when we use requireAlloc to guarantee a chunk of memory // first: this sets the lock, and since it is not reentrant, we get a deadlock. pthread_mutexattr_t rec_attr; pthread_mutexattr_init(&rec_attr); pthread_mutexattr_settype(&rec_attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&(vm->inbox_lock), NULL); pthread_mutex_init(&(vm->inbox_block), NULL); pthread_mutex_init(&(vm->alloc_lock), &rec_attr); pthread_cond_init(&(vm->inbox_waiting), NULL); vm->max_threads = max_threads; vm->processes = 0; #else global_vm = vm; #endif STATS_LEAVE_INIT(vm->stats) return vm; }
VM* init_vm(int stack_size, size_t heap_size, int max_threads, // not implemented yet int argc, char* argv[]) { VM* vm = malloc(sizeof(VM)); STATS_INIT_STATS(vm->stats) STATS_ENTER_INIT(vm->stats) VAL* valstack = malloc(stack_size * sizeof(VAL)); vm->valstack = valstack; vm->valstack_top = valstack; vm->valstack_base = valstack; vm->stack_max = valstack + stack_size; alloc_heap(&(vm->heap), heap_size); vm->ret = NULL; vm->reg1 = NULL; vm->inbox = malloc(1024*sizeof(VAL)); memset(vm->inbox, 0, 1024*sizeof(VAL)); vm->inbox_end = vm->inbox + 1024; vm->inbox_ptr = vm->inbox; vm->inbox_write = vm->inbox; pthread_mutex_init(&(vm->inbox_lock), NULL); pthread_mutex_init(&(vm->inbox_block), NULL); pthread_mutex_init(&(vm->alloc_lock), NULL); pthread_cond_init(&(vm->inbox_waiting), NULL); vm->max_threads = max_threads; vm->processes = 0; vm->argv = argv; vm->argc = argc; STATS_LEAVE_INIT(vm->stats) return vm; }