void text_splash() { const int usleep_time = 1000; int i; { #include "ERT.h" printf("\n\n"); for (i = 0; i < SPLASH_LENGTH; i++) { printf("%s\n", splash_text[i]); util_usleep(usleep_time); } printf("\n\n"); sleep(1); #undef SPLASH_LENGTH } }
void * global_status( void * arg ) { job_queue_type * job_queue = job_queue_safe_cast( arg ); int counter = 0; while (true) { util_usleep(100000); if (job_queue_get_num_complete(job_queue) == job_queue_get_active_size(job_queue)) break; if ((counter % 10) == 0) printf("Waiting:%03d Running:%03d Callback:%03d Complete:%03d \n", job_queue_get_num_waiting(job_queue) , job_queue_get_num_running(job_queue), job_queue_get_num_callback( job_queue ) , job_queue_get_num_complete(job_queue)); counter++; } return NULL; }
static void * thread_pool_main_loop( void * arg ) { thread_pool_type * tp = (thread_pool_type *) arg; { const int usleep_busy = 1000; /* The sleep time when all job slots are occupied. */ const int usleep_init = 1000; /* The sleep time when there are free slots available - but no jobs wanting to run. */ int internal_offset = 0; /* Keep track of the (index of) the last job slot fired off - minor time saving. */ while (true) { if (tp->queue_size > tp->queue_index) { /* There are jobs in the queue which would like to run - let us see if we can find a slot for them. */ int counter = 0; bool slot_found = false; do { int slot_index = (counter + internal_offset) % tp->max_running; thread_pool_job_slot_type * job_slot = &tp->job_slots[ slot_index ]; if (!job_slot->running) { /* OK thread[slot_index] is ready to take this job.*/ thread_pool_arg_type * tp_arg; /* The queue might be updated by the main thread - we must take a copy of the node we are interested in. */ pthread_rwlock_rdlock( &tp->queue_lock ); tp_arg = util_alloc_copy( &tp->queue[ tp->queue_index ] , sizeof * tp_arg ); pthread_rwlock_unlock( &tp->queue_lock ); tp_arg->slot_index = slot_index; job_slot->running = true; /* Here is the actual pthread_create() call creating an additional running thread. */ pthread_create( &job_slot->thread , NULL , thread_pool_start_job , tp_arg ); job_slot->run_count += 1; tp->queue_index++; internal_offset += (counter + 1); slot_found = true; } else counter++; } while (!slot_found && (counter < tp->max_running)); if (!slot_found) util_usleep( usleep_busy ); /* There are no available job slots. */ } else util_usleep( usleep_init ); /* There are no jobs wanting to run. */ /*****************************************************************/ /* We exit explicitly from this loop when both conditions apply: 1. tp->join == true : The calling scope has signaled that it will not submit more jobs. 2. tp->queue_size == tp->queue_index : This function has submitted all the jobs in the queue. */ if ((tp->join) && (tp->queue_size == tp->queue_index)) break; } /* End of while() loop */ } /* There are no more jobs in the queue, and the main scope has signaled that join should start. Observe that we join only the jobs corresponding to explicitly running job_slots; when a job slot is used multiple times the first jobs run in the job_slot will not be explicitly joined. */ { int i; for (i=0; i < tp->max_running; i++) { thread_pool_job_slot_type job_slot = tp->job_slots[i]; if (job_slot.run_count > 0) pthread_join( job_slot.thread , NULL ); } } /* When we are here all the jobs have completed. */ return NULL; }