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