static uint32_t get_next_id(void) { uint64_t id = 0; char* lock_record = NULL; char* record = NULL; // Find a valid ID for our next semaphore // This lock makes sure that we don't // have concurrent access to sem.ids errval_t err = oct_lock("sem.lock", &lock_record); assert(err_is_ok(err)); err = oct_get(&record, "sem.ids { current_id: _ }"); if (err_is_ok(err)) { err = oct_read(record, "_ { current_id: %d }", &id); assert(err_is_ok(err)); } else if (err_no(err) == OCT_ERR_NO_RECORD) { err = oct_set("sem.ids { current_id: 0 }"); assert(err_is_ok(err)); } else { assert(!"Should not happen."); } id += 1; err = oct_set("sem.ids { current_id: %lu }", id); assert(err_is_ok(err)); err = oct_unlock(lock_record); free(lock_record); free(record); assert(err_is_ok(err)); return id; }
/** * \brief Non-blocking name service lookup * * \param iface Name of interface for which to query name server * \param retiref Returns pointer to IREF on success */ errval_t nameservice_lookup(const char *iface, iref_t *retiref) { errval_t err; struct octopus_rpc_client *r = get_octopus_rpc_client(); if (r == NULL) { return LIB_ERR_NAMESERVICE_NOT_BOUND; } char* record = NULL; octopus_trigger_id_t tid; errval_t error_code; err = r->vtbl.get(r, iface, NOP_TRIGGER, &record, &tid, &error_code); if (err_is_fail(err)) { goto out; } err = error_code; if (err_is_fail(err)) { if (err_no(err) == OCT_ERR_NO_RECORD) { err = err_push(err, LIB_ERR_NAMESERVICE_UNKNOWN_NAME); } goto out; } uint64_t iref_number = 0; err = oct_read(record, "_ { iref: %d }", &iref_number); if (err_is_fail(err) || iref_number == 0) { err = err_push(err, LIB_ERR_NAMESERVICE_INVALID_NAME); goto out; } if (retiref != NULL) { *retiref = iref_number; } out: free(record); return err; }
static void cpu_change_event(octopus_mode_t mode, char* record, void* state) { if (mode & OCT_ON_SET) { KALUGA_DEBUG("CPU found: %s\n", record); assert(my_core_id == 0); // TODO(gz): why? uint64_t barrelfish_id, arch_id, enabled = 0; errval_t err = oct_read(record, "_ { barrelfish_id: %d, apic_id: %d, enabled: %d }", &barrelfish_id, &arch_id, &enabled); if (err_is_fail(err)) { DEBUG_ERR(err, "Cannot read record."); assert(!"Illformed core record received"); goto out; } struct module_info* mi = find_module("corectrl"); if (mi != NULL) { err = mi->start_function(0, mi, record); if (err_is_fail(err)) { printf("Boot driver not found. Do not boot discovered CPU %"PRIu64".\n", barrelfish_id); goto out; } assert(err_is_ok(err)); } } if (mode & OCT_ON_DEL) { KALUGA_DEBUG("CPU removed: %s\n", record); assert(!"NYI"); } out: assert(!(mode & OCT_REMOVED)); free(record); }
errval_t start_networking(coreid_t core, struct module_info* driver, char* record) { assert(driver != NULL); errval_t err = SYS_ERR_OK; uint64_t vendor_id, device_id, bus, dev, fun; /* check if we are using the supplied pci address of eth0 */ if (eth0.bus != 0xff || eth0.device != 0xff || eth0.function != 0xff) { err = oct_read(record, "_ { bus: %d, device: %d, function: %d, vendor: %d, device_id: %d }", &bus, &dev, &fun, &vendor_id, &device_id); assert(err_is_ok(err)); if ((eth0.bus != (uint8_t)bus) | (eth0.device != (uint8_t)dev) | (eth0.function != (uint8_t)fun)) { KALUGA_DEBUG("start_networking: skipping card %" PRIu64 ":% "PRIu64 ":% " PRIu64"\n", bus, dev, fun); return KALUGA_ERR_DRIVER_NOT_AUTO; } } if (is_started(driver)) { return KALUGA_ERR_DRIVER_ALREADY_STARTED; } if (!is_auto_driver(driver)) { return KALUGA_ERR_DRIVER_NOT_AUTO; } struct module_info* netd = find_module("netd"); if (netd == NULL || !is_auto_driver(netd)) { KALUGA_DEBUG("netd not found or not declared as auto."); return KALUGA_ERR_DRIVER_NOT_AUTO; } struct module_info* ngd_mng = find_module("NGD_mng"); if (ngd_mng == NULL || !is_auto_driver(ngd_mng)) { KALUGA_DEBUG("NGD_mng not found or not declared as auto."); return KALUGA_ERR_DRIVER_NOT_AUTO; } err = default_start_function(core, driver, record); if (err_is_fail(err)) { DEBUG_ERR(err, "Spawning %s failed.", driver->path); return err; } // XXX: Manually add cardname (overwrite first (auto) argument) // +Weird convention, e1000n binary but cardname=e1000 char* cardname = strcmp(driver->binary, "e1000n") == 0 ? "e1000" : driver->binary; size_t name_len = strlen("cardname=") + strlen(cardname) + 1; char* card_argument = malloc(name_len); sprintf(card_argument, "cardname=%s", cardname); printf("############# starting network with arguments %s\n", card_argument); // Spawn netd and ngd_mng netd->argv[0] = card_argument; err = spawn_program(core, netd->path, netd->argv, environ, 0, get_did_ptr(netd)); ngd_mng->argv[0] = card_argument; err = spawn_program(core, ngd_mng->path, ngd_mng->argv, environ, 0, get_did_ptr(ngd_mng)); free(card_argument); return err; }
/** * \brief Leave a barrier. Blocks until all involved parties have * called oct_barrier_leave(). * * Client deletes its barrier record. In case the client * was the last one we delete the special record which * wakes up all other clients. * * \param barrier_record Clients own record as provided by * oct_barrier_enter. */ errval_t oct_barrier_leave(const char* barrier_record) { errval_t exist_err; errval_t err; char* rec_name = NULL; char* barrier_name = NULL; char* record = NULL; char** names = NULL; size_t remaining_barriers = 0; uint64_t mode = 0; uint64_t state = 0; uint64_t fn = 0; octopus_trigger_id_t tid; octopus_trigger_t t = oct_mktrigger(SYS_ERR_OK, octopus_BINDING_RPC, OCT_ON_DEL, NULL, NULL); //debug_printf("leaving: %s\n", barrier_record); err = oct_read(barrier_record, "%s { barrier: %s }", &rec_name, &barrier_name); if (err_is_ok(err)) { err = oct_del(rec_name); if (err_is_fail(err)) { goto out; } err = oct_get_names(&names, &remaining_barriers, "_ { barrier: '%s' }", barrier_name); oct_free_names(names, remaining_barriers); //debug_printf("remaining barriers is: %lu\n", remaining_barriers); if (err_is_ok(err)) { struct octopus_thc_client_binding_t* cl = oct_get_thc_client(); err = cl->call_seq.exists(cl, barrier_name, t, &tid, &exist_err); if (err_is_fail(err)) { goto out; } err = exist_err; if (err_is_ok(err)) { // Wait until everyone has left the barrier err = cl->recv.trigger(cl, &tid, &fn, &mode, &record, &state); assert(mode & OCT_REMOVED); } else if (err_no(err) == OCT_ERR_NO_RECORD) { // barrier already deleted err = SYS_ERR_OK; } } else if (err_no(err) == OCT_ERR_NO_RECORD) { // We are the last one to leave the barrier, // wake-up all others err = oct_del("%s", barrier_name); } else { // Just return the error } } out: free(record); free(rec_name); free(barrier_name); return err; }
errval_t start_boot_driver(coreid_t where, struct module_info* mi, char* record) { assert(mi != NULL); errval_t err = SYS_ERR_OK; if (!is_auto_driver(mi)) { return KALUGA_ERR_DRIVER_NOT_AUTO; } // Construct additional command line arguments containing pci-id. // We need one extra entry for the new argument. uint64_t barrelfish_id, apic_id, cpu_type; char **argv = mi->argv; bool cleanup = false; char barrelfish_id_s[10]; size_t argc = mi->argc; KALUGA_DEBUG("Starting corectrl for %s\n", record); err = oct_read(record, "_ { apic_id: %d, barrelfish_id: %d, type: %d }", &apic_id, &barrelfish_id, &cpu_type); if (err_is_ok(err)) { skb_add_fact("corename(%"PRIu64", %s, apic(%"PRIu64")).", barrelfish_id, cpu_type_to_archstr(cpu_type), apic_id); if (barrelfish_id == my_core_id) { return SYS_ERR_OK; } argv = malloc((argc+5) * sizeof(char *)); memcpy(argv, mi->argv, argc * sizeof(char *)); snprintf(barrelfish_id_s, 10, "%"PRIu64"", barrelfish_id); argv[argc] = "boot"; argc += 1; argv[argc] = barrelfish_id_s; argc += 1; // Copy kernel args over to new core struct module_info* cpu_module = find_module("cpu"); if (cpu_module != NULL && strlen(cpu_module->args) > 1) { KALUGA_DEBUG("%s:%s:%d: Boot with cpu arg %s and barrelfish_id_s=%s\n", __FILE__, __FUNCTION__, __LINE__, cpu_module->args, barrelfish_id_s); argv[argc] = "-a"; argc += 1; argv[argc] = cpu_module->args; argc += 1; } argv[argc] = NULL; cleanup = true; } else { DEBUG_ERR(err, "Malformed CPU record?"); return err; } struct capref task_cap_kernel; task_cap_kernel.cnode = cnode_task; task_cap_kernel.slot = TASKCN_SLOT_KERNELCAP; #ifdef KALUGA_SERVICE_DEBUG struct capability info; err = debug_cap_identify(task_cap_kernel, &info); if (err_is_fail(err)) { USER_PANIC_ERR(err, "Can not identify the capability."); } char buffer[1024]; debug_print_cap(buffer, 1024, &info); KALUGA_DEBUG("%s:%d: capability=%s\n", __FILE__, __LINE__, buffer); #endif struct capref inheritcn_cap; err = alloc_inheritcn_with_caps(&inheritcn_cap, NULL_CAP, NULL_CAP, task_cap_kernel); if (err_is_fail(err)) { DEBUG_ERR(err, "alloc_inheritcn_with_caps failed."); } err = spawn_program_with_caps(where, mi->path, argv, environ, inheritcn_cap, NULL_CAP, SPAWN_FLAGS_NEW_DOMAIN, &mi->did[0]); if (err_is_fail(err)) { DEBUG_ERR(err, "Spawning %s failed.", mi->path); } if (cleanup) { free(argv); } return err; }
void gen_oct(MESH *m, char *filename) { // place each point into the oct-tree OctTree *tree = oct_new(100000, 500000); int depth = 6; float total = (float)(B_EDGE-1) / (float)B_EDGE; for(int i=0; i<m->nv; i++) { F3MULS(m->v[i], m->v[i], total); int leaf = oct_leaf(tree, &m->v[i], depth); ListInt2 *tmp = malloc(sizeof(ListInt2)); tmp->x = i; tmp->y = tree->brick[leaf].nv; tmp->next = tree->brick[leaf].v; tree->brick[leaf].v = tmp; tree->brick[leaf].nv++; } depth++; printf("TreeBlock/Brick = (%d %d)\n", tree->blockcount, tree->brickcount); // tree->brickcount ++; unsigned int buf_size = 16*B_CUBE; float4 (*bricktex)[B_EDGE][B_EDGE] = malloc(buf_size); memset(bricktex, 0, buf_size); int3 index; int3 itmp; int id, idt; ListInt2 *tmp; printf("Generating Voxel bricks.\n"); int lastbrickcount = tree->brickcount; for(int i=0; i<lastbrickcount; i++) { // printf("Brick #%d. %d\n", i, tree->brick[i].nv); tmp = tree->brick[i].v; if(tmp) for(int j=0; j<tree->brick[i].nv && tmp; j++) //while(tmp) { index.x = ((int)(m->v[tmp->x].x * (7<<depth)) % (B_SIZE-1))+1; index.y = ((int)(m->v[tmp->x].y * (7<<depth)) % (B_SIZE-1))+1; index.z = ((int)(m->v[tmp->x].z * (7<<depth)) % (B_SIZE-1))+1; id = i; itmp.x = id % B_COUNT; idt = (id-itmp.x) / B_COUNT; itmp.y = idt % B_COUNT; itmp.z = (idt-itmp.y) / B_COUNT; F3MULS(itmp, itmp, (B_SIZE)); F3ADD(index, index, itmp); F3COPY(bricktex[index.z][index.y][index.x], m->n[tmp->x]); bricktex[index.z][index.y][index.x].w = 1.0f; tmp = tmp->next; } } printf("Copy neighbour voxels.\n"); for(int i=1; i<tree->brickcount; i++) { float size = tree->location[i].w; int3 d,s; d.x = i % B_COUNT; idt = (i-d.x) / B_COUNT; d.y = idt % B_COUNT; d.z = (idt-d.y) / B_COUNT; F3MULS(d, d, B_SIZE); int src; float3 pos; F3COPY(pos, tree->location[i]); pos.x += size*1.5; pos.y += size * 0.5; pos.z += size * 0.5; src = oct_read(tree, &pos); if(src) { s.x = src % B_COUNT; idt = (src-s.x) / B_COUNT; s.y = idt % B_COUNT; s.z = (idt-s.y) / B_COUNT; F3MULS(s, s, B_SIZE); for(int x=0; x<B_SIZE; x++) for(int y=0; y<B_SIZE; y++) { bricktex[s.z+x][s.y+y][s.x] = bricktex[d.z+x][d.y+y][d.x+7]; } } F3COPY(pos, tree->location[i]); pos.x += size*0.5; pos.y += size*1.5; pos.z += size*0.5; src = oct_read(tree, &pos); if(src) { s.x = src % B_COUNT; idt = (src-s.x) / B_COUNT; s.y = idt % B_COUNT; s.z = (idt-s.y) / B_COUNT; F3MULS(s, s, B_SIZE); for(int x=1; x<B_SIZE; x++) for(int y=1; y<B_SIZE; y++) { bricktex[s.z+x][s.y][s.x+y] = bricktex[d.z+x][d.y+7][d.x+y]; } } F3COPY(pos, tree->location[i]); pos.x += size*0.5; pos.y += size*0.5; pos.z += size*1.5; src = oct_read(tree, &pos); if(src) { s.x = src % B_COUNT; idt = (src-s.x) / B_COUNT; s.y = idt % B_COUNT; s.z = (idt-s.y) / B_COUNT; F3MULS(s, s, B_SIZE); for(int x=1; x<B_SIZE; x++) for(int y=1; y<B_SIZE; y++) { bricktex[s.z][s.y+x][s.x+y] = bricktex[d.z+7][d.y+x][d.x+y]; } } F3COPY(pos, tree->location[i]); pos.x += size*1.5; pos.y += size*1.5; pos.z += size*0.5; src = oct_read(tree, &pos); if(src) { s.x = src % B_COUNT; idt = (src-s.x) / B_COUNT; s.y = idt % B_COUNT; s.z = (idt-s.y) / B_COUNT; F3MULS(s, s, B_SIZE); for(int x=1; x<B_SIZE; x++) { bricktex[s.z+x][s.y][s.x] = bricktex[d.z+x][d.y+7][d.x+7]; } } F3COPY(pos, tree->location[i]); pos.x += size*1.5; pos.y += size*0.5; pos.z += size*1.5; src = oct_read(tree, &pos); if(src) { s.x = src % B_COUNT; idt = (src-s.x) / B_COUNT; s.y = idt % B_COUNT; s.z = (idt-s.y) / B_COUNT; F3MULS(s, s, B_SIZE); for(int x=1; x<B_SIZE; x++) { bricktex[s.z][s.y+x][s.x] = bricktex[d.z+7][d.y+x][d.x+7]; } } F3COPY(pos, tree->location[i]); pos.x += size*0.5; pos.y += size*1.5; pos.z += size*1.5; src = oct_read(tree, &pos); if(src) { s.x = src % B_COUNT; idt = (src-s.x) / B_COUNT; s.y = idt % B_COUNT; s.z = (idt-s.y) / B_COUNT; F3MULS(s, s, B_SIZE); for(int x=1; x<B_SIZE; x++) { bricktex[s.z][s.y][s.x+x] = bricktex[d.z+7][d.y+7][d.x+x]; } } F3COPY(pos, tree->location[i]); pos.x += size*1.5; pos.y += size*1.5; pos.z += size*1.5; src = oct_read(tree, &pos); if(src) { s.x = src % B_COUNT; idt = (src-s.x) / B_COUNT; s.y = idt % B_COUNT; s.z = (idt-s.y) / B_COUNT; F3MULS(s, s, B_SIZE); bricktex[s.z][s.y][s.x] = bricktex[d.z+7][d.y+7][d.x+7]; } } printf("TreeBlock/Brick = (%d %d)\n", tree->blockcount, tree->brickcount); printf("Walking the normals.\n"); for(int i=1; i<tree->brickcount; i++) { } printf("Writing \"%s\".\n", filename); FILE *fptr = fopen(filename, "wb"); int zero = 0; fwrite("VOCT", 4, 1, fptr); fwrite(&tree->blockcount, 4, 1, fptr); fwrite(&tree->brickcount, 4, 1, fptr); fwrite(&zero, 4, 1, fptr); fwrite(tree->block, tree->blockcount, sizeof(OctBlock), fptr); z_stream strm = { .zalloc=Z_NULL, .zfree=Z_NULL, .opaque=Z_NULL }; int ret = deflateInit(&strm, Z_DEFAULT_COMPRESSION); if(ret != Z_OK) { printf("deflateInit() failed.\n"); return; } #define CHUNK (256 * 1024) unsigned char in[CHUNK]; unsigned char out[CHUNK]; int row = sizeof(float4)*B_SIZE; int have, inoff = 0; for(int i=0; i<tree->brickcount; i++) { int3 boff; int itmp = i % B_COUNT; boff.x = itmp; itmp = (i-boff.x) / B_COUNT; boff.y = itmp % B_COUNT; boff.z = (itmp-boff.y) / B_COUNT; F3MULS(boff, boff, B_SIZE); for(int z=0; z < B_SIZE; z++) for(int y=0; y < B_SIZE; y++) { memcpy(in+inoff, &bricktex[boff.z+z][boff.y+y][boff.x], row); inoff += row; if(inoff+row > CHUNK) { strm.next_in = in; strm.avail_in = inoff; do{ strm.avail_out = CHUNK; strm.next_out = out; ret = deflate(&strm, Z_NO_FLUSH); // assert(ret != Z_STREAM_ERROR); have = CHUNK - strm.avail_out; fwrite(out, have, 1, fptr); } while (strm.avail_out == 0); // assert(strm.avail_in == 0); inoff = 0; } // fwrite(&bricktex[boff.z+z][boff.y+y][boff.x], // sizeof(float4)*B_SIZE, 1, fptr); } } strm.next_in = in; strm.avail_in = inoff; do{ strm.avail_out = CHUNK; strm.next_out = out; ret = deflate(&strm, Z_FINISH); // assert(ret != Z_STREAM_ERROR); have = CHUNK - strm.avail_out; fwrite(out, have, 1, fptr); } while (strm.avail_out == 0); // assert(strm.avail_in == 0); deflateEnd(&strm); // fwrite(bricktex, 16*B_CUBE, 1, fptr); // fwrite(bricktex[B_EDGE], 16*B_CUBE, 1, fptr); fclose(fptr); }
/** * \brief executes a lookup query on octopus to obtain the symbol * * \param binary name of the binary to query * \param idx index of the symbol to query * \param ret_name returns the name of the symbol * \param ret_addr returns the address of the symbol * * \return */ errval_t spawn_symval_lookup(const char *binary, uint32_t idx, char **ret_name, genvaddr_t *ret_addr) { errval_t err; size_t len; len = snprintf(NULL, 0, "%s.omp.%"PRIu32, binary, idx); char *omp_entry = malloc(len+1); if (omp_entry == NULL) { return LIB_ERR_MALLOC_FAIL; } snprintf(omp_entry, len+1, "%s.omp.%"PRIu32, binary, idx); struct octopus_rpc_client *r = get_octopus_rpc_client(); if (r == NULL) { return LIB_ERR_NAMESERVICE_NOT_BOUND; } // transform to lower case for (int i = 0; i < len; ++i) { if (omp_entry[i] >= 'A' && omp_entry[i] <= 'Z') { omp_entry[i] -= ('A' - 'a'); } } char* record = NULL; octopus_trigger_id_t tid; errval_t error_code; err = r->vtbl.get(r, omp_entry, NOP_TRIGGER, &record, &tid, &error_code); if (err_is_fail(err)) { goto out; } err = error_code; if (err_is_fail(err)) { if (err_no(err) == OCT_ERR_NO_RECORD) { err = err_push(err, LIB_ERR_NAMESERVICE_UNKNOWN_NAME); } goto out; } uint64_t addr = 0; char *symname = NULL; err = oct_read(record, "_ { sym: %s, addr: %d }", &symname, &addr); if (err_is_fail(err) || symname == NULL) { err = err_push(err, LIB_ERR_NAMESERVICE_INVALID_NAME); goto out; } if (ret_addr != NULL) { *ret_addr = addr; } if (ret_name != NULL) { *ret_name = strdup(symname); } out: free(record); free(omp_entry); return err; }