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; }
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 }