예제 #1
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] );
          }
     }
}
예제 #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;
}
예제 #3
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();
}
예제 #4
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;
}
예제 #5
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;
}
예제 #6
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 );
}
예제 #7
0
파일: dispatcher.cpp 프로젝트: kuii/dfbNEON
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;
}
예제 #8
0
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;
}
예제 #9
0
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;
}
예제 #10
0
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;
}
예제 #11
0
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;
}