示例#1
0
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);
}
示例#2
0
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);
}