void *Thread2(void *x) { Global++; barrier_wait(&barrier); return NULL; }
void *Thread1(void *x) { barrier_wait(&barrier); __atomic_fetch_add(&Global, 1, __ATOMIC_RELAXED); return NULL; }
void *Thread(void *a) { barrier_wait(&barrier); __atomic_fetch_add((int*)a, 1, __ATOMIC_SEQ_CST); return 0; }
int main() { int i, c, pID, handle; struct barrier_d b; void *mem; volatile int *ptr; long long cnt; unsigned long long t1, t2, dt, t_min, t_max, t_sum; int histogram[HISTOGRAM_SIZE]; #ifdef ARCH_X86 /* change previledge level */ iopl(3); #endif handle = rtipc_create_handle(); if ((c = fork()) == 0) { pID = 1; } else { pID = 0; } osfunctions_mLockAll(); if (pID == 0) { if (osfunctions_movetocpu(0) == -1) printf("PROC %d: cannot move to cpu %d\n", pID, 0); } else { if (osfunctions_movetocpu(1) == -1) printf("PROC %d: cannot move to cpu %d\n", pID, 1); } if (osfunctions_setMaxPriority() == -1) printf("PROC %d: cannot set priority\n", pID); if (rtipc_initialize(handle) == -1) { printf("PROC %d: rtipc_initialize() failed\n", pID); return 0; } if (barrier_get(&b, SHMID_BARRIER, 2) == -1) { printf("PROC %d: barrier_get() failed\n", pID); return 0; } /* get the shared memory segment */ if (shmman_get_shmseg(SHMID_SHMSEG, 1024, &mem)) { printf("PROC %d: shmman_getshm_seg() failed\n", pID); return 0; } ptr = (volatile int *)mem; *ptr = 0; *(ptr + 1) = 0; for (i = 0; i < HISTOGRAM_SIZE; i++) histogram[i] = 0; t_max = 0; t_min = 0xffffffffffffffff; t_sum = 0; barrier_wait(&b); #ifdef ARCH_X86 hwfunctions_cli(); #endif if (pID == 0) { cnt = 0; while(cnt < NUM_ITERATION) { *(ptr) = cnt + 1; #ifdef ARCH_X86 t1 = read_tsc(); #endif while(*(ptr + 1) != cnt + 1) hwfunctions_nop(); #ifdef ARCH_X86 t2 = read_tsc(); #endif if (cnt >= 100) { dt = t2 - t1; if(dt > t_max) t_max = dt; if(dt < t_min) t_min = dt; t_sum += dt; histogram[(((dt / HISTOGRAM_STEP) < HISTOGRAM_SIZE) && (dt > 0)) ? (dt / HISTOGRAM_STEP) : (HISTOGRAM_SIZE - 1)]++; } cnt++; } } else { cnt = 0; while(cnt < NUM_ITERATION) { while(*(ptr) != cnt + 1) hwfunctions_nop(); *(ptr + 1) = cnt + 1; cnt++; } } barrier_wait(&b); if (pID == 0) { printf("min: %llu, max: %llu, avrg: %llu, num interation: %d\n", t_min, t_max, t_sum / (NUM_ITERATION - 100), NUM_ITERATION - 100); printf("\n histogram \n range (cycles) \t\t abs. frequency\n"); for (i = 0; i < HISTOGRAM_SIZE - 1; i++) printf("%d \t <= # < \t %d :\t %d\n", i * HISTOGRAM_STEP, (i + 1) * HISTOGRAM_STEP, histogram[i]); printf("%d \t <= # \t\t :\t %d\n", (HISTOGRAM_SIZE - 1) * HISTOGRAM_STEP, histogram[HISTOGRAM_SIZE - 1]); } #ifdef ARCH_X86 hwfunctions_sti(); #endif barrier_release(&b); shmman_release_shmseg(SHMID_SHMSEG); if (pID == 0) rtipc_finalize(); return 0; }
void *Thread1(void *x) { barrier_wait(&barrier); Global.a = 42; return x; }
void pcu_thread_barrier(void) { barrier_wait(&global_barrier); }
int main(int argc, char *argv[]) { int backlog = 10; muxer_t *muxers[2] = {NULL, NULL}; status_writer_t *sw = NULL; child_t *child = NULL; int child_status = -1; int ring_buffer_size = 65535; int fds[3] = {-1, -1, -1}; int ii = 0, exit_status = 0, nwritten = 0; pthread_t sw_thread, muxer_threads[2]; char socket_paths[3][PATH_MAX + 1]; char *socket_names[3] = { "stdout.sock", "stderr.sock", "status.sock" }; barrier_t *barrier = NULL; if (argc < 3) { fprintf(stderr, "Usage: %s <socket directory> <cmd>\n", argv[0]); exit(EXIT_FAILURE); } printf("Usage: %s <socket directory> = %s <cmd> = %s \n" , argv[0],argv[1],argv[2]); fflush(stdout); /* Setup listeners on domain sockets */ for (ii = 0; ii < 3; ++ii) { memset(socket_paths[ii], 0, sizeof(socket_paths[ii])); nwritten = snprintf(socket_paths[ii], sizeof(socket_paths[ii]), "%s/%s", argv[1], socket_names[ii]); if (nwritten >= sizeof(socket_paths[ii])) { fprintf(stderr, "Socket path too long\n"); exit_status = 1; goto cleanup; } fds[ii] = create_unix_domain_listener(socket_paths[ii], backlog); DLOG("created listener, path=%s fd=%d", socket_paths[ii], fds[ii]); if (-1 == fds[ii]) { perrorf("Failed creating socket at %s:", socket_paths[ii]); exit_status = 1; goto cleanup; } set_cloexec(fds[ii]); } /* * Make sure iomux-spawn runs in an isolated process group such that * it is not affected by signals sent to its parent's process group. */ setsid(); child = child_create(argv + 2, argc - 2); printf("child_pid=%d\n", child->pid); fflush(stdout); /* Muxers for stdout/stderr */ muxers[0] = muxer_alloc(fds[0], child->stdout[0], ring_buffer_size); muxers[1] = muxer_alloc(fds[1], child->stderr[0], ring_buffer_size); for (ii = 0; ii < 2; ++ii) { if (pthread_create(&muxer_threads[ii], NULL, run_muxer, muxers[ii])) { perrorf("Failed creating muxer thread:"); exit_status = 1; goto cleanup; } DLOG("created muxer thread for socket=%s", socket_paths[ii]); } /* Status writer */ barrier = barrier_alloc(); sw = status_writer_alloc(fds[2], barrier); if (pthread_create(&sw_thread, NULL, run_status_writer, sw)) { perrorf("Failed creating muxer thread:"); exit_status = 1; goto cleanup; } /* Wait for clients on stdout, stderr, and status */ for (ii = 0; ii < 2; ++ii) { muxer_wait_for_client(muxers[ii]); } barrier_wait(barrier); child_continue(child); printf("child active\n"); fflush(stdout); if (-1 == waitpid(child->pid, &child_status, 0)) { perrorf("Waitpid for child failed: "); exit_status = 1; goto cleanup; } DLOG("child exited, status = %d", WEXITSTATUS(child_status)); /* Wait for status writer */ status_writer_finish(sw, child_status); pthread_join(sw_thread, NULL); /* Wait for muxers */ for (ii = 0; ii < 2; ++ii) { muxer_stop(muxers[ii]); pthread_join(muxer_threads[ii], NULL); } DLOG("all done, cleaning up and exiting"); cleanup: if (NULL != child) { child_free(child); } if (NULL != barrier) { barrier_free(barrier); } if (NULL != sw) { status_writer_free(sw); } for (ii = 0; ii < 2; ++ii) { if (NULL != muxers[ii]) { muxer_free(muxers[ii]); } } /* Close accept sockets and clean up paths */ for (ii = 0; ii < 3; ++ii) { if (-1 != fds[ii]) { close(fds[ii]); unlink(socket_paths[ii]); } } return exit_status; }
int main() { int i, pID, handle, cpu; struct barrier_d b; sensorbuffer_d_t sb; void *data; data = malloc(sizeof(BUFFER_SIZE)); handle = rtipc_create_handle(); /* fork one process */ if (fork() == 0) { pID = 1; /* child */ cpu = 1; } else { pID = 0; cpu = 0; } /* set CPUs to run on */ if (osfunctions_movetocpu(cpu) == -1) printf("Proc %d: cannot move to CPU %d\n", pID, cpu); /* initialize librtipc */ rtipc_initialize(handle); /* get barrier */ if (barrier_get(&b, SHMID_BARRIER, 2) == -1) { printf("Proc %d: barrier_get() failed\n", pID); return 0; } /* get to the buffer */ if (sensorbuffer_get(&sb, SHMID_SENSORBUFFER, BUFFER_SIZE, NUM_BUFFER) == -1) { printf("Proc %d: sensorbuffer_get() failed\n", pID); return 0; } else { printf("Proc %d: sensorbuffer_get() successful\n", pID); } /* sync */ barrier_wait(&b); if (pID == 0) { for (i = 0; i < NUM_ITERATION; i++) { *((int *)data) = i; sensorbuffer_update(&sb, data); printf("wrote %d\n", *((int *)data)); usleep(100000); } } else { for (i = 0; i < NUM_ITERATION; i++) { while(sensorbuffer_read(&sb, data) == -1); /* repeat until first element was inserted to buffer */ printf("read buffer: %d\n", *((int *)data)); usleep(370000); } } /* sync */ barrier_wait(&b); sensorbuffer_release(&sb); barrier_release(&b); /* stop librtipc */ if (pID == 0) rtipc_finalize(); printf("Proc %d: finished\n", pID); return 0; }
//main work function for each thread void * do_thread_work (void * _id) { int id = (int) _id; int tstep, i; cpu_set_t mask; CPU_ZERO( &mask ); #ifdef WITH_SMT CPU_SET( id*2, &mask ); #else CPU_SET( id, &mask ); #endif sched_setaffinity(0, sizeof(mask), &mask); for ( tstep=0; tstep< NUMBER_TIMESTEPS; tstep++) { barrier_wait (&barrier); //need to reset these global vars in the beginning of every timestep //global vars, need to be protected if (id == 0) { vir = 0.0; epot = 0.0; ekin = 0.0; vel = 0.0; count = 0.0; } //because we have this barrier here, we don't need one at the end of //each timestep; this barrier effectively acts as if it was at the end; //we need it here because we need to perform the initializations above //at the _beginning_ of each timestep. //No, you need a barrier at the end, as well, because if you only have one //here but not at the end, you may reset some of the above global vars //while a slower thread is still computing stuff in the previous timestep... //I'm not sure, but we may be able to replace this barrier with just //asm volatile("mfence" ::: "memory"); barrier_wait (&barrier); //UpdateCoordinates (NULL, id); //PARALLEL_EXECUTE( NTHREADS, UpdateCoordinates, NULL ); //barrier_wait (&barrier); if ( tstep % neighUpdate == 0) { //this barrier needed because of the single-threaded code below barrier_wait (&barrier); if (id == 0) { #ifdef PRINT_COORDINATES PrintCoordinates(numMoles); #endif //global var, needs to be protected ninter = 0; } //this barrier needed because of the single-threaded code above barrier_wait (&barrier); BuildNeigh (NULL, id); //PARALLEL_EXECUTE( NTHREADS, BuildNeigh, NULL ); //this barrier needed because of the single-threaded code below barrier_wait (&barrier); if (id == 0) { #ifdef PRINT_INTERACTION_LIST PrintInteractionList(INPARAMS ninter); #endif #ifdef MEASURE PrintConnectivity(); #endif } //we need this here because otherwise fast threads might start //changing the data that thread 0 is reading above while running //PrintInteractionList() and PrintConnectivity(). barrier_wait (&barrier); } ComputeForces (NULL, id); //PARALLEL_EXECUTE( NTHREADS, ComputeForces, NULL ); //this barrier disappears with relaxed predicated commits barrier_wait (&barrier); //UpdateVelocities (NULL, id); //PARALLEL_EXECUTE( NTHREADS, UpdateVelocities, NULL ); //this barrier disappears with relaxed predicated commits //barrier_wait (&barrier); //ComputeKEVel (NULL, id); //PARALLEL_EXECUTE( NTHREADS, ComputeKEVel, NULL ); //Mike: consolidated all update functions into 1 Update(NULL, id); //need a barrier at the end of each timestep barrier_wait (&barrier); if (id == 0) { PrintResults (INPARAMS tstep, (double)ekin, (double)epot, (double)vir,(double)vel,(double)count,numMoles,(int)ninter); } barrier_wait (&barrier); } return NULL; }
static void worker_runphase2(workqueue_t *wq) { tdata_t *pow1, *pow2; int batchid; for (;;) { pthread_mutex_lock(&wq->wq_queue_lock); if (wq->wq_ninqueue == 1) { pthread_cond_broadcast(&wq->wq_work_avail); pthread_mutex_unlock(&wq->wq_queue_lock); debug(2, "%d: entering p2 completion barrier\n", pthread_self()); if (barrier_wait(&wq->wq_bar1)) { pthread_mutex_lock(&wq->wq_queue_lock); wq->wq_alldone = 1; pthread_cond_signal(&wq->wq_alldone_cv); pthread_mutex_unlock(&wq->wq_queue_lock); } return; } if (fifo_len(wq->wq_queue) < 2) { pthread_cond_wait(&wq->wq_work_avail, &wq->wq_queue_lock); pthread_mutex_unlock(&wq->wq_queue_lock); continue; } /* there's work to be done! */ pow1 = fifo_remove(wq->wq_queue); pow2 = fifo_remove(wq->wq_queue); wq->wq_ninqueue -= 2; batchid = wq->wq_next_batchid++; pthread_mutex_unlock(&wq->wq_queue_lock); debug(2, "%d: merging %p into %p\n", pthread_self(), (void *)pow1, (void *)pow2); merge_into_master(pow1, pow2, NULL, 0); tdata_free(pow1); /* * merging is complete. place at the tail of the queue in * proper order. */ pthread_mutex_lock(&wq->wq_queue_lock); while (wq->wq_lastdonebatch + 1 != batchid) { pthread_cond_wait(&wq->wq_done_cv, &wq->wq_queue_lock); } wq->wq_lastdonebatch = batchid; fifo_add(wq->wq_queue, pow2); debug(2, "%d: added %p to queue, len now %d, ninqueue %d\n", pthread_self(), (void *)pow2, fifo_len(wq->wq_queue), wq->wq_ninqueue); pthread_cond_broadcast(&wq->wq_done_cv); pthread_cond_signal(&wq->wq_work_avail); pthread_mutex_unlock(&wq->wq_queue_lock); } }
void *Thread2(void *x) { barrier_wait(&barrier); close(fds[0]); close(fds[1]); return NULL; }
void *Thread1(void *x) { write(fds[1], "a", 1); barrier_wait(&barrier); return NULL; }
void *Thread2(void *x) { bar2(); barrier_wait(&barrier); return NULL; }
void *Thread1(void *x) { barrier_wait(&barrier); bar1(); return NULL; }
/*********************************************************************** do nothing! ************************************************************************/ static void *test_noop(int id) { barrier_wait(&barriers[0]); barrier_wait(&barriers[1]); return NULL; }