Mercurial > repos > rhope
diff worker.c @ 0:76568becd6d6
Rhope Alpha 2a source import
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 28 Apr 2009 23:06:07 +0000 |
parents | |
children | 914ad38f9b59 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/worker.c Tue Apr 28 23:06:07 2009 +0000 @@ -0,0 +1,567 @@ +#include "structs.h" +#include "interp.h" +#include "datum.h" +#include "parser.h" +#include "saveload.h" +#include <stdlib.h> +#include <string.h> + +int vis_worker_from_string(datum ** inputlist, queue_entry * worker_entry) +{ + int i; + worker_datum * work; + datum * output = new_datum(BUILTIN_TYPE_WORKER, 1, sizeof(worker_datum), worker_entry->instance->def->program); + work = output->c.generic.data; + find_worker(inputlist[0]->c.generic.data, NULL, NULL, worker_entry->instance->def->program, &work->def); + if(work->def) + add_program_ref(work->def->program); + for(i = 0; i < 32; ++i) + work->params[i] = NULL; + release_ref(inputlist[0]); + inputlist[0] = output; + return 0; +} + +BOOL list_to_array(datum * list_dat, datum ** out_params, int num) +{ + int i; + datum * params[2]; + list_data * list = list_dat->c.generic.data; + if(num > list->num_entries) { + return FALSE; + } + for(i = 0; i < num; ++i) + out_params[i] = add_ref(list->entries[i]); + release_ref(list_dat); + return TRUE; +} + +datum * array_to_list(datum ** in_params, int num, program * prog) +{ + int i; + datum * params[2]; + params[0] = create_list(prog); + for(i = 0; i < num; ++i) + { + params[1] = in_params[i]; + vis_list_append(params, NULL); + } + return params[0]; +} + +int worker_populate_inputs(datum * inputWorker, datum * ioList, datum ** inputlist) +{ + int i,j=0; + worker_datum * work = inputWorker->c.generic.data; + list_data * list = ioList->c.generic.data; + for(i = 0; i < work->def->num_inputs; ++i) + if(work->params[i]) + { + DEBUGPRINTF("Setting input %d to %X from worker object\n", i, work->params[i]); + inputlist[i] = add_ref(work->params[i]); + } + else + { + if(j < list->num_entries) + { + DEBUGPRINTF("Setting input %d to %X from input %d\n", i, list->entries[j], j); + inputlist[i] = add_ref(list->entries[j]); + ++j; + } + else + { + ERRORPRINTF("Error: List passed to Do@Worker doesn't have enough entries for worker %s\n", work->def->name); + return -1; + } + } + return 0; +} + +int vis_worker_do(datum ** inputlist, queue_entry * worker_entry) +{ + //int i,j; + worker_datum * work; + //worker_def * def; + //list_data * list; + datum * inputWorker = inputlist[0]; + datum * ioList = inputlist[1]; + int returnval; + //release_ref(inputlist[0]); + work = inputlist[0]->c.generic.data; + //list_to_array(inputlist[1], inputlist, work->def->num_inputs); + /*list = inputlist[1]->c.generic.data; + j = 0; + DEBUGPRINTF("vis_worker_do: def_name: %s, num_inputs = %d, list length = %d\n", work->def->name, work->def->num_inputs, list->num_entries); + for(i = 0; i < work->def->num_inputs; ++i) + if(work->params[i]) + { + DEBUGPRINTF("Setting input %d to %X from worker object\n", i, work->params[i]); + inputlist[i] = add_ref(work->params[i]); + } + else + { + DEBUGPRINTF("Setting input %d to %X from input %d, company name: %s\n", i, list->entries[j], j, list->entries[j]->company->name); + inputlist[i] = add_ref(list->entries[j]); + ++j; + }*/ + returnval = worker_populate_inputs(inputWorker, ioList, inputlist); + release_ref(ioList); + if(returnval) + return returnval; + if(work->def->program != worker_entry->instance->def->program) { + prep_program(work->def->program ); + } + returnval = execute_def(work->def, *worker_entry, inputlist, pack_list_sub_callback); + if(returnval == 0) + { + inputlist[0] = array_to_list(inputlist, work->def->num_outputs, worker_entry->instance->def->program); + /*vis_list_new(params, NULL); + DEBUGPRINTF("params[0] after vis_list_new: %X\n", params[0]); + for(i = 0; i < work->def->num_outputs; ++i) + { + params[1] = inputlist[i]; + vis_list_append(params, NULL); + DEBUGPRINTF("params[0] after vis_list_append: %X\n", params[0]); + } + inputlist[0] = params[0];*/ + } + release_ref(inputWorker); + return returnval; +} + +int vis_worker_setinput(datum ** inputlist, queue_entry * worker_entry) +{ + worker_datum * work; + inputlist[0] = copy_datum(inputlist[0], 0); + work = inputlist[0]->c.generic.data; + if(inputlist[1]->c.integers.num_a < 32) + work->params[inputlist[1]->c.integers.num_a] = inputlist[2]; + else + { + puts("Error: Visuality currently only supports 32 inputs\n"); + execute_active = FALSE; + return -1; + } + release_ref(inputlist[1]); + inputlist[1] = inputlist[2] = NULL; + return 0; +} + +int vis_worker_add_worker_call(datum ** inputlist, queue_entry * worker_entry) +{ + worker_datum * add_work; + worker_datum * work = inputlist[0]->c.generic.data; + int index; + add_work = inputlist[1]->c.generic.data; + /*index = add_work->def - work->def->program->deflist; + DEBUGPRINTF("work->def: %X, deflist: %X\n", work->def, worker_entry->instance->def->program->deflist); + DEBUGPRINTF("work->def->name: %X\n", work->def->name);*/ + index = add_worker_to_def(work->def, add_work->def, 1.0, 1.0); + release_ref(inputlist[1]); + inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program); + inputlist[1]->c.integers.num_a = index; + return 0; +} + +int vis_worker_add_wire(datum ** inputlist, queue_entry * worker_entry) +{ + worker_datum * work = inputlist[0]->c.generic.data; + add_wire(work->def, inputlist[1]->c.integers.num_a, inputlist[2]->c.integers.num_a, inputlist[3]->c.integers.num_a, inputlist[4]->c.integers.num_a); + release_ref(inputlist[1]); + release_ref(inputlist[2]); + release_ref(inputlist[3]); + release_ref(inputlist[4]); + return 0; +} + +void list_change_program(list_data * list, program * new_prog) +{ + int i; + for(i = 0; i < list->num_entries; ++i) + { + if(list->entries[i] && list->entries[i]->company->type_id < USER_DEFINED_TYPES) + { + list->entries[i] = copy_datum(list->entries[i], 0); + list->entries[i]->company = new_prog->companylist + list->entries[i]->company->type_id; + if(list->entries[i]->company->type_id == BUILTIN_TYPE_LIST) + list_change_program(list->entries[i]->c.generic.data, new_prog); + } + } +} + +int vis_worker_add_constant(datum ** inputlist, queue_entry * worker_entry) +{ + datum * constant = inputlist[1]; + worker_datum * work = inputlist[0]->c.generic.data; + int index = add_constant(work->def, "code generated", 1.0, 1.0); + if(worker_entry->instance->def->program != work->def->program && constant->company->type_id < USER_DEFINED_TYPES) + { + constant = copy_datum(constant, 0); + constant->company = work->def->program->companylist + constant->company->type_id; + if(constant->company->type_id == BUILTIN_TYPE_LIST) + { + list_change_program(constant->c.generic.data, work->def->program); + } + } + work->def->implement_func->workerlist[index].value_index = constant; + inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program); + inputlist[1]->c.integers.num_a = index; + return 0; +} + +int vis_worker_add_input(datum ** inputlist, queue_entry * worker_entry) +{ + worker_datum * work = inputlist[0]->c.generic.data; + int index = add_input_num(work->def, inputlist[1]->c.generic.data, inputlist[2]->c.integers.num_a, 1.0, 1.0); + release_ref(inputlist[1]); + release_ref(inputlist[2]); + inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program); + inputlist[1]->c.integers.num_a = index; + return 0; +} + +int vis_worker_add_output(datum ** inputlist, queue_entry * worker_entry) +{ + worker_datum * work = inputlist[0]->c.generic.data; + int index = add_output_num(work->def, inputlist[1]->c.generic.data, inputlist[2]->c.integers.num_a, 1.0, 1.0); + release_ref(inputlist[1]); + release_ref(inputlist[2]); + inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program); + inputlist[1]->c.integers.num_a = index; + return 0; +} + +int vis_worker_add_objectget(datum ** inputlist, queue_entry * worker_entry) +{ + worker_datum * work = inputlist[0]->c.generic.data; + int index = add_get_comp_room(work->def, inputlist[1]->c.generic.data, 1.0,1.0); + release_ref(inputlist[1]); + inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program); + inputlist[1]->c.integers.num_a = index; + return 0; +} + +int vis_worker_add_objectset(datum ** inputlist, queue_entry * worker_entry) +{ + worker_datum * work = inputlist[0]->c.generic.data; + int index = add_set_comp_room(work->def, inputlist[1]->c.generic.data, 1.0,1.0); + release_ref(inputlist[1]); + inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program); + inputlist[1]->c.integers.num_a = index; + return 0; +} + +int vis_worker_add_globalget(datum ** inputlist, queue_entry * worker_entry) +{ + worker_datum * work = inputlist[0]->c.generic.data; + int index; + char * name = malloc(inputlist[1]->c.generic.len + inputlist[2]->c.generic.len + 1); + memcpy(name, inputlist[1]->c.generic.data, inputlist[1]->c.generic.len); + release_ref(inputlist[1]); + strcat(name, "::"); + strcat(name, inputlist[2]->c.generic.data); + release_ref(inputlist[2]); + index = add_global_get(work->def, name, 1.0,1.0); + free(name); + inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program); + inputlist[1]->c.integers.num_a = index; + return 0; +} + +int vis_worker_add_globalset(datum ** inputlist, queue_entry * worker_entry) +{ + worker_datum * work = inputlist[0]->c.generic.data; + int index; + char * name = malloc(inputlist[1]->c.generic.len + inputlist[2]->c.generic.len + 1); + memcpy(name, inputlist[1]->c.generic.data, inputlist[1]->c.generic.len); + release_ref(inputlist[1]); + strcat(name, "::"); + strcat(name, inputlist[2]->c.generic.data); + release_ref(inputlist[2]); + index = add_global_set(work->def, name, 1.0,1.0); + free(name); + inputlist[1] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program); + inputlist[1]->c.integers.num_a = index; + return 0; +} + +int vis_worker_new(datum ** inputlist, queue_entry * worker_entry) +{ + int i; + datum * output = new_datum(BUILTIN_TYPE_WORKER, 1, sizeof(worker_datum), worker_entry->instance->def->program); + worker_datum * work = output->c.generic.data; + work->def = create_worker(worker_entry->instance->def->program, inputlist[0]->c.generic.data, 0, 0, USER_FLAG | WORKER_TYPE); + add_program_ref(work->def->program); + for(i = 0; i < 32; ++i) + work->params[i] = NULL; + release_ref(inputlist[0]); + inputlist[0] = output; + return 0; +} + +int vis_worker_clear(datum ** inputlist, queue_entry * worker_entry) +{ + int i; + worker_datum * work = inputlist[0]->c.generic.data; + VIS_EnterCriticalSection(work->def->implement_func->lock); + for(i = 0; i < work->def->implement_func->num_workers; ++i) { + if(work->def->implement_func->workerlist[i].type == CONSTANT) { + release_ref(work->def->implement_func->workerlist[i].value_index); + } + } + work->def->num_inputs = 0; + work->def->num_outputs = 0; + work->def->implement_func->num_workers = 0; + work->def->implement_func->num_wires = 0; + work->def->implement_func->dirty = TRUE; + VIS_LeaveCriticalSection(work->def->implement_func->lock); + return 0; +} + +int vis_worker_uses(datum ** inputlist, queue_entry * worker_entry) +{ + int i; + worker_datum * work = inputlist[0]->c.generic.data; + list_data * list = inputlist[1]->c.generic.data; + char ** new_uses; + if(list->num_entries) + { + new_uses = malloc(sizeof(char *) * list->num_entries); + for(i = 0; i < list->num_entries; ++i) { + if(list->entries[i]->company->type_id != BUILTIN_TYPE_STRING) { + ERRORPUTS("List passed to Uses@Worker contains non-string value(s)\n"); + execute_active = FALSE; + return -1; + } + new_uses[i] = malloc(sizeof(char) * list->entries[i]->c.generic.len); + memcpy(new_uses[i], list->entries[i]->c.generic.data, list->entries[i]->c.generic.len); + } + } else + new_uses = NULL; + if(work->def->uses_stores) + free(work->def->uses_stores); + work->def->uses_stores = new_uses; + work->def->num_stores = list->num_entries; + release_ref(inputlist[1]); + return 0; +} + +int vis_worker_setio_counts(datum ** inputlist, queue_entry * worker_entry) +{ + int i; + int new_inputs = inputlist[1]->c.integers.num_a; + worker_datum * work = inputlist[0]->c.generic.data; + release_ref(inputlist[1]); + if(work->def->num_inputs < new_inputs) + { + work->def->input_types = realloc(work->def->input_types, sizeof(short)*new_inputs); + for(i = work->def->num_inputs; i < new_inputs; ++i) + work->def->input_types[i] = ANY_TYPE; + } + work->def->num_inputs = new_inputs; + work->def->num_outputs = inputlist[2]->c.integers.num_a; + release_ref(inputlist[2]); + return 0; +} + +int vis_program_new(datum ** inputlist, queue_entry * worker_entry) +{ + program * prog = new_program(START_DEF_STORAGE, START_COMP_STORAGE); + inputlist[0] = new_datum(BUILTIN_TYPE_PROGRAM, 2, 0, worker_entry->instance->def->program); + inputlist[0]->c.generic.data = prog; + inputlist[0]->c.generic.len = sizeof(program); + //inputlist[0]->union_type = 1; + return 0; +} + +int vis_program_new_worker(datum ** inputlist, queue_entry * worker_entry) +{ + int i; + datum * output = new_datum(BUILTIN_TYPE_WORKER, 1, sizeof(worker_datum), worker_entry->instance->def->program); + worker_datum * work = output->c.generic.data; + add_program_ref(inputlist[0]->c.generic.data); + work->def = create_worker(inputlist[0]->c.generic.data, inputlist[1]->c.generic.data, 0, 0, USER_FLAG | WORKER_TYPE); + for(i = 0; i < 32; ++i) + work->params[i] = NULL; + release_ref(inputlist[1]); + inputlist[1] = output; + return 0; +} + +int vis_program_add_worker(datum ** inputlist, queue_entry * worker_entry) +{ + int i; + worker_datum * work = inputlist[1]->c.generic.data; + program * prog = inputlist[0]->c.generic.data; + datum * output = new_datum(BUILTIN_TYPE_WORKER, 1, sizeof(worker_datum), worker_entry->instance->def->program); + worker_datum * out_work = output->c.generic.data; + add_program_ref(inputlist[0]->c.generic.data); + out_work->def = create_worker(prog, work->def->name, work->def->num_inputs, work->def->num_outputs, WORKER_TYPE); + out_work->def->implement_func = work->def->implement_func; + out_work->def->type = work->def->type; + if(work->def->type & USER_FLAG) + out_work->def->program = work->def->program; + for(i = 0; i < work->def->num_inputs; ++i) + out_work->def->input_types[i] = out_work->def->input_types[i]; + release_ref(inputlist[1]); + inputlist[1] = output; + return 0; +} + +int vis_program_add_builtins(datum ** inputlist, queue_entry * worker_entry) +{ + initpredefworkers((program *)inputlist[0]->c.generic.data); + return 0; +} + +int vis_program_run(datum ** inputlist, queue_entry * worker_entry) +{ + datum * params[32]; + defchunk * current; + int i; + program * prog = inputlist[0]->c.generic.data; + params[0] = inputlist[1]; + VIS_EnterCriticalSection(program_count_lock); + ++program_count; + VIS_LeaveCriticalSection(program_count_lock); + prep_program(prog); + add_program_ref(prog); + init_custom_worker(-1, NULL, prog->defs->deflist, main_callback, add_ref(inputlist[0]), params); + return 0; +} + +int vis_program_find_worker(datum ** inputlist, queue_entry * worker_entry) +{ + int i,returnval; + worker_datum * work; + worker_def * def; + program * prog = inputlist[0]->c.generic.data; + returnval = find_worker(inputlist[1]->c.generic.data, NULL, NULL, prog, &def); + release_ref(inputlist[0]); + if(returnval >= 0) + { + add_program_ref(prog); + release_ref(inputlist[1]); + inputlist[0] = new_datum(BUILTIN_TYPE_WORKER, 1, sizeof(worker_datum), worker_entry->instance->def->program); + inputlist[1] = NULL; + work = inputlist[0]->c.generic.data; + work->def = def; + for(i = 0; i < 32; ++i) + work->params[i] = NULL; + } else { + inputlist[0] = NULL; + } + return 0; +} + +void free_worker(worker_def * def) +{ + int i; + if(def->type & USER_FLAG && (def->type & TYPE_MASK) == WORKER_TYPE) + { + for(i = 0; i < def->implement_func->num_workers; ++i) + if(def->implement_func->workerlist[i].type == CONSTANT) + release_ref(def->implement_func->workerlist[i].value_index); + free(def->implement_func->workerlist); + free(def->implement_func->wirelist); + free(def->implement_func->workers_to_wires_up); + free(def->implement_func->workers_to_wires_down); + free(def->implement_func); + } + free(def->name); + free(def->input_types); + free(def->output_types); +} + +void free_company(company * comp) +{ + free(comp->methodlist); + free(comp->room_list); +} + +void add_program_ref(program * prog) +{ + VIS_EnterCriticalSection(prog->lock); + ++prog->refcount; + VIS_LeaveCriticalSection(prog->lock); +} + +void release_program_ref(program * prog) +{ + int i; + defchunk * current, *temp; + VIS_EnterCriticalSection(prog->lock); + --prog->refcount; + if(!prog->refcount) { + VIS_LeaveCriticalSection(prog->lock); + VIS_DeleteCriticalSection(prog->lock); + current = prog->defs; + while(current) + { + for(i = 0; i < current->num_defs; ++i) + { + free_worker(current->deflist + i); + } + current = current->next; + } + current = prog->defs; + while(current) + { + temp = current; + current = current->next; + free(temp); + } + //FIXME: We can't currently free the object definitions because of issues related to global stores + //for(i = 0; i < prog->num_companies; ++i) + // free_company(prog->companylist + i); + //free(prog->companylist); + free(prog); + } else { + VIS_LeaveCriticalSection(prog->lock); + } +} + +/* +int vis_worker_begin_transaction(datum ** inputlist, queue_entry * worker_entry) +{ + worker_def * def; + int returnval; + datum * params[2]; + int i; + global_store * store; + list_data * list = inputist[0]->c.generic.data; + transaction * trans = malloc(sizeof(transaction) + list->num_entries - 1); + trans->num_stores = list->num_entries; + VIS_EnterCriticalSection(global_store_lock); + for(i = 0; i < list->num_entries; ++i) + { + params[0] = global_store_dict; + params[1] = add_ref(list->entries[i]); + vis_dict_index(params, NULL); + store = params[0]->c.generic.data; + while(store->inuse) + { + VIS_LeaveCriticalSection(global_store_lock); + #ifdef WIN32 + Sleep(0); + #else + sleep(0); + #endif + VIS_EnterCriticalSection(global_store_lock); + } + store->inuse; + trans->stores[i] = params[0]; + } + VIS_LeaveCriticalSection(global_store_lock; + release_ref(inputlist[0]); + def = deflist+inputlist[1]->c.integers.num_a; + release_ref(inputlist[1]); + list_to_array(inputlist[2], inputlist, def->num_inputs); + returnval = execute_def_data(def, *worker_entry, inputlist, trasnaction_sub_callback, transaction); + if(returnval == 0) + inputlist[0] = array_to_list(inputlist, def->num_outputs); + return returnval; +} + +*/ +