Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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( &notification, 0, sizeof(notification) );

     notification.type = IHNT_ATTACHED;

     OneQueue_Dispatch( request->listen_qid, &notification, sizeof(notification) );


     OneQueue_Attach( hub->notify_qid, request->listen_qid );

     direct_mutex_unlock( &hub->lock );
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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();
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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 );
}
Ejemplo n.º 9
0
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( &notification, 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, &notification, sizeof(notification) );

     direct_mutex_unlock( &hub->lock );

     return DFB_OK;
}
Ejemplo n.º 10
0
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( &notification, 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, &notification, sizeof(notification) );

     direct_mutex_unlock( &hub->lock );

     return DFB_OK;
}
Ejemplo n.º 11
0
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";
}
Ejemplo n.º 12
0
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 );
}
Ejemplo n.º 13
0
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 );
     }
Ejemplo n.º 15
0
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 );
     }
Ejemplo n.º 18
0
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 );
}
Ejemplo n.º 19
0
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 );
     }
Ejemplo n.º 21
0
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;
}
Ejemplo n.º 22
0
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;
          }
     }
Ejemplo n.º 23
0
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 );
}
Ejemplo n.º 24
0
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;
}
Ejemplo n.º 25
0
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;
}
Ejemplo n.º 26
0
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 );
}
Ejemplo n.º 27
0
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;
}
Ejemplo n.º 28
0
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 );
}
Ejemplo n.º 29
0
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 );
}
Ejemplo n.º 30
0
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;
}