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 * 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; }
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 ); }
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 ); }
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; }
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 ); }
DirectResult DirectResultTypeRegister( DirectResultType *type ) { DirectResult ret; D_DEBUG_AT( Direct_Result, "%s( %p )\n", __FUNCTION__, type ); D_ASSERT( type != NULL ); D_DEBUG_AT( Direct_Result, " -> refs %d\n", type->refs ); D_DEBUG_AT( Direct_Result, " -> base 0x%08x\n", type->base ); D_DEBUG_AT( Direct_Result, " -> strings %p\n", type->result_strings ); D_DEBUG_AT( Direct_Result, " -> count %u\n", type->result_count ); D_ASSERT( type->result_count > 0 ); D_ASSERT( type->result_count <= D_RESULT_TYPE_SPACE ); D_DEBUG_AT( Direct_Result, " => %s\n", type->result_strings[0] ); ret = direct_mutex_lock( &result_mutex ); if (ret) return ret; if (direct_hash_lookup( &result_types, type->base )) { D_ASSERT( direct_hash_lookup( &result_types, type->base ) == type ); D_MAGIC_ASSERT( type, DirectResultType ); D_ASSERT( type->refs > 0 ); type->refs++; } else { D_ASSERT( type->refs == 0 ); D_MAGIC_SET( type, DirectResultType ); ret = direct_hash_insert( &result_types, type->base, (void*) type ); if (ret) D_MAGIC_CLEAR( type ); else type->refs = 1; } direct_mutex_unlock( &result_mutex ); return ret; }
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 DirectUnregisterInterface( DirectInterfaceFuncs *funcs ) { DirectInterfaceImplementation *impl; D_DEBUG_AT( Direct_Interface, "%s( %p )\n", __FUNCTION__, funcs ); direct_mutex_lock( &implementations_mutex ); direct_list_foreach (impl, implementations) { D_MAGIC_ASSERT( impl, DirectInterfaceImplementation ); if (impl->funcs == funcs) { direct_list_remove( &implementations, &impl->link ); break; } }
DirectResult direct_signal_handler_remove( DirectSignalHandler *handler ) { D_MAGIC_ASSERT( handler, DirectSignalHandler ); D_DEBUG_AT( Direct_Signals, "Removing handler %p for signal %d with context %p...\n", handler->func, handler->num, handler->ctx ); direct_mutex_lock( &handlers_lock ); direct_list_remove( &handlers, &handler->link ); direct_mutex_unlock( &handlers_lock ); D_MAGIC_CLEAR( handler ); D_FREE( handler ); return DR_OK; }
void direct_dbg_free( const char *file, int line, const char *func, const char *what, void *mem ) { unsigned long *val; MemDesc *desc; if (!mem) { D_WARN( "%s (NULL) called", __FUNCTION__ ); return; } val = (unsigned long*)((char*) mem - DISABLED_OFFSET); if (val[0] == ~0) { D_DEBUG_AT( Direct_Mem, " - number of bytes of %s [%s:%d in %s()] -> %p\n", what, file, line, func, mem ); val[0] = 0; direct_free( val ); return; } /* Debug only. */ direct_mutex_lock( &alloc_lock ); desc = (MemDesc*)((char*) mem - sizeof(MemDesc)); D_ASSERT( desc->mem == mem ); if (direct_hash_remove( &alloc_hash, (unsigned long) mem )) { D_ERROR( "Direct/Mem: Not freeing unknown %p (%s) from [%s:%d in %s()] - corrupt/incomplete list?\n", mem, what, file, line, func ); } else { D_DEBUG_AT( Direct_Mem, " -"_ZUn(6)" bytes [%s:%d in %s()] -> %p '%s'\n", desc->bytes, file, line, func, mem, what ); if (desc->trace) direct_trace_free_buffer( desc->trace ); direct_free( desc ); } direct_mutex_unlock( &alloc_lock ); }
void direct_print_memleaks( void ) { unsigned long total = 0; /* Debug only. */ direct_mutex_lock( &alloc_lock ); if (alloc_hash.count) { direct_log_printf( NULL, "Local memory allocations remaining (%d): \n", alloc_hash.count ); direct_hash_iterate( &alloc_hash, local_alloc_hash_iterator, &total ); } direct_mutex_unlock( &alloc_lock ); if (total) direct_log_printf( NULL, "%7lu bytes in total\n", total ); }
static ssize_t Write( VoodooLink *link, const void *buffer, size_t count ) { ssize_t ret; Link *l = link->priv; direct_mutex_lock( &l->lock ); ret = send( l->socket, buffer, count, 0 ); if (ret < 0) { D_PERROR( "send(): WSA error %d\n", WSAGetLastError() ); } direct_mutex_unlock( &l->lock ); return ret; }
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 * direct_dbg_calloc( const char* file, int line, const char *func, size_t count, size_t bytes ) { void *mem; unsigned long *val; D_DEBUG_AT( Direct_Mem, " +"_ZUn(6)" bytes [%s:%d in %s()]\n", count * bytes, file, line, func ); if (direct_config->debugmem) { MemDesc *desc; mem = direct_calloc( 1, count * bytes + sizeof(MemDesc) ); D_DEBUG_AT( Direct_Mem, " '-> %p\n", mem ); if (!mem) return NULL; desc = fill_mem_desc( mem, count * 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 ); return desc->mem; } mem = direct_calloc( 1, count * bytes + DISABLED_OFFSET ); D_DEBUG_AT( Direct_Mem, " '-> %p\n", mem ); if (!mem) return NULL; val = mem; val[0] = ~0; return (char*) mem + DISABLED_OFFSET; }
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 ); OneQueue_Attach( hub->notify_qid, request->listen_qid ); direct_mutex_unlock( &hub->lock ); }
DirectResult fusion_ref_up (FusionRef *ref, bool global) { DirectResult ret = DR_OK; D_ASSERT( ref != NULL ); direct_mutex_lock (&ref->single.lock); if (ref->single.destroyed) ret = DR_DESTROYED; else if (ref->single.locked) ret = DR_LOCKED; else ref->single.refs++; direct_mutex_unlock (&ref->single.lock); return ret; }
DirectResult fusion_ref_unlock (FusionRef *ref) { DirectResult ret = DR_OK; D_ASSERT( ref != NULL ); direct_mutex_lock (&ref->single.lock); if (ref->single.locked == direct_gettid()) { ref->single.locked = 0; direct_waitqueue_broadcast (&ref->single.cond); } else ret = DR_ACCESSDENIED; direct_mutex_unlock (&ref->single.lock); return ret; }
void VoodooConnectionLink::Flush( VoodooPacket *packet ) { D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionLink::%s( %p, packet %p )\n", __func__, this, packet ); D_MAGIC_ASSERT( this, VoodooConnection ); direct_mutex_lock( &output.lock ); D_ASSERT( !direct_list_contains_element_EXPENSIVE( output.packets, &packet->link ) ); D_ASSERT( !packet->sending ); packet->sending = true; direct_list_append( &output.packets, &packet->link ); direct_mutex_unlock( &output.lock ); link->WakeUp( link ); }
VoodooConnectionLink::~VoodooConnectionLink() { D_DEBUG_AT( Voodoo_Connection, "VoodooConnectionLink::%s( %p )\n", __func__, this ); D_MAGIC_ASSERT( this, VoodooConnection ); /* Acquire locks and wake up waiters. */ direct_mutex_lock( &output.lock ); direct_waitqueue_broadcast( &output.wait ); direct_mutex_unlock( &output.lock ); /* Destroy conditions. */ direct_waitqueue_deinit( &output.wait ); /* Destroy locks. */ direct_mutex_deinit( &output.lock ); /* Deallocate buffers. */ D_FREE( input.buffer ); direct_tls_unregister( &output.tls ); }
DirectResult fusion_ref_zero_trylock (FusionRef *ref) { DirectResult ret = DR_OK; D_ASSERT( ref != NULL ); direct_mutex_lock (&ref->single.lock); if (ref->single.destroyed) ret = DR_DESTROYED; else if (ref->single.locked) ret = DR_LOCKED; else if (ref->single.refs) ret = DR_BUSY; else ref->single.locked = direct_gettid(); direct_mutex_unlock (&ref->single.lock); return ret; }
static void CoreInputHubClient_Dispatch( void *context, const OnePacketHeader *header, void *data, OneThread *thread ) { CoreInputHubClient *client = context; const InputHubNotification *notification = data; D_DEBUG_AT( Core_InputHub, "%s()\n", __FUNCTION__ ); switch (notification->type) { case IHNT_ATTACHED: direct_mutex_lock( &client->lock ); client->activate_stop = true; direct_waitqueue_broadcast( &client->wq ); direct_mutex_unlock( &client->lock ); break; case IHNT_DEVICE_ADD: CoreInputHubClient_Dispatch_DeviceAdd( client, notification ); break; case IHNT_DEVICE_REMOVE: CoreInputHubClient_Dispatch_DeviceRemove( client, notification ); break; case IHNT_EVENT_DISPATCH: CoreInputHubClient_Dispatch_EventDispatch( client, notification ); break; default: D_BUG( "unknown notification type %d", notification->type ); } }
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; }
DirectResult DirectResultTypeUnregister( DirectResultType *type ) { DirectResult ret; D_DEBUG_AT( Direct_Result, "%s( %p )\n", __FUNCTION__, type ); D_MAGIC_ASSERT( type, DirectResultType ); D_DEBUG_AT( Direct_Result, " -> refs %d\n", type->refs ); D_DEBUG_AT( Direct_Result, " -> base 0x%08x\n", type->base ); D_DEBUG_AT( Direct_Result, " -> strings %p\n", type->result_strings ); D_DEBUG_AT( Direct_Result, " -> count %u\n", type->result_count ); D_ASSERT( type->result_count > 0 ); D_ASSERT( type->result_count <= D_RESULT_TYPE_SPACE ); D_DEBUG_AT( Direct_Result, " => %s\n", type->result_strings[0] ); ret = direct_mutex_lock( &result_mutex ); if (ret) return ret; D_ASSERT( type->refs > 0 ); D_ASSERT( direct_hash_lookup( &result_types, type->base ) == type ); if (! --(type->refs)) { D_MAGIC_CLEAR( type ); ret = direct_hash_remove( &result_types, type->base ); } direct_mutex_unlock( &result_mutex ); return ret; }
void DirectRegisterInterface( DirectInterfaceFuncs *funcs ) { DirectInterfaceImplementation *impl; D_DEBUG_AT( Direct_Interface, "%s( %p )\n", __FUNCTION__, funcs ); impl = (DirectInterfaceImplementation*) D_CALLOC( 1, sizeof(DirectInterfaceImplementation) ); D_DEBUG_AT( Direct_Interface, " -> %p\n", impl ); impl->funcs = funcs; impl->type = funcs->GetType(); impl->implementation = funcs->GetImplementation(); D_MAGIC_SET( impl, DirectInterfaceImplementation ); D_DEBUG_AT( Direct_Interface, " -> %s | %s\n", impl->type, impl->implementation ); direct_mutex_lock( &implementations_mutex ); direct_list_prepend( &implementations, &impl->link ); direct_mutex_unlock( &implementations_mutex ); }
VoodooDispatcher::~VoodooDispatcher() { D_DEBUG_AT( Voodoo_Dispatcher, "VoodooDispatcher::%s( %p )\n", __func__, this ); D_MAGIC_ASSERT( this, VoodooDispatcher ); /* Acquire lock and wake up waiters. */ direct_mutex_lock( &lock ); direct_waitqueue_broadcast( &queue ); direct_mutex_unlock( &lock ); /* Wait for dispatcher loop exiting. */ direct_thread_join( dispatch_loop ); direct_thread_destroy( dispatch_loop ); /* Destroy queue. */ direct_waitqueue_deinit( &queue ); /* Destroy lock. */ direct_mutex_deinit( &lock ); D_MAGIC_CLEAR( this ); }
static void * CoreInputHubClient_ActivateThread( DirectThread *thread, void *arg ) { CoreInputHubClient *client = arg; InputHubAttachRequest request; D_DEBUG_AT( Core_InputHub, "%s()\n", __FUNCTION__ ); direct_mutex_lock( &client->lock ); while (!client->activate_stop) { request.listen_qid = client->listen_qid; OneQueue_Dispatch( client->remote_qid, &request, sizeof(request) ); direct_waitqueue_wait_timeout( &client->wq, &client->lock, 1000000 ); } direct_mutex_unlock( &client->lock ); return DFB_OK; }