static void * Mesa_BufferThread_Main( DirectThread *thread, void *arg ) { MesaData *data = arg; D_DEBUG_AT( Mesa_Layer, "%s()\n", __FUNCTION__ ); while (true) { direct_mutex_lock( &data->lock ); while (!data->flip_pending) { D_DEBUG_AT( Mesa_Layer, " -> waiting for flip to be issued\n" ); direct_waitqueue_wait( &data->wq_flip, &data->lock ); } direct_mutex_unlock( &data->lock ); D_DEBUG_AT( Mesa_Layer, " -> waiting for flip to be done\n" ); drmHandleEvent( data->fd, &data->drmeventcontext ); direct_mutex_lock( &data->lock ); data->flip_pending = false; direct_waitqueue_broadcast( &data->wq_event ); direct_mutex_unlock( &data->lock ); } return NULL; }
DirectResult fusion_ref_zero_lock (FusionRef *ref) { DirectResult ret = DR_OK; D_ASSERT( ref != NULL ); direct_mutex_lock (&ref->single.lock); do { if (ref->single.destroyed) ret = DR_DESTROYED; else if (ref->single.locked) ret = DR_LOCKED; else if (ref->single.refs) direct_waitqueue_wait (&ref->single.cond, &ref->single.lock); else { ref->single.locked = direct_gettid(); break; } } while (ret == DR_OK); direct_mutex_unlock (&ref->single.lock); return ret; }
DFBResult CoreInputHubClient_Destroy( CoreInputHubClient *client ) { D_DEBUG_AT( Core_InputHub, "%s()\n", __FUNCTION__ ); OneThread_Destroy( client->thread ); OneQueue_Destroy( client->listen_qid ); if (client->activate_thread) { direct_mutex_lock( &client->lock ); client->activate_stop = true; direct_waitqueue_broadcast( &client->wq ); direct_mutex_unlock( &client->lock ); direct_thread_join( client->activate_thread ); direct_thread_destroy( client->activate_thread ); } direct_mutex_deinit( &client->lock ); direct_waitqueue_deinit( &client->wq ); D_FREE( client ); return DFB_OK; }
static void CoreInputHub_Dispatch( void *context, const OnePacketHeader *header, void *data, OneThread *thread ) { InputHubAttachRequest *request = data; CoreInputHub *hub = context; D_DEBUG_AT( Core_InputHub, "%s()\n", __FUNCTION__ ); direct_mutex_lock( &hub->lock ); // FIXME: replace by own list of devices recorded in CoreInputHub_AddDevice/RemoveDevice calls dfb_input_enumerate_devices( CoreInputHub_EnumDevice_Callback, request, DICAPS_ALL ); InputHubNotification notification; memset( ¬ification, 0, sizeof(notification) ); notification.type = IHNT_ATTACHED; OneQueue_Dispatch( request->listen_qid, ¬ification, sizeof(notification) ); OneQueue_Attach( hub->notify_qid, request->listen_qid ); direct_mutex_unlock( &hub->lock ); }
DirectResult fusion_ref_watch (FusionRef *ref, FusionCall *call, int call_arg) { DirectResult ret = DR_OK; D_ASSERT( ref != NULL ); D_ASSERT( call != NULL ); direct_mutex_lock (&ref->single.lock); if (ref->single.destroyed) ret = DR_DESTROYED; else if (!ref->single.refs) ret = DR_BUG; else if (ref->single.call) ret = DR_BUSY; else { ref->single.call = call; ref->single.call_arg = call_arg; } direct_mutex_unlock (&ref->single.lock); return ret; }
void VoodooConnectionPacket::Stop() { D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionPacket::%s( %p )\n", __func__, this ); D_MAGIC_ASSERT( this, VoodooConnection ); direct_mutex_lock( &output.lock ); while (!closed && output.packets) { D_DEBUG_AT( Voodoo_Connection, " -> waiting for output packets to be sent...\n" ); direct_waitqueue_wait( &output.wait, &output.lock ); } direct_mutex_unlock( &output.lock ); stop = true; link->WakeUp( link ); /* Wait for manager threads exiting. */ direct_thread_join( io ); direct_thread_destroy( io ); VoodooConnectionLink::Stop(); }
DirectResult direct_signal_handler_add( int num, DirectSignalHandlerFunc func, void *ctx, DirectSignalHandler **ret_handler ) { DirectSignalHandler *handler; D_ASSERT( func != NULL ); D_ASSERT( ret_handler != NULL ); D_DEBUG_AT( Direct_Signals, "Adding handler %p for signal %d with context %p...\n", func, num, ctx ); handler = D_CALLOC( 1, sizeof(DirectSignalHandler) ); if (!handler) { D_WARN( "out of memory" ); return DR_NOLOCALMEMORY; } handler->num = num; handler->func = func; handler->ctx = ctx; D_MAGIC_SET( handler, DirectSignalHandler ); direct_mutex_lock( &handlers_lock ); direct_list_append( &handlers, &handler->link ); direct_mutex_unlock( &handlers_lock ); *ret_handler = handler; return DR_OK; }
void VoodooConnectionLink::Stop() { D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionLink::%s( %p )\n", __func__, this ); D_MAGIC_ASSERT( this, VoodooConnection ); direct_mutex_lock( &output.lock ); while (output.packets) { VoodooPacket *packet = (VoodooPacket*) output.packets; D_DEBUG_AT( Voodoo_Connection, " -> discarding output packet %p\n", packet ); D_ASSUME( packet->sending ); packet->sending = false; direct_list_remove( &output.packets, &packet->link ); } direct_mutex_unlock( &output.lock ); direct_waitqueue_broadcast( &output.wait ); }
DFBResult CoreInputHub_DispatchEvent( CoreInputHub *hub, DFBInputDeviceID device_id, const DFBInputEvent *event ) { InputHubNotification notification; D_DEBUG_AT( Core_InputHub, "%s( ID %u, %s )\n", __FUNCTION__, device_id, dfb_input_event_type_name(event->type) ); D_ASSERT( hub != NULL ); D_ASSERT( event != NULL ); memset( ¬ification, 0, sizeof(notification) ); notification.type = IHNT_EVENT_DISPATCH; notification.data.event_dispatch.device_id = device_id; notification.data.event_dispatch.event = *event; direct_mutex_lock( &hub->lock ); OneQueue_Dispatch( hub->notify_qid, ¬ification, sizeof(notification) ); direct_mutex_unlock( &hub->lock ); return DFB_OK; }
DFBResult CoreInputHub_AddDevice( CoreInputHub *hub, DFBInputDeviceID device_id, const DFBInputDeviceDescription *desc ) { InputHubNotification notification; D_ASSERT( hub != NULL ); D_ASSERT( desc != NULL ); D_DEBUG_AT( Core_InputHub, "%s( ID %u, '%s' )\n", __FUNCTION__, device_id, desc->name ); memset( ¬ification, 0, sizeof(notification) ); notification.type = IHNT_DEVICE_ADD; notification.data.device_add.device_id = device_id; notification.data.device_add.description = *desc; direct_mutex_lock( &hub->lock ); OneQueue_Dispatch( hub->notify_qid, ¬ification, sizeof(notification) ); direct_mutex_unlock( &hub->lock ); return DFB_OK; }
const char * DirectResultString( DirectResult result ) { DirectResult ret; DirectResultType *type; if (result) { ret = direct_mutex_lock( &result_mutex ); if (ret) return NULL; type = direct_hash_lookup( &result_types, D_RESULT_TYPE( result ) ); direct_mutex_unlock( &result_mutex ); if (type) { unsigned int index = D_RESULT_INDEX( result ); D_MAGIC_ASSERT( type, DirectResultType ); D_ASSERT( type->refs > 0 ); if (index < type->result_count) return type->result_strings[index]; return type->result_strings[0]; } return "UNKNOWN RESULT TYPE"; } return "OK"; }
static void DecoupleCall( ComaTestInstance *instance, ComaMethodID method, void *data, unsigned int serial ) { DecoupledCall *call; IComaComponent *component = instance->component; call = D_CALLOC( 1, sizeof(DecoupledCall) ); if (!call) { D_OOM(); component->Return( component, DR_NOLOCALMEMORY, call->serial ); return; } call->instance = instance; call->method = method; call->data = data; call->serial = serial; direct_mutex_lock( &decoupled_calls_lock ); direct_list_append( &decoupled_calls, &call->link ); direct_mutex_unlock( &decoupled_calls_lock ); direct_waitqueue_broadcast( &decoupled_calls_wq ); }
VoodooConnectionLink::Packets::~Packets() { D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionLink::Packets::%s( %p )\n", __func__, this ); D_MAGIC_ASSERT( this, Packets ); for (size_t i=0; i<num; i++) { if (packets[i]) { D_DEBUG_AT( Voodoo_Connection, " -> destroying output packet "_ZU" (%p)\n", i, packets[i] ); if (packets[i]->sending) { direct_mutex_lock( &connection->output.lock ); while (packets[i]->sending) { D_DEBUG_AT( Voodoo_Connection, " -> packet sending, waiting...\n" ); direct_waitqueue_wait( &connection->output.wait, &connection->output.lock ); } direct_mutex_unlock( &connection->output.lock ); } D_FREE( packets[i] ); } } }
void RemoveClient( CoreGraphicsStateClient *client ) { direct_mutex_lock( &lock ); clients.remove( client ); direct_mutex_unlock( &lock ); }
static ssize_t Read( VoodooLink *link, void *buffer, size_t count ) { Link *l = link->priv; while (true) { ssize_t ret; fd_set rfds; struct timeval tv; int retval; FD_ZERO( &rfds ); FD_SET( l->socket, &rfds ); tv.tv_sec = 0; tv.tv_usec = 0;//10000; direct_mutex_lock( &l->lock ); retval = select( l->socket+1, &rfds, NULL, NULL, &tv ); switch (retval) { default: ret = recv( l->socket, buffer, count, 0 ); direct_mutex_unlock( &l->lock ); return ret; case 0: D_DEBUG( "Voodoo/Link: Timeout during select()\n" ); break; case -1: //if (errno && errno != EINTR) D_PERROR( "Voodoo/Player: select() on socket failed!\n" ); direct_mutex_unlock( &l->lock ); return -1; } direct_mutex_unlock( &l->lock ); direct_thread_sleep( 20000 ); } return -1; }
void AddClient( CoreGraphicsStateClient *client ) { direct_mutex_lock( &lock ); clients.push_back( client ); direct_mutex_unlock( &lock ); }
void FlushAll() { direct_mutex_lock( &lock ); for (std::list<CoreGraphicsStateClient*>::const_iterator it = clients.begin(); it != clients.end(); ++it) CoreGraphicsStateClient_Flush( *it ); direct_mutex_unlock( &lock ); }
void direct_processor_unlock( DirectProcessor *processor ) { direct_mutex_lock( &processor->lock_mutex ); if (! --processor->lock && processor->locked) direct_waitqueue_signal( &processor->lock_cond ); direct_mutex_unlock( &processor->lock_mutex ); }
void direct_perf_count( DirectPerfCounterInstallation *installation, int diff ) { DirectPerfCounter *counter; D_ASSERT( installation != NULL ); direct_mutex_lock( &counter_lock ); if (installation->counter_id == 0) { counter = D_CALLOC( 1, sizeof(DirectPerfCounter) ); if (!counter) { direct_mutex_unlock( &counter_lock ); D_OOM(); return; } installation->counter_id = ++counter_ids; D_ASSERT( installation->counter_id != 0 ); D_ASSERT( installation->counter_id != ~0 ); // FIXME: can there be more than 4 billion counters? direct_snputs( counter->name, installation->name, sizeof(counter->name) ); counter->reset_on_dump = installation->reset_on_dump; direct_hash_insert( &counter_hash, installation->counter_id, counter ); } else { counter = direct_hash_lookup( &counter_hash, installation->counter_id ); if (!counter) { direct_mutex_unlock( &counter_lock ); D_BUG( "unknown performance counter installation (%lu)", installation->counter_id ); return; } } counter->count += diff; if (!counter->start) counter->start = direct_clock_get_time( DIRECT_CLOCK_SESSION ); direct_mutex_unlock( &counter_lock ); }
void FlushAllDst( CoreSurface *surface ) { direct_mutex_lock( &lock ); for (std::list<CoreGraphicsStateClient*>::const_iterator it = clients.begin(); it != clients.end(); ++it) { if ((*it)->state->destination == surface) CoreGraphicsStateClient_Flush( *it ); } direct_mutex_unlock( &lock ); }
char * direct_dbg_strdup( const char* file, int line, const char *func, const char *string ) { void *mem; unsigned long *val; size_t bytes = string ? direct_strlen( string ) + 1 : 1; D_DEBUG_AT( Direct_Mem, " +"_ZUn(6)" bytes [%s:%d in %s()] <- \"%30s\"\n", bytes, file, line, func, string ); if (direct_config->debugmem) { MemDesc *desc; mem = direct_malloc( bytes + sizeof(MemDesc) ); D_DEBUG_AT( Direct_Mem, " '-> %p\n", mem ); if (!mem) return NULL; desc = fill_mem_desc( mem, bytes, func, file, line, direct_trace_copy_buffer(NULL) ); direct_mutex_lock( &alloc_lock ); direct_hash_insert( &alloc_hash, (unsigned long) desc->mem, desc ); direct_mutex_unlock( &alloc_lock ); if (string) direct_memcpy( desc->mem, string, bytes ); else *(u8*)desc->mem = 0; return desc->mem; } mem = direct_malloc( bytes + DISABLED_OFFSET ); D_DEBUG_AT( Direct_Mem, " '-> %p\n", mem ); if (!mem) return NULL; val = mem; val[0] = ~0; if (string) direct_memcpy( (char*) mem + DISABLED_OFFSET, string, bytes ); else *((u8*)mem + DISABLED_OFFSET) = 0; return (char*) mem + DISABLED_OFFSET; }
static void call_handlers( int num, void *addr ) { DirectLink *l, *n; if (num == SIG_DUMP_STACK) num = DIRECT_SIGNAL_DUMP_STACK; /* Loop through all handlers. */ direct_mutex_lock( &handlers_lock ); direct_list_foreach_safe (l, n, handlers) { DirectSignalHandler *handler = (DirectSignalHandler*) l; if (handler->removed) { direct_list_remove( &handlers, &handler->link ); D_MAGIC_CLEAR( handler ); D_FREE( handler ); continue; } D_LOG( Direct_Signals, FATAL, " --> %d\n", handler->num ); if (handler->num != num && handler->num != DIRECT_SIGNAL_ANY) continue; if (handler->num == DIRECT_SIGNAL_ANY && num == DIRECT_SIGNAL_DUMP_STACK) continue; switch (handler->func( num, addr, handler->ctx )) { case DSHR_OK: break; case DSHR_REMOVE: direct_list_remove( &handlers, &handler->link ); D_MAGIC_CLEAR( handler ); D_FREE( handler ); break; case DSHR_RESUME: D_LOG( Direct_Signals, FATAL, " '-> cured!\n" ); direct_mutex_unlock( &handlers_lock ); return; default: D_BUG( "unknown result" ); break; } }
void direct_perf_dump_all() { direct_mutex_lock( &counter_lock ); if (direct_hash_count( &counter_hash )) { direct_log_printf( NULL, "Performance Counters Total count rate start end\n" ); direct_hash_iterate( &counter_hash, perf_iterate, NULL ); } direct_mutex_unlock( &counter_lock ); }
void * VoodooDispatcher::DispatchLoop() { D_DEBUG_AT( Voodoo_Dispatcher, "VoodooDispatcher::%s( %p )\n", __func__, this ); direct_mutex_lock( &lock ); while (!manager->is_quit) { VoodooPacket *packet; D_MAGIC_ASSERT( this, VoodooDispatcher ); if (packets) { packet = (VoodooPacket*) packets; direct_list_remove( &packets, &packet->link ); manager->connection->WakeUp(); } else { direct_waitqueue_wait( &queue, &lock ); continue; } direct_mutex_unlock( &lock ); ProcessMessages( (VoodooMessageHeader*) packet->data_start(), packet->size() ); D_FREE( packet ); direct_mutex_lock( &lock ); } direct_mutex_unlock( &lock ); return NULL; }
DirectResult fusion_ref_down (FusionRef *ref, bool global) { D_ASSERT( ref != NULL ); direct_mutex_lock (&ref->single.lock); if (!ref->single.refs) { D_BUG( "no more references" ); direct_mutex_unlock (&ref->single.lock); return DR_BUG; } if (ref->single.destroyed) { direct_mutex_unlock (&ref->single.lock); return DR_DESTROYED; } if (! --ref->single.refs) { if (ref->single.call) { FusionCall *call = ref->single.call; if (call->handler) { fusion_call_execute( call, FCEF_NODIRECT | FCEF_ONEWAY, ref->single.call_arg, NULL, NULL ); direct_mutex_unlock( &ref->single.lock ); return DR_OK; } } else direct_waitqueue_broadcast (&ref->single.cond); } direct_mutex_unlock (&ref->single.lock); return DR_OK; }
static void TestDispatch( void *context, const OnePacketHeader *header, void *data, OneThread *thread ) { // D_INFO( "TestDispatch called\n" ); direct_mutex_lock( &lock ); direct_waitqueue_signal( &queue ); direct_mutex_unlock( &lock ); }
VoodooPacket * VoodooConnectionLink::GetPacket( size_t length ) { D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionLink::%s( %p, length "_ZU" )\n", __func__, this, length ); D_MAGIC_ASSERT( this, VoodooConnection ); D_ASSERT( length >= (int) sizeof(VoodooMessageHeader) ); D_ASSUME( length <= MAX_MSG_SIZE ); if (length > MAX_MSG_SIZE) { D_WARN( _ZU" exceeds maximum message size of %d", length, MAX_MSG_SIZE ); return NULL; } size_t aligned = VOODOO_MSG_ALIGN( length ); Packets *packets = (Packets*) direct_tls_get( output.tls ); if (!packets) { packets = new Packets( this ); direct_tls_set( output.tls, packets ); } VoodooPacket *packet = packets->active; if (packet) { if (packet->append( aligned )) return packet; Flush( packet ); } packet = packets->Get(); if (packet) { if (packet->sending) { direct_mutex_lock( &output.lock ); while (packet->sending) direct_waitqueue_wait( &output.wait, &output.lock ); direct_mutex_unlock( &output.lock ); } packet->reset( aligned ); } return packet; }
void direct_processor_lock( DirectProcessor *processor ) { direct_mutex_lock( &processor->lock_mutex ); processor->lock++; while (!processor->locked) { direct_fifo_wakeup( &processor->commands ); direct_waitqueue_wait( &processor->lock_cond, &processor->lock_mutex ); } direct_mutex_unlock( &processor->lock_mutex ); }
void VoodooDispatcher::PutPacket( VoodooPacket *packet ) { D_DEBUG_AT( Voodoo_Dispatcher, "VoodooDispatcher::%s( %p, packet %p )\n", __func__, this, packet ); D_MAGIC_ASSERT( this, VoodooDispatcher ); direct_mutex_lock( &lock ); direct_list_append( &packets, &packet->link ); direct_waitqueue_broadcast( &queue ); direct_mutex_unlock( &lock ); }
bool VoodooDispatcher::Ready() { D_DEBUG_AT( Voodoo_Dispatcher, "VoodooDispatcher::%s( %p )\n", __func__, this ); D_MAGIC_ASSERT( this, VoodooDispatcher ); direct_mutex_lock( &lock ); bool ready = direct_list_count_elements_EXPENSIVE( packets ) < 3; direct_mutex_unlock( &lock ); return ready; }