/* * The main program to "drive" the crew... */ int main (int argc, char *argv[]) { crew_t my_crew; char line[128], *next; int status; if (argc < 3) { fprintf (stderr, "Usage: %s string path\n", argv[0]); return -1; } #ifdef sun /* * On Solaris 2.5, threads are not timesliced. To ensure * that our threads can run concurrently, we need to * increase the concurrency level to CREW_SIZE. */ DPRINTF (("Setting concurrency level to %d\n", CREW_SIZE)); thr_setconcurrency (CREW_SIZE); #endif status = crew_create (&my_crew, CREW_SIZE); if (status != 0) err_abort (status, "Create crew"); status = crew_start (&my_crew, argv[2], argv[1]); if (status != 0) err_abort (status, "Start crew"); return 0; }
/* * Collect the result of the pipeline. Wait for a * result if the pipeline hasn't produced one. */ int pipe_result (pipe_t *pipe, long *result) { stage_t *tail = pipe->tail; long value; int empty = 0; int status; status = pthread_mutex_lock (&pipe->mutex); if (status != 0) err_abort (status, "Lock pipe mutex"); if (pipe->active <= 0) empty = 1; else pipe->active--; status = pthread_mutex_unlock (&pipe->mutex); if (status != 0) err_abort (status, "Unlock pipe mutex"); if (empty) return 0; pthread_mutex_lock (&tail->mutex); while (!tail->data_ready) pthread_cond_wait (&tail->avail, &tail->mutex); *result = tail->data; tail->data_ready = 0; pthread_cond_signal (&tail->ready); pthread_mutex_unlock (&tail->mutex); return 1; }
/* * Wait for the SIGINT signal. When it has occurred 5 times, set * the "interrupted" flag (the main thread's wait predicate) and * signal a condition variable. The main thread will exit. */ void *signal_waiter (void *arg) { int sig_number; int signal_count = 0; int status; while (1) { sigwait (&signal_set, &sig_number); if (sig_number == SIGINT) { printf ("Got SIGINT (%d of 5)\n", signal_count+1); if (++signal_count >= 5) { status = pthread_mutex_lock (&mutex); if (status != 0) err_abort (status, "Lock mutex"); interrupted = 1; status = pthread_cond_signal (&cond); if (status != 0) err_abort (status, "Signal condition"); status = pthread_mutex_unlock (&mutex); if (status != 0) err_abort (status, "Unlock mutex"); break; } } } return NULL; }
void *startthread(void *p) { AsyncRead *aw = (AsyncRead *)p; //printf("startthread: aw->filesdim = %p %d\n", aw, aw->filesdim); size_t dim = aw->filesdim; for (size_t i = 0; i < dim; i++) { FileData *f = &aw->files[i]; f->result = f->file->read(); // Set event int status = pthread_mutex_lock(&f->mutex); if (status != 0) err_abort(status, "lock mutex"); f->value = 1; status = pthread_cond_signal(&f->cond); if (status != 0) err_abort(status, "signal condition"); status = pthread_mutex_unlock(&f->mutex); if (status != 0) err_abort(status, "unlock mutex"); } return NULL; // end thread }
/* * The thread start routine for pipe stage threads. * Each will wait for a data item passed from the * caller or the previous stage, modify the data * and pass it along to the next (or final) stage. */ void *pipe_stage (void *arg) { stage_t *stage = (stage_t*)arg; stage_t *next_stage = stage->next; int status; status = pthread_mutex_lock (&stage->mutex); if (status != 0) err_abort (status, "Lock pipe stage"); while (1) { while (stage->data_ready != 1) { status = pthread_cond_wait (&stage->avail, &stage->mutex); if (status != 0) err_abort (status, "Wait for previous stage"); } pipe_send (next_stage, stage->data + 1); stage->data_ready = 0; status = pthread_cond_signal (&stage->ready); if (status != 0) err_abort (status, "Wake next stage"); } /* * Notice that the routine never unlocks the stage->mutex. * The call to pthread_cond_wait implicitly unlocks the * mutex while the thread is waiting, allowing other threads * to make progress. Because the loop never terminates, this * function has no need to unlock the mutex explicitly. */ return NULL; }
/* * Client routine -- multiple copies will request server. */ void *client_routine (void *arg) { int my_number = (int)arg, loops; char prompt[32]; char string[128], formatted[128]; int status; sprintf (prompt, "Client %d> ", my_number); while (1) { tty_server_request (REQ_READ, 1, prompt, string); if (strlen (string) == 0) break; for (loops = 0; loops < 4; loops++) { sprintf ( formatted, "(%d#%d) %s", my_number, loops, string); tty_server_request (REQ_WRITE, 0, NULL, formatted); sleep (1); } } status = pthread_mutex_lock (&client_mutex); if (status != 0) err_abort (status, "Lock client mutex"); client_threads--; if (client_threads <= 0) { status = pthread_cond_signal (&clients_done); if (status != 0) err_abort (status, "Signal clients done"); } status = pthread_mutex_unlock (&client_mutex); if (status != 0) err_abort (status, "Unlock client mutex"); return NULL; }
int main (int argc, char *argv[]) { pthread_t thread_id[THREADS]; int count; void *result; int status; for (count = 0; count < THREADS; count++) { status = pthread_create ( &thread_id[count], NULL, thread_routine, NULL); if (status != 0) err_abort (status, "Create thread"); } sleep (2); for (count = 0; count < THREADS; count++) { status = pthread_cancel (thread_id[count]); if (status != 0) err_abort (status, "Cancel thread"); status = pthread_join (thread_id[count], &result); if (status != 0) err_abort (status, "Join thread"); if (result == PTHREAD_CANCELED) printf ("thread %d cancelled\n", count); else printf ("thread %d was not cancelled\n", count); } return 0; }
int main (int argc, char *argv[]) { pthread_t thread_id; int status; #ifdef sun /* * On Solaris 2.5, threads are not timesliced. To ensure * that our threads can run concurrently, we need to * increase the concurrency level to at least 2 plus THREADS * (the number of workers). */ DPRINTF (("Setting concurrency level to %d\n", THREADS+2)); thr_setconcurrency (THREADS+2); #endif status = pthread_create (&thread_id, NULL, thread_routine, NULL); if (status != 0) err_abort (status, "Create team"); sleep (5); printf ("Cancelling...\n"); status = pthread_cancel (thread_id); if (status != 0) err_abort (status, "Cancel team"); status = pthread_join (thread_id, NULL); if (status != 0) err_abort (status, "Join team"); }
/* * External interface to create a pipeline. All the * data is initialized and the threads created. They'll * wait for data. */ int pipe_create (pipe_t *pipe, int stages) { int pipe_index; stage_t **link = &pipe->head, *new_stage, *stage; int status; status = pthread_mutex_init (&pipe->mutex, NULL); if (status != 0) err_abort (status, "Init pipe mutex"); pipe->stages = stages; pipe->active = 0; for (pipe_index = 0; pipe_index <= stages; pipe_index++) { new_stage = (stage_t*)malloc (sizeof (stage_t)); if (new_stage == NULL) errno_abort ("Allocate stage"); status = pthread_mutex_init (&new_stage->mutex, NULL); if (status != 0) err_abort (status, "Init stage mutex"); status = pthread_cond_init (&new_stage->avail, NULL); if (status != 0) err_abort (status, "Init avail condition"); status = pthread_cond_init (&new_stage->ready, NULL); if (status != 0) err_abort (status, "Init ready condition"); new_stage->data_ready = 0; *link = new_stage; link = &new_stage->next; } *link = (stage_t*)NULL; /* Terminate list */ pipe->tail = new_stage; /* Record the tail */ /* * Create the threads for the pipe stages only after all * the data is initialized (including all links). Note * that the last stage doesn't get a thread, it's just * a receptacle for the final pipeline value. * * At this point, proper cleanup on an error would take up * more space than worthwhile in a "simple example", so * instead of cancelling and detaching all the threads * already created, plus the synchronization object and * memory cleanup done for earlier errors, it will simply * abort. */ for ( stage = pipe->head; stage->next != NULL; stage = stage->next) { status = pthread_create ( &stage->thread, NULL, pipe_stage, (void*)stage); if (status != 0) err_abort (status, "Create pipe stage"); } return 0; }
/*---------------------------------------------------------------------------- CSP_altClose Shuts down the alternative structure after use. CSP_Alt_t * alt : pointer to an alternative structure */ void CSP_altClose (CSP_Alt_t * alt) { int status; status = pthread_mutex_destroy (&(alt->altMx)); if (status != 0) { err_abort (status, "destroy mutex", __LINE__); } status = pthread_cond_destroy (&(alt->altSync)); if (status != 0) { err_abort (status, "destroy meet", __LINE__); } }
/*---------------------------------------------------------------------------- CSP_altInit Initialises the alternative structure before it can be used in CSP_priAltSelect. CSP_Alt_t * alt : pointer to an alternative structure */ void CSP_altInit (CSP_Alt_t * alt) { int status; status = pthread_mutex_init (&(alt->altMx), NULL); if (status != 0) { err_abort (status, "init mutex", __LINE__); } status = pthread_cond_init (&(alt->altSync), NULL); if (status != 0) { err_abort (status, "init meet", __LINE__); } }
int main(int argc, char *argv[]) { int version; void *thread_result; long status; pthread_t repl_thread_id; pthread_t web_thread_id; pthread_mutex_t main_mutex = PTHREAD_MUTEX_INITIALIZER; lua_State *L_main; /* * Set up lua state with data at specified version */ if (argc < 2) { printf("Usage: qplan <version>\n"); return 1; } version = strtol(argv[1], NULL, 0); L_main = init_lua_state(version); /* * Set up context and spin up threads */ QPlanContext qplan_context; qplan_context.main_lua_state = L_main; qplan_context.main_mutex = &main_mutex; /* Create REPL thread */ status = pthread_create(&repl_thread_id, NULL, repl_routine, (void *)&qplan_context); if (status != 0) err_abort(status, "Create repl thread"); /* Create web server thread */ status = pthread_create(&web_thread_id, NULL, web_routine, (void *)&qplan_context); if (status != 0) err_abort(status, "Create web thread"); status = pthread_detach(web_thread_id); if (status != 0) err_abort(status, "Problem detaching web thread"); /* Join REPL thread */ status = pthread_join(repl_thread_id, &thread_result); if (status != 0) err_abort(status, "Join thread"); /* * Clean up */ lua_close(L_main); printf("We are most successfully done!\n"); return 0; }
/* * External interface to start a pipeline by passing * data to the first stage. The routine returns while * the pipeline processes in parallel. Call the * pipe_result return to collect the final stage values * (note that the pipe will stall when each stage fills, * until the result is collected). */ int pipe_start (pipe_t *pipe, long value) { int status; status = pthread_mutex_lock (&pipe->mutex); if (status != 0) err_abort (status, "Lock pipe mutex"); pipe->active++; status = pthread_mutex_unlock (&pipe->mutex); if (status != 0) err_abort (status, "Unlock pipe mutex"); pipe_send (pipe->head, value); return 0; }
void AsyncRead::dispose(AsyncRead *aw) { //printf("AsyncRead::dispose()\n"); for (int i = 0; i < aw->filesdim; i++) { FileData *f = &aw->files[i]; int status = pthread_cond_destroy(&f->cond); if (status != 0) err_abort(status, "cond destroy"); status = pthread_mutex_destroy(&f->mutex); if (status != 0) err_abort(status, "mutex destroy"); } delete aw; }
int main (int argc, char *argv[]) { pthread_t thread1, thread2; int status; status = pthread_create ( &thread1, NULL, thread_routine, "thread 1"); if (status != 0) err_abort (status, "Create thread 1"); status = pthread_create ( &thread2, NULL, thread_routine, "thread 2"); if (status != 0) err_abort (status, "Create thread 2"); pthread_exit (NULL); }
int main (int argc, char *argv[]) { pthread_t signal_thread_id; int status; /* * Start by masking the "interesting" signal, SIGINT in the * initial thread. Because all threads inherit the signal mask * from their creator, all threads in the process will have * SIGINT masked unless one explicitly unmasks it. The * semantics of sigwait require that all threads (including * the thread calling sigwait) have the signal masked, for * reliable operation. Otherwise, a signal that arrives * while the sigwaiter is not blocked in sigwait might be * delivered to another thread. */ sigemptyset (&signal_set); sigaddset (&signal_set, SIGINT); status = pthread_sigmask (SIG_BLOCK, &signal_set, NULL); if (status != 0) err_abort (status, "Set signal mask"); /* * Create the sigwait thread. */ status = pthread_create (&signal_thread_id, NULL, signal_waiter, NULL); if (status != 0) err_abort (status, "Create sigwaiter"); /* * Wait for the sigwait thread to receive SIGINT and signal * the condition variable. */ status = pthread_mutex_lock (&mutex); if (status != 0) err_abort (status, "Lock mutex"); while (!interrupted) { status = pthread_cond_wait (&cond, &mutex); if (status != 0) err_abort (status, "Wait for interrupt"); } status = pthread_mutex_unlock (&mutex); if (status != 0) err_abort (status, "Unlock mutex"); printf ("Main terminating with SIGINT\n"); return 0; }
int main (int argc, char * argv[]) { int tstatus, nc = 0, ic; pthread_t produce_t, consume_t; char command, extra; pthread_t consumer_thread [MAX_CONSUMER]; /* Create the producer thread */ tstatus = pthread_create (&produce_t, NULL, Produce, NULL); if (tstatus != 0) err_abort (tstatus, "Cannot create producer thread"); /* Prompt the user to create a consumer or shutdown */ while (!mBlock.fStop) { /* This is the only thread accessing stdin, stdout */ printf ("\n**Enter 'c' for create consumer; 's' to stop: "); scanf ("%c%c", &command, &extra); if (command == 's') { pthread_mutex_lock (&mBlock.nGuard); mBlock.fStop = 1; pthread_cond_signal (&mBlock.mReady); pthread_mutex_unlock (&mBlock.nGuard); } else if (command == 'c' && nc < MAX_CONSUMER-1) { tstatus = pthread_create (&consumer_thread[nc++], NULL, Consume, &mBlock); if (tstatus != 0) err_abort (tstatus, "Cannot create consumer thread"); } else { printf ("Illegal command or too many consumers.\n"); } } printf ("\nConsumers will report their results and terminate\n\n"); /* Wait for the producer to terminate */ tstatus = pthread_join (produce_t, NULL); if (tstatus != 0) err_abort (tstatus, "Cannot join producer thread\n"); /* Wait for the consumer threads to complete */ for (ic = 0; ic < nc; ic++) { tstatus = pthread_join (consumer_thread[ic], NULL); if (tstatus != 0) err_abort (tstatus, "Cannot join consumer thread"); } printf ("Producer and consumer threads have terminated\n"); return 0; }
int main (int argc, char *argv[]) { int status; char line[128]; alarm_t *alarm; pthread_t thread; while (1) { printf ("Alarm> "); if (fgets (line, sizeof (line), stdin) == NULL) exit (0); if (strlen (line) <= 1) continue; alarm = (alarm_t*)malloc (sizeof (alarm_t)); if (alarm == NULL) errno_abort ("Allocate alarm"); /* * Parse input line into seconds (%d) and a message * (%64[^\n]), consisting of up to 64 characters * separated from the seconds by whitespace. */ if (sscanf (line, "%d %64[^\n]", &alarm->seconds, alarm->message) < 2) { fprintf (stderr, "Bad command\n"); free (alarm); } else { status = pthread_create ( &thread, NULL, alarm_thread, alarm); if (status != 0) err_abort (status, "Create alarm thread"); } } }
/* * Thread start routine that issues work queue requests. */ void *thread_routine (void *arg) { power_t *element; int count; unsigned int seed = (unsigned int)time (NULL); int status; /* * Loop, making requests. */ for (count = 0; count < ITERATIONS; count++) { element = (power_t*)malloc (sizeof (power_t)); if (element == NULL) errno_abort ("Allocate element"); element->value = rand_r (&seed) % 20; element->power = rand_r (&seed) % 7; DPRINTF (( "Request: %d^%d\n", element->value, element->power)); status = workq_add (&workq, (void*)element); if (status != 0) err_abort (status, "Add to work queue"); sleep (rand_r (&seed) % 5); } return NULL; }
/* * This is the routine called by the work queue servers to * perform operations in parallel. */ void engine_routine (void *arg) { engine_t *engine; power_t *power = (power_t*)arg; int result, count; int status; engine = pthread_getspecific (engine_key); if (engine == NULL) { engine = (engine_t*)malloc (sizeof (engine_t)); status = pthread_setspecific ( engine_key, (void*)engine); if (status != 0) err_abort (status, "Set tsd"); engine->thread_id = pthread_self (); engine->calls = 1; } else engine->calls++; result = 1; printf ( "Engine: computing %d^%d\n", power->value, power->power); for (count = 1; count <= power->power; count++) result *= power->value; free (arg); }
/* * Cancellation cleanup handler for the contractor thread. It * will cancel and detach each worker in the team. */ void cleanup (void *arg) { team_t *team = (team_t *)arg; int count, status; for (count = team->join_i; count < THREADS; count++) { status = pthread_cancel (team->workers[count]); if (status != 0) err_abort (status, "Cancel worker"); status = pthread_detach (team->workers[count]); if (status != 0) err_abort (status, "Detach worker"); printf ("Cleanup: cancelled %d\n", count); } }
int main (int arg, char *argv[]) { int thread_count, array_count; int status; barrier_init (&barrier, THREADS); /* * Create a set of threads that will use the barrier. */ for (thread_count = 0; thread_count < THREADS; thread_count++) { thread[thread_count].increment = thread_count; thread[thread_count].number = thread_count; for (array_count = 0; array_count < ARRAY; array_count++) thread[thread_count].array[array_count] = array_count + 1; // for (array_count = 0; array_count < ARRAY; array_count++) // printf ("%010u ", thread[thread_count].array[array_count]); // printf ("\n"); status = pthread_create (&thread[thread_count].thread_id, NULL, thread_routine, (void*)&thread[thread_count]); if (status != 0) err_abort (status, "Create thread"); } /* * Now join with each of the threads. */ for (thread_count = 0; thread_count < THREADS; thread_count++) { status = pthread_join (thread[thread_count].thread_id, NULL); if (status != 0) err_abort (status, "Join thread"); printf ("%02d: (%d) ", thread_count, thread[thread_count].increment); for (array_count = 0; array_count < ARRAY; array_count++) printf ("%010u ", thread[thread_count].array[array_count]); printf ("\n"); } /* * To be thorough, destroy the barrier. */ barrier_destroy (&barrier); return 0; }
void AsyncRead::addFile(File *file) { //printf("addFile(file = %p)\n", file); //printf("filesdim = %d, filesmax = %d\n", filesdim, filesmax); assert(filesdim < filesmax); FileData *f = &files[filesdim]; f->file = file; int status = pthread_mutex_init(&f->mutex, NULL); if (status != 0) err_abort(status, "init mutex"); status = pthread_cond_init(&f->cond, NULL); if (status != 0) err_abort(status, "init cond"); filesdim++; }
/* * One-time initialization routine used with the pthread_once * control block. */ void once_routine (void) { int status; printf ("initializing key\n"); status = pthread_key_create (&tsd_key, NULL); if (status != 0) err_abort (status, "Create key"); }
static int ws_extend_frame_buf(WebsocketFrame *frame, size_t more_len) { if ((frame->buf = (uint8_t *)realloc(frame->buf, frame->buf_len + more_len)) == NULL) err_abort(-1, "Can't realloc in ws_extend_frame_buf"); frame->buf_len += more_len; return 0; }
void et_tcp_unlock(et_id *id) { int status; status = pthread_mutex_unlock(&id->mutex); if (status != 0) { err_abort(status, "Failed tcp unlock"); } }
void *counter_thread (void *arg) { int status; int spin; while (time (NULL) < end_time) { status = pthread_mutex_lock (&mutex); if (status != 0) err_abort (status, "Lock mutex"); for (spin = 0; spin < SPIN; spin++) counter++; // RACE! status = pthread_mutex_unlock (&mutex); if (status != 0) err_abort (status, "Unlock mutex"); sleep (1); } // printf ("Counter is %#lx\n", counter); <-- interesting test for thread IDs. return NULL; }
PUBLIC S16 Trylock() { S32 status; pthread_t counter_thread_id; pthread_t monitor_thread_id; #ifdef sun /* * On Solaris 2.5, threads are not timesliced. To ensure * that our threads can run concurrently, we need to * increase the concurrency level to 2. */ DPRINTF (("Setting concurrency level to 2\n")); thr_setconcurrency (2); #endif end_time = time(NULL) + 60; /* Run for 1 minute */ status = pthread_create(&counter_thread_id, NULL, counter_thread, NULL); if (status != 0) { err_abort(status, "Create counter thread"); } status = pthread_create(&monitor_thread_id, NULL, monitor_thread, NULL); if (status != 0) { err_abort (status, "Create monitor thread"); } status = pthread_join(counter_thread_id, NULL); if (status != 0) { err_abort (status, "Join counter thread"); } status = pthread_join (monitor_thread_id, NULL); if (status != 0) { err_abort (status, "Join monitor thread"); } return ROK; }
int main(int argc,char* argv[]) { int status; char line[128]; alarm_t* alarm; pthread_t thread; status=pthread_create(&thread,NULL,alarm_thread,NULL); if(status!=0) { err_abort(status,"Create alarm thread"); } while(1){ printf("Alarm> \n"); if(fgets(line,sizeof(line),stdin)==NULL) exit(0); if(strlen(line)<=1) continue; alarm=(alarm_t*)malloc(sizeof(alarm_t)); if(alarm==NULL) { errno_abort("Allocate alarm"); } if(sscanf(line,"%d %64[^\n]", &alarm->seconds,alarm->message)<2) { fprintf(stderr,"Bad command\n"); free(alarm); } else { status=pthread_mutex_lock(&alarm_mutex); if(status!=0) { err_abort(status,"Lock mutex"); } alarm->time=time(NULL)+alarm->seconds; alarm_insert(alarm); status=pthread_mutex_unlock(&alarm_mutex); if(status!=0) { err_abort(status,"Unlock mutex"); } } } return 0; }
int main (int argc, char *argv[]) { int status; pthread_t counter_thread_id; pthread_t monitor_thread_id; end_time = time (NULL) + 60; status = pthread_create (&counter_thread_id, NULL, counter_thread, NULL); if (status != 0) err_abort (status, "Create counter thread"); status = pthread_create (&monitor_thread_id, NULL, monitor_thread, NULL); if (status != 0) err_abort (status, "Create monitor thread"); status = pthread_join (counter_thread_id, NULL); if (status != 0) err_abort (status, "Join counter thread"); status = pthread_join (monitor_thread_id, NULL); if (status != 0) err_abort (status, "Join monitor thread"); return 0; }