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] ); } } }
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; }
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(); }
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; }
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::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; }
static void * DecoupledCall_thread_main( DirectThread *thread, void *ctx ) { while (true) { DecoupledCall *call; direct_mutex_lock( &decoupled_calls_lock ); while (!decoupled_calls) direct_waitqueue_wait( &decoupled_calls_wq, &decoupled_calls_lock ); call = (DecoupledCall*) decoupled_calls; direct_list_remove( &decoupled_calls, &call->link ); direct_mutex_unlock( &decoupled_calls_lock ); ComaTestInstance *instance = call->instance; IComaComponent *component = instance->component; switch (call->method) { case COMA_TEST_CALL1: DispatchCall1( instance, call->data, call->serial ); break; default: component->Return( component, DR_NOIMPL, call->serial ); break; } D_FREE( call ); } return NULL; }
static DirectResult TestWakeUp(void) { DirectResult ret; char buf[512]; int loops = 1000000; while (loops--) { ret = OneThread_AddQueue( thread, queue_id, TestDispatch, NULL ); if (ret) { D_DERROR( ret, "OneTest: AddQueue error!\n" ); return ret; } direct_mutex_lock( &lock ); ret = OneQueue_Dispatch( queue_id, buf, 12 ); if (ret) { D_DERROR( ret, "OneTest: Dispatch error!\n" ); direct_mutex_unlock( &lock ); return ret; } direct_waitqueue_wait( &queue, &lock ); direct_mutex_unlock( &lock ); ret = OneThread_RemoveQueue( thread, queue_id ); if (ret) { D_DERROR( ret, "OneTest: RemoveQueue error!\n" ); return ret; } } return DR_OK; }
static void * processor_thread( DirectThread *thread, void *ctx ) { DirectResult ret; bool started = false; DirectProcessor *processor = ctx; const DirectProcessorFuncs *funcs; D_DEBUG_AT( Direct_Processor, "%s( %p, %p )...\n", __FUNCTION__, thread, ctx ); D_MAGIC_ASSERT( processor, DirectProcessor ); funcs = processor->funcs; D_ASSERT( funcs != NULL ); D_ASSERT( funcs->Process != NULL ); while (!processor->stop) { ProcessorCommand *command = direct_fifo_pull( &processor->commands ); if (command) { D_DEBUG_AT( Direct_Processor, "=---### %p - %p (%s)\n", command, command + 1, processor->name ); D_MAGIC_ASSERT( command, ProcessorCommand ); if (!started) { if (funcs->Start) funcs->Start( processor, processor->context ); started = true; } ret = funcs->Process( processor, command + 1, processor->context ); if (ret) D_DERROR( ret, "Direct/Processor: Processing failed! (%s)\n", processor->name ); } else { if (started) { if (funcs->Stop) funcs->Stop( processor, processor->context ); started = false; } #if 0 while (processor->lock) { direct_mutex_lock( &processor->lock_mutex ); processor->locked = true; direct_waitqueue_signal( &processor->lock_cond ); while (processor->lock) direct_waitqueue_wait( &processor->lock_cond, &processor->lock_mutex ); processor->locked = false; direct_waitqueue_signal( &processor->lock_cond ); direct_mutex_unlock( &processor->lock_mutex ); } #endif if (processor->idle_ms) { while (direct_fifo_wait_timed( &processor->commands, processor->idle_ms ) == DR_TIMEOUT) { if (funcs->Idle) funcs->Idle( processor, processor->context ); } } else { if (funcs->Idle) funcs->Idle( processor, processor->context ); direct_fifo_wait( &processor->commands ); } } } return NULL; }
static DFBResult mesaFlipRegion( CoreLayer *layer, void *driver_data, void *layer_data, void *region_data, CoreSurface *surface, DFBSurfaceFlipFlags flags, const DFBRegion *left_update, CoreSurfaceBufferLock *left_lock, const DFBRegion *right_update, CoreSurfaceBufferLock *right_lock ) { int ret; MesaData *mesa = driver_data; D_DEBUG_AT( Mesa_Layer, "%s()\n", __FUNCTION__ ); // ret = drmModeSetCrtc( mesa->fd, mesa->encoder->crtc_id, (u32)(long)left_lock->handle, 0, 0, // &mesa->connector->connector_id, 1, &mesa->mode ); direct_mutex_lock( &mesa->lock ); while (mesa->flip_pending) { D_DEBUG_AT( Mesa_Layer, " -> waiting for pending flip (previous)\n" ); direct_waitqueue_wait( &mesa->wq_event, &mesa->lock ); } direct_mutex_unlock( &mesa->lock ); D_ASSERT( mesa->buffer == NULL ); mesa->buffer = left_lock->buffer; dfb_surface_buffer_ref( mesa->buffer ); D_DEBUG_AT( Mesa_Layer, " -> calling drmModePageFlip()\n" ); ret = drmModePageFlip( mesa->fd, mesa->encoder->crtc_id, (u32)(long)left_lock->handle, DRM_MODE_PAGE_FLIP_EVENT, driver_data ); if (ret) { D_PERROR( "DirectFB/Mesa: drmModePageFlip() failed!\n" ); return DFB_FAILURE; } dfb_surface_flip( surface, false ); direct_mutex_lock( &mesa->lock ); mesa->flip_pending = true; direct_waitqueue_broadcast( &mesa->wq_flip ); if ((flags & DSFLIP_WAITFORSYNC) == DSFLIP_WAITFORSYNC) { while (mesa->flip_pending) { D_DEBUG_AT( Mesa_Layer, " -> waiting for pending flip (WAITFORSYNC)\n" ); direct_waitqueue_wait( &mesa->wq_event, &mesa->lock ); } } direct_mutex_unlock( &mesa->lock ); return DFB_OK; }