/** * \brief Client enters a barrier. Blocks until all clients have entered the * barrier. * * Each client creates a (sequential record) based on the provided name. * Once a client sees the specified amount (wait_for) of records it * creates a record that wakes up all waiting clients. * * \param[in] name Name of the barrier. * \param[out] barrier_record Record created for each client. * \param[in] wait_for Number of clients entering the barrier. */ errval_t oct_barrier_enter(const char* name, char** barrier_record, size_t wait_for) { errval_t err; errval_t exist_err; char* record = NULL; char** names = NULL; uint64_t mode = 0; uint64_t state = 0; uint64_t fn = 0; octopus_trigger_id_t tid; size_t current_barriers = 0; octopus_trigger_t t = oct_mktrigger(OCT_ERR_NO_RECORD, octopus_BINDING_RPC, OCT_ON_SET, NULL, NULL); err = oct_set_get(SET_SEQUENTIAL, barrier_record, "%s_ { barrier: '%s' }", name, name); err = oct_get_names(&names, ¤t_barriers, "_ { barrier: '%s' }", name); oct_free_names(names, current_barriers); if (err_is_fail(err)) { return err; } //debug_printf("current_barriers: %lu wait_for: %lu\n", current_barriers, // wait_for); if (current_barriers != wait_for) { struct octopus_thc_client_binding_t* cl = oct_get_thc_client(); err = cl->call_seq.exists(cl, name, t, &tid, &exist_err); if (err_is_fail(err)) { return err; } err = exist_err; if (err_is_ok(err)) { // Barrier already exists } if (err_no(err) == OCT_ERR_NO_RECORD) { // Wait until barrier record is created err = cl->recv.trigger(cl, &tid, &fn, &mode, &record, &state); free(record); assert(mode & OCT_REMOVED); err = SYS_ERR_OK; } else { // Some other error happend, return it } } else { // We are the last to enter the barrier, // wake up the others err = oct_set(name); } return err; }
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; }
static void spawnd_change_event(octopus_mode_t mode, char* record, void* state) { size_t count = (size_t) state; static coreid_t spawnd_counter = 0; if (mode & OCT_ON_SET) { KALUGA_DEBUG("spawnd found: %s\n", record); spawnd_counter++; if (spawnd_counter == count) { KALUGA_DEBUG("Found enough spawnds, setting all_spawnds_up\n"); errval_t err = oct_set("all_spawnds_up { iref: 0 }"); assert(err_is_ok(err)); } } }
int main(int argc, char** argv) { vfs_init(); init_environ(); errval_t err; my_core_id = disp_get_core_id(); parse_arguments(argc, argv); err = oct_init(); if (err_is_fail(err)) { USER_PANIC_ERR(err, "Initialize octopus service."); } KALUGA_DEBUG("Kaluga: parse boot modules...\n"); err = init_boot_modules(); if (err_is_fail(err)) { USER_PANIC_ERR(err, "Parse boot modules."); } add_start_function_overrides(); #ifdef __x86__ // We need to run on core 0 // (we are responsible for booting all the other cores) assert(my_core_id == BSP_CORE_ID); KALUGA_DEBUG("Kaluga running on x86.\n"); err = skb_client_connect(); if (err_is_fail(err)) { USER_PANIC_ERR(err, "Connect to SKB."); } // Make sure the driver db is loaded err = skb_execute("[device_db]."); if (err_is_fail(err)) { USER_PANIC_ERR(err, "Device DB not loaded."); } // The current boot protocol needs us to have // knowledge about how many CPUs are available at boot // time in order to start-up properly. char* record = NULL; err = oct_barrier_enter("barrier.acpi", &record, 2); KALUGA_DEBUG("Kaluga: watch_for_cores\n"); err = watch_for_cores(); if (err_is_fail(err)) { USER_PANIC_ERR(err, "Watching cores."); } KALUGA_DEBUG("Kaluga: pci_root_bridge\n"); err = watch_for_pci_root_bridge(); if (err_is_fail(err)) { USER_PANIC_ERR(err, "Watching PCI root bridges."); } KALUGA_DEBUG("Kaluga: pci_devices\n"); err = watch_for_pci_devices(); if (err_is_fail(err)) { USER_PANIC_ERR(err, "Watching PCI devices."); } KALUGA_DEBUG("Kaluga: wait_for_all_spawnds\n"); err = wait_for_all_spawnds(); if (err_is_fail(err)) { USER_PANIC_ERR(err, "Unable to wait for spawnds failed."); } #elif __pandaboard__ debug_printf("Kaluga running on Pandaboard.\n"); err = init_cap_manager(); assert(err_is_ok(err)); err = oct_set("all_spawnds_up { iref: 0 }"); assert(err_is_ok(err)); struct module_info* mi = find_module("fdif"); if (mi != NULL) { err = mi->start_function(0, mi, "hw.arm.omap44xx.fdif {}"); assert(err_is_ok(err)); } mi = find_module("mmchs"); if (mi != NULL) { err = mi->start_function(0, mi, "hw.arm.omap44xx.mmchs {}"); assert(err_is_ok(err)); } mi = find_module("mmchs2"); if (mi != NULL) { err = mi->start_function(0, mi, "hw.arm.omap44xx.mmchs {}"); assert(err_is_ok(err)); } mi = find_module("prcm"); if (mi != NULL) { err = mi->start_function(0, mi, "hw.arm.omap44xx.prcm {}"); assert(err_is_ok(err)); } mi = find_module("serial"); if (mi != NULL) { err = mi->start_function(0, mi, "hw.arm.omap44xx.uart {}"); assert(err_is_ok(err)); } mi = find_module("sdma"); if (mi != NULL) { err = mi->start_function(0, mi, "hw.arm.omap44xx.sdma {}"); assert(err_is_ok(err)); } mi = find_module("usb_manager"); if (mi != NULL) { #define USB_ARM_EHCI_IRQ 109 char *buf = malloc(255); uint8_t offset = 0; mi->cmdargs = buf; mi->argc = 3; mi->argv[0] = mi->cmdargs + 0; snprintf(buf + offset, 255 - offset, "ehci\0"); offset += strlen(mi->argv[0]) + 1; mi->argv[1] = mi->cmdargs + offset; snprintf(buf + offset, 255 - offset, "%u\0", 0xC00); offset += strlen(mi->argv[1]) + 1; mi->argv[2] = mi->cmdargs + offset; snprintf(buf+offset, 255-offset, "%u\0", USB_ARM_EHCI_IRQ); // XXX Use customized start function or add to module info err = mi->start_function(0, mi, "hw.arm.omap44xx.usb {}"); assert(err_is_ok(err)); } #elif __gem5__ printf("Kaluga running on GEM5 armv8.\n"); err = init_cap_manager(); assert(err_is_ok(err)); err = oct_set("all_spawnds_up { iref: 0 }"); assert(err_is_ok(err)); struct module_info* mi = find_module("serial"); if (mi != NULL) { err = mi->start_function(0, mi, "hw.arm.gem5.uart {}"); assert(err_is_ok(err)); } #endif THCFinish(); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { oct_init(); errval_t err = SYS_ERR_OK; octopus_trigger_id_t tid; size_t received = 0; err = oct_set("obj1 { attr: 1 }"); ASSERT_ERR_OK(err); err = oct_set("obj2 { attr: 2 }"); ASSERT_ERR_OK(err); err = oct_set("obj3 { attr: 3 }"); ASSERT_ERR_OK(err); struct octopus_thc_client_binding_t* c = oct_get_thc_client(); octopus_trigger_t record_deleted = oct_mktrigger(SYS_ERR_OK, octopus_BINDING_EVENT, OCT_ON_DEL, trigger_handler, &received); errval_t error_code = SYS_ERR_OK; char* output = NULL; err = c->call_seq.get(c, "r'^obj.$' { attr: 3 } ", record_deleted, &output, &tid, &error_code); ASSERT_ERR_OK(err); ASSERT_ERR_OK(error_code); ASSERT_STRING(output, "obj3 { attr: 3 }"); debug_printf("tid is: %lu\n", tid); free(output); oct_del("obj3"); while (received != 1) { messages_wait_and_handle_next(); } received = 0; tid = 0; octopus_mode_t m = OCT_ON_SET | OCT_ON_DEL | OCT_PERSIST; octopus_trigger_t ptrigger = oct_mktrigger(SYS_ERR_OK, octopus_BINDING_EVENT, m, persistent_trigger, &received); output = NULL; err = c->call_seq.get(c, "obj2", ptrigger, &output, &tid, &error_code); ASSERT_ERR_OK(err); ASSERT_ERR_OK(error_code); debug_printf("tid is: %lu\n", tid); ASSERT_STRING(output, "obj2 { attr: 2 }"); oct_del("obj2"); while (received != 1) { messages_wait_and_handle_next(); } received = 0; oct_set("obj2 { attr: 'asdf' }"); while (received != 1) { messages_wait_and_handle_next(); } received = 0; err = oct_remove_trigger(tid); DEBUG_ERR(err, "remove trigger"); ASSERT_ERR_OK(err); while (received != 1) { messages_wait_and_handle_next(); } printf("d2trigger SUCCESS!\n"); return EXIT_SUCCESS; }