int main(int argc, char *argv[]) { assert(argc >= 2); errval_t err = SYS_ERR_OK; oct_init(); size_t wait_for = atoi(argv[1]); char* record = NULL; debug_printf("Barrier test with: %lu processes:\n", wait_for); err = oct_barrier_enter("my_barrier", &record, wait_for); if(err_is_ok(err)) { debug_printf("Execute Barrier code section\n"); debug_printf("Barrier record is: %s\n", record); } else { DEBUG_ERR(err, "Barrier enter fail."); abort(); } err = oct_barrier_leave(record); ASSERT_ERR_OK(err); debug_printf("Process no longer inside barrier.\n"); free(record); return EXIT_SUCCESS; }
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; }
void shl_barrier_shm(int b_count) { #if 0 #if defined(QRM_DBG_ENABLED) assert(_shl_round<QRM_ROUND_MAX); #endif #if 0 assert (!"Not tested with overflow"); // ////////////////////////////////////////////////// // SPINLOCK (disabled) // ////////////////////////////////////////////////// volatile uint8_t *ptr = &(get_master_share()->data.rounds[round]); // Increment counter acquire_spinlock(&get_master_share()->data.lock); *ptr += 1; QDBG("SPINLOCK: core %d waiting in round %d ptr %d\n", get_thread_id(), round, *ptr); release_spinlock(&get_master_share()->data.lock); // Wait until counter reached number of cores int i = 0; while (*ptr<b_count) { // Yield every now and then .. if (i++ >2000) { /* thread_yield(); */ i = 0; } } QDBG("SPINLOCK: core %d leaving in round %d ptr %d\n", get_thread_id(), round, *ptr); #elif 1 // ////////////////////////////////////////////////// // Atomic increment // ////////////////////////////////////////////////// #if defined(QRM_DBG_ENABLED) if (get_master_share()==NULL) { printf("cb: quorum %p %p\n", __builtin_return_address(0), __builtin_return_address(1)); } assert(get_master_share()!=NULL); #endif volatile uint8_t *ptr = &(get_master_share()->data.rounds[_shl_round]); #if defined(QRM_DBG_ENABLED) uint8_t val = #endif __sync_add_and_fetch(ptr, 1); debug_printfff(DBG__QRM_BARRIER, "qrm_barrier: core %d value %d waiting for %d round %d\n", get_thread_id(), val, b_count, _shl_round); #ifdef SIMULATOR uint64_t i = 1; #endif while (*ptr<b_count) { #ifdef SIMULATOR // Sleep every now and then .. we should remove this later on // We should use this only when running in the SIMULATOR // qemu run's nicely when one physical core is simulated by // each hyperthread, unless they are spinning on a memory // location. if ((++i)%100000 == 0) { thread_yield(); } #endif } // Everyone passed the barrier, and is working on the next // one. Access to this barriers counter is save now to the // coordinator, which can reset it's value to 0. if (get_thread_id()==get_sequentializer()) { unsigned _tmp = (_shl_round+QRM_ROUND_MAX-1)%QRM_ROUND_MAX; get_master_share()->data.rounds[_tmp] = 0; } debug_printfff(DBG__QRM_BARRIER, "qrm_barrier done\n"); #else assert (!"Overflow of round will not work"); // ////////////////////////////////////////////////// // Octopus // ////////////////////////////////////////////////// char *dummy; char name[100]; sprintf(name, "qrm_exp_round_%d", round); oct_barrier_enter(name, &dummy, b_count); oct_barrier_leave(dummy); #endif _shl_round = (_shl_round+1) % QRM_ROUND_MAX; #endif }