server_papi.c revision e0e0c19eefceaf5d4ec40f9466b58a771f50e799
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener/* Copyright (c) 2001, Stanford University
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener * All rights reserved
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener *
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener * See the file LICENSE.txt for information on redistributing this software.
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener */
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener#include "server_dispatch.h"
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener#include "server.h"
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener#include "cr_error.h"
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener#include "cr_mem.h"
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener#include "state/cr_statetypes.h"
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener#define DEBUG_BARRIERS 1
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchenervoid SERVER_DISPATCH_APIENTRY crServerDispatchBarrierCreateCR( GLuint name, GLuint count )
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener{
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener CRServerBarrier *barrier;
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener#if DEBUG_BARRIERS
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener char debug_buf[4096];
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener#endif
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener if (cr_server.ignore_papi)
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener {
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener cr_server.head_spu->dispatch_table.BarrierCreateCR( name, count );
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener return;
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener }
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener barrier = (CRServerBarrier *) crHashtableSearch( cr_server.barriers, name );
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener#if DEBUG_BARRIERS
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener sprintf( debug_buf, "BarrierCreateCR( %d, %d )", name, count );
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener cr_server.head_spu->dispatch_table.ChromiumParametervCR( GL_PRINT_STRING_CR, GL_UNSIGNED_BYTE, sizeof(debug_buf), debug_buf );
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener#endif
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener if (count == 0)
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener {
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener count = cr_server.numClients;
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener#if DEBUG_BARRIERS
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener sprintf( debug_buf, "changing count to %d", count );
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener cr_server.head_spu->dispatch_table.ChromiumParametervCR( GL_PRINT_STRING_CR, GL_UNSIGNED_BYTE, sizeof(debug_buf), debug_buf );
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener#endif
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener }
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener /* we use maxBarrierCount in Clear() and SwapBuffers() and also use it
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener * in __getNextClient() for deadlock detection. The issue is that all
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener * the existing clients may be blocked, but we might soon get another
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener * client connection to break the apparent deadlock.
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener */
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener if (count > cr_server.maxBarrierCount)
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener cr_server.maxBarrierCount = count;
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener if ( barrier == NULL )
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener {
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener barrier = (CRServerBarrier *) crAlloc( sizeof(*barrier) );
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener barrier->count = count;
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener barrier->num_waiting = 0;
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener barrier->waiting = (RunQueue **)
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener crAlloc( count * sizeof(*(barrier->waiting)) );
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener crHashtableAdd( cr_server.barriers, name, barrier );
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener#if DEBUG_BARRIERS
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener sprintf( debug_buf, "This was a new barrier!" );
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener cr_server.head_spu->dispatch_table.ChromiumParametervCR( GL_PRINT_STRING_CR, GL_UNSIGNED_BYTE, sizeof(debug_buf), debug_buf );
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener#endif
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener }
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener else
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener {
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener /* HACK -- this allows everybody to create a barrier, and all
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener but the first creation are ignored, assuming the count
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener match. */
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener#if DEBUG_BARRIERS
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener sprintf( debug_buf, "I already knew about this barrier." );
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener cr_server.head_spu->dispatch_table.ChromiumParametervCR( GL_PRINT_STRING_CR, GL_UNSIGNED_BYTE, sizeof(debug_buf), debug_buf );
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener#endif
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener if ( barrier->count != count )
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener {
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener#if DEBUG_BARRIERS
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener sprintf( debug_buf, "And someone messed up the count!." );
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener cr_server.head_spu->dispatch_table.ChromiumParametervCR( GL_PRINT_STRING_CR, GL_UNSIGNED_BYTE, sizeof(debug_buf), debug_buf );
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener#endif
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener crError( "Barrier name=%u created with count=%u, but already "
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener "exists with count=%u", name, count, barrier->count );
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener }
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener }
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener if (cr_server.debug_barriers)
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener crDebug("crserver: BarrierCreate(id=%d, count=%d)", name, barrier->count);
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener}
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchenervoid SERVER_DISPATCH_APIENTRY crServerDispatchBarrierDestroyCR( GLuint name )
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener{
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener if (cr_server.ignore_papi)
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener {
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener cr_server.head_spu->dispatch_table.BarrierDestroyCR( name );
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener return;
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener }
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener crError( "NO BARRIER DESTROY FOR YOU! (name=%u)", name );
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener}
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchenervoid SERVER_DISPATCH_APIENTRY crServerDispatchBarrierExecCR( GLuint name )
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener{
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener CRServerBarrier *barrier;
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener#if DEBUG_BARRIERS
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener char debug_buf[4096];
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener#endif
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener if (cr_server.ignore_papi)
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener {
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener cr_server.head_spu->dispatch_table.BarrierExecCR( name );
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener return;
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener }
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener barrier = (CRServerBarrier *) crHashtableSearch( cr_server.barriers, name );
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener if ( barrier == NULL )
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener {
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener crError( "crServerDispatchBarrierExec: No such barrier: %d", name );
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener }
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener#if DEBUG_BARRIERS
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener sprintf( debug_buf, "BarrierExec( %d )", name );
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener cr_server.head_spu->dispatch_table.ChromiumParametervCR( GL_PRINT_STRING_CR, GL_UNSIGNED_BYTE, sizeof(debug_buf), debug_buf );
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener sprintf( debug_buf, "num_waiting = %d", barrier->num_waiting );
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener cr_server.head_spu->dispatch_table.ChromiumParametervCR( GL_PRINT_STRING_CR, GL_UNSIGNED_BYTE, sizeof(debug_buf), debug_buf );
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener#endif
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener barrier->waiting[barrier->num_waiting++] = cr_server.run_queue;
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener cr_server.run_queue->blocked = 1;
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener if ( barrier->num_waiting == barrier->count )
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener {
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener GLuint i;
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener if (cr_server.debug_barriers)
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener crDebug("crserver: BarrierExec(client=%p, id=%d, num_waiting=%d/%d) - release",
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener cr_server.curClient, name, barrier->num_waiting,
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener barrier->count);
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener for ( i = 0; i < barrier->count; i++ )
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener {
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener barrier->waiting[i]->blocked = 0;
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener }
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener barrier->num_waiting = 0;
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener }
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener else if (cr_server.debug_barriers)
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener crDebug("crserver: BarrierExec(client=%p, id=%d, num_waiting=%d/%d) - block",
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener cr_server.curClient, name, barrier->num_waiting,
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener barrier->count);
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener}
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchenervoid SERVER_DISPATCH_APIENTRY crServerDispatchSemaphoreCreateCR( GLuint name, GLuint count )
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener{
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener CRServerSemaphore *sema;
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener if (cr_server.ignore_papi)
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener {
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener cr_server.head_spu->dispatch_table.SemaphoreCreateCR( name, count );
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener return;
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener }
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener sema = crHashtableSearch(cr_server.semaphores, name);
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener if (sema)
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener return; /* already created */
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener sema = (CRServerSemaphore *) crAlloc( sizeof( *sema ) );
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener crHashtableAdd( cr_server.semaphores, name, sema );
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener sema->count = count;
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener sema->waiting = sema->tail = NULL;
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener if (cr_server.debug_barriers)
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener crDebug("crserver: SemaphoreCreate(id=%d, count=%d)", name, count);
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener}
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchenervoid SERVER_DISPATCH_APIENTRY crServerDispatchSemaphoreDestroyCR( GLuint name )
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener{
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener if (cr_server.ignore_papi)
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener {
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener cr_server.head_spu->dispatch_table.SemaphoreDestroyCR( name );
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener return;
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener }
1df39e6d090e04296ab0788832d5c3a1540d2156Jim Mitchener
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener crError( "NO DESTROY FOR YOU! (name=%u)", name );
f2943ad659f4f773b76ed5d7ad502494bb148148Jim Mitchener}
/* Semaphore wait */
void SERVER_DISPATCH_APIENTRY crServerDispatchSemaphorePCR( GLuint name )
{
CRServerSemaphore *sema;
if (cr_server.ignore_papi)
{
cr_server.head_spu->dispatch_table.SemaphorePCR( name );
return;
}
sema = (CRServerSemaphore *) crHashtableSearch( cr_server.semaphores, name );
if (!sema)
{
crError( "No such semaphore: %d", name );
}
if (sema->count)
{
/* go */
if (cr_server.debug_barriers)
crDebug("crserver: SemaphoreP(client=%p, id=%d, count=%d) decrement to %d",
cr_server.curClient, name, sema->count, sema->count - 1);
sema->count--;
}
else
{
/* block */
wqnode *node;
if (cr_server.debug_barriers)
crDebug("crserver: SemaphoreP(client=%p, id=%d, count=%d) - block.",
cr_server.curClient, name, sema->count);
cr_server.run_queue->blocked = 1;
node = (wqnode *) crAlloc( sizeof( *node ) );
node->q = cr_server.run_queue;
node->next = NULL;
if (sema->tail)
{
sema->tail->next = node;
}
else
{
sema->waiting = node;
}
sema->tail = node;
}
}
/* Semaphore signal */
void SERVER_DISPATCH_APIENTRY crServerDispatchSemaphoreVCR( GLuint name )
{
CRServerSemaphore *sema;
if (cr_server.ignore_papi)
{
cr_server.head_spu->dispatch_table.SemaphoreVCR( name );
return;
}
sema = (CRServerSemaphore *) crHashtableSearch( cr_server.semaphores, name );
if (!sema)
{
crError( "No such semaphore: %d", name );
}
if (sema->waiting)
{
wqnode *temp = sema->waiting;
if (cr_server.debug_barriers)
crDebug("crserver: SemaphoreV(client=%p, id=%d, count=%d) - unblock.",
cr_server.curClient, name, sema->count);
/* unblock one waiter */
temp->q->blocked = 0;
sema->waiting = temp->next;
crFree( temp );
if (!sema->waiting)
{
sema->tail = NULL;
}
}
else
{
/* nobody's waiting */
if (cr_server.debug_barriers)
crDebug("crserver: SemaphoreV(client=%p, id=%d, count=%d) - increment to %d",
cr_server.curClient, name, sema->count, sema->count + 1);
sema->count++;
}
}