void process_tasks(long process_id) { Task *t ; retry_entry: t = DEQUEUE_TASK( taskqueue_id[process_id], QUEUES_VISITED, process_id ) ; while( t ) { switch( t->task_type ) { case TASK_MODELING: process_model( t->task.model.model, t->task.model.type, process_id ) ; break ; case TASK_BSP: define_patch( t->task.bsp.patch, t->task.bsp.parent, process_id ) ; break ; case TASK_FF_REFINEMENT: ff_refine_elements( t->task.ref.e1, t->task.ref.e2, 0, process_id ) ; break ; case TASK_RAY: process_rays( t->task.ray.e, process_id ) ; break ; case TASK_VISIBILITY: visibility_task( t->task.vis.e, t->task.vis.inter, t->task.vis.n_inter, t->task.vis.k, process_id ) ; break ; case TASK_RAD_AVERAGE: radiosity_averaging( t->task.rad.e, t->task.rad.mode, process_id ) ; break ; default: fprintf( stderr, "Panic:process_tasks:Illegal task type\n" ); } /* Free the task */ free_task( t, process_id ) ; /* Get next task */ t = DEQUEUE_TASK( taskqueue_id[process_id], QUEUES_VISITED, process_id ) ; } /* Barrier. While waiting for other processors to finish, poll the task queues and resume processing if there is any task */ LOCK(global->pbar_lock); /* Reset the barrier counter if not initialized */ if( global->pbar_count >= n_processors ) global->pbar_count = 0 ; /* Increment the counter */ global->pbar_count++ ; /* barrier spin-wait loop */ long bar_done = !(global->pbar_count < n_processors); UNLOCK(global->pbar_lock); while(!bar_done) { /* Wait for a while and then retry dequeue */ if( _process_task_wait_loop() ) break ; /* Waited for a while but other processors are still running. Poll the task queue again If polling succeeds (without actually getting a task) then we exit the barrier and try to get a task. This fixes the bug where all the threads might finish the barrier but in the meantime one reenters it to process some tasks. */ int has_task = peek_dequeue( taskqueue_id[process_id], QUEUES_VISITED, process_id ); if (has_task) { LOCK(global->pbar_lock); global->pbar_count-- ; UNLOCK(global->pbar_lock); goto retry_entry ; } LOCK(global->pbar_lock); bar_done = !(global->pbar_count < n_processors); UNLOCK(global->pbar_lock); } BARRIER(global->barrier, n_processors); }
void process_tasks(long process_id) { Task *t ; t = DEQUEUE_TASK( taskqueue_id[process_id], QUEUES_VISITED, process_id ) ; retry_entry: while( t ) { switch( t->task_type ) { case TASK_MODELING: process_model( t->task.model.model, t->task.model.type, process_id ) ; break ; case TASK_BSP: define_patch( t->task.bsp.patch, t->task.bsp.parent, process_id ) ; break ; case TASK_FF_REFINEMENT: ff_refine_elements( t->task.ref.e1, t->task.ref.e2, 0, process_id ) ; break ; case TASK_RAY: process_rays( t->task.ray.e, process_id ) ; break ; case TASK_VISIBILITY: visibility_task( t->task.vis.e, t->task.vis.inter, t->task.vis.n_inter, t->task.vis.k, process_id ) ; break ; case TASK_RAD_AVERAGE: radiosity_averaging( t->task.rad.e, t->task.rad.mode, process_id ) ; break ; default: fprintf( stderr, "Panic:process_tasks:Illegal task type\n" ); } /* Free the task */ free_task( t, process_id ) ; /* Get next task */ t = DEQUEUE_TASK( taskqueue_id[process_id], QUEUES_VISITED, process_id ) ; } /* Barrier. While waiting for other processors to finish, poll the task queues and resume processing if there is any task */ LOCK(global->pbar_lock); /* Reset the barrier counter if not initialized */ if( global->pbar_count >= n_processors ) global->pbar_count = 0 ; /* Increment the counter */ global->pbar_count++ ; UNLOCK(global->pbar_lock); /* barrier spin-wait loop */ while( global->pbar_count < n_processors ) { /* Wait for a while and then retry dequeue */ if( _process_task_wait_loop() ) break ; /* Waited for a while but other processors are still running. Poll the task queue again */ t = DEQUEUE_TASK( taskqueue_id[process_id], QUEUES_VISITED, process_id ) ; if( t ) { /* Task found. Exit the barrier and work on it */ LOCK(global->pbar_lock); global->pbar_count-- ; UNLOCK(global->pbar_lock); goto retry_entry ; } } BARRIER(global->barrier, n_processors); }