/***********************************************************
 * Name: os_cond_wait
 *
 * Arguments:  OS_COND_T *cond,
 *             OS_SEMAPHORE_T *semaphore
 *
 * Description: Routine to wait for a condition variable
 *              to be signalled. Semaphore is released
 *              while waiting. The same semaphore must
 *              always be used.
 *
 * Returns: int32_t - success == 0
 *
 ***********************************************************/
int32_t os_cond_wait( OS_COND_T *cond, OS_SEMAPHORE_T *semaphore )
{
   int32_t success = -1;
    
   if (cond && semaphore)
   {
      COND_WAITER_T w;
      COND_WAITER_T *p, **prev;
       
      // Check the API is being followed
      os_assert((*cond)->semaphore == semaphore && os_semaphore_obtained(semaphore));
      
      // Fill in a new waiter structure allocated on our stack
      w.next = NULL;
      vcos_demand(vcos_event_create(&w.latch, NULL) == VCOS_SUCCESS);
      
      // Add it to the end of the condvar's wait queue (we wake first come, first served)
      prev = &(*cond)->waiters;
      p = (*cond)->waiters;
      while (p)
         prev = &p->next, p = p->next;
      *prev = &w;

      // Ready to go to sleep now
      success = os_semaphore_release(semaphore);
      os_assert(success == 0);

      vcos_event_wait(&w.latch);

      success = os_semaphore_obtain(semaphore);
      os_assert(success == 0);
   }
   
   return success;
}
Exemplo n.º 2
0
static void __inline remote_event_create(REMOTE_EVENT_T *event)
{
#ifdef VCHIQ_LOCAL
   vcos_event_create(&event->event, "vchiq");
#else
   event->set_count = 0;
   event->clr_count = 0;
   local_event_create(&event->local);
#endif
}
Exemplo n.º 3
0
int vchiu_queue_init(VCHIU_QUEUE_T *queue, int size)
{
   vcos_assert(is_pow2(size));

   queue->size = size;
   queue->read = 0;
   queue->write = 0;

   vcos_event_create(&queue->pop, "vchiu");
   vcos_event_create(&queue->push, "vchiu");

   queue->storage = vcos_malloc(size * sizeof(VCHIQ_HEADER_T *), VCOS_FUNCTION);
   if (queue->storage == NULL)
   {
      vchiu_queue_delete(queue);
      return 0;
   }
   return 1;
}
Exemplo n.º 4
0
static int start_monitor( void )
{
   if ( vcos_event_create( &quit_event, "smem" ) != VCOS_SUCCESS )
   {
      vcos_log_info( "Failed to create quit event" );

      return -1;
   }

   // Handle the INT and TERM signals so we can quit
   signal( SIGINT, control_c );
   signal( SIGTERM, control_c );

   return 0;
}
Exemplo n.º 5
0
void vchiq_init_state(VCHIQ_STATE_T *state, VCHIQ_CHANNEL_T *local, VCHIQ_CHANNEL_T *remote)
{
   VCOS_THREAD_ATTR_T attrs;
   char threadname[8];
   static int id = 0;

   vcos_assert(is_pow2(VCHIQ_CHANNEL_SIZE));

   vcos_assert(is_pow2(VCHIQ_NUM_CURRENT_BULKS));
   vcos_assert(is_pow2(VCHIQ_NUM_SERVICE_BULKS));

   vcos_assert(sizeof(VCHIQ_HEADER_T) == 8);    /* we require this for consistency between endpoints */

   memset(state, 0, sizeof(VCHIQ_STATE_T));
   state->id = id++;

   /*
      initialize events and mutex
   */

   vcos_event_create(&state->connect, "vchiq");
   vcos_mutex_create(&state->mutex, "vchiq");

   /*
      initialize channel pointers
   */

   state->local  = local;
   state->remote = remote;
   vchiq_init_channel(local);

   /*
      bring up slot handler thread
   */

   vcos_thread_attr_init(&attrs);
   vcos_thread_attr_setstacksize(&attrs, VCHIQ_SLOT_HANDLER_STACK);
   vcos_thread_attr_setpriority(&attrs, 5); /* FIXME: should not be hardcoded */
   vcos_thread_attr_settimeslice(&attrs, 20); /* FIXME: should not be hardcoded */
   strcpy(threadname, "VCHIQ-0");
   threadname[6] += state->id % 10;
   vcos_thread_create(&state->slot_handler_thread, threadname,
                      &attrs, slot_handler_func, state);

   /* Indicate readiness to the other side */
   local->initialised = 1;
}
static int start_monitor( void )
{
   if ( vcos_event_create( &quit_event, "tvservice" ) != VCOS_SUCCESS )
   {
      LOG_ERR( "Failed to create quit event" );

      return -1;
   }

   // Handle the INT and TERM signals so we can quit
   signal( SIGINT, control_c );
   signal( SIGTERM, control_c );

   vc_tv_register_callback( &tvservice_callback, NULL );

   return 0;
}
bool khrn_worker_init(void)
{
#ifndef KHRN_WORKER_USE_LLAT
   VCOS_THREAD_ATTR_T attr;
#endif
   vcos_assert(!inited);

   khrn_worker_enter_pos = 0;
   khrn_worker_exit_pos_0 = 0;
   khrn_worker_exit_pos_1 = 0;

   khrn_worker_msg.post = msgs;
   khrn_worker_msg.done_it = msgs;
   khrn_worker_msg.cleanup = msgs;

#ifdef KHRN_WORKER_USE_LLAT
   llat_i = khrn_llat_register(khrn_worker_llat_callback);
   vcos_assert(llat_i != -1);
#else
   if (vcos_event_create(&event, "khrn_worker_event") != VCOS_SUCCESS) {
      return false;
   }

   exit_thread = false;

   vcos_thread_attr_init(&attr);
   vcos_thread_attr_setpriority(&attr, THREAD_PRIORITY);
#if !defined(V3D_LEAN)
   switch (vcos_thread_get_affinity(vcos_thread_current())) {
   case VCOS_AFFINITY_CPU0: vcos_thread_attr_setaffinity(&attr, VCOS_AFFINITY_CPU1); break;
   case VCOS_AFFINITY_CPU1: vcos_thread_attr_setaffinity(&attr, VCOS_AFFINITY_CPU0); break;
   }
   vcos_thread_attr_setstacksize(&attr, THREAD_STACK_SIZE);
#endif /* V3D_LEAN */
   if (vcos_thread_create(&thread, "khrn_worker_thread", &attr, khrn_worker_main, NULL) != VCOS_SUCCESS) {
      vcos_event_delete(&event);
      return false;
   }
#endif

   inited = true;

   return true;
}
	CComponent::CComponent(std::string sName, CGraph* pGraph) : m_sName(std::move(sName)), m_hComponent(NULL), m_pGraph(pGraph)
	{
		std::string sStateChangedEventName(m_sName);
		sStateChangedEventName.append(":state_changed_event");
		CHECK_VCOS(vcos_event_create(&m_StateChangedEvent, sStateChangedEventName.c_str()), "failed to create vcos event");
		std::string sEventThreadName(m_sName);
		sEventThreadName.append(":event_thread");
		m_EventThread.Start(&CComponent::EventThreadProc, this, sEventThreadName.c_str());
		std::string sEventQueueMutexName(m_sName);
		sEventQueueMutexName.append(":event_queue_mutex");
		vcos_mutex_create(&m_EventQueueMutex, sEventThreadName.c_str());
		OMX_CALLBACKTYPE Callbacks;
		Callbacks.EventHandler = &CComponent::EventHandler;
		Callbacks.EmptyBufferDone = &CComponent::EmptyBufferDone;
		Callbacks.FillBufferDone = &CComponent::FillBufferDone;
		std::string sError("failed to create component ");
		sError.append(m_sName);
		CHECK_OMX(OMX_GetHandle(&m_hComponent, const_cast<char*>(m_sName.c_str()), this, &Callbacks), sError.c_str());
	}
void vc_vchi_khronos_init()
{
   VCOS_STATUS_T status = vcos_event_create(&bulk_event, NULL);
   assert(status == VCOS_SUCCESS);
   
   if (vchiq_initialise(&khrn_vchiq_instance) != VCHIQ_SUCCESS)
   {
      KHRONOS_CLIENT_LOG("* failed to open vchiq device\n");
      
      exit(1);
   }

   KHRONOS_CLIENT_LOG("gldemo: connecting\n");

   if (vchiq_connect(khrn_vchiq_instance) != VCHIQ_SUCCESS)
   {
      KHRONOS_CLIENT_LOG("* failed to connect\n");
      
      exit(1);
   }

   if (vchiq_open_service(khrn_vchiq_instance, FOURCC_KHAN, khan_callback, NULL, &vchiq_khan_service) != VCHIQ_SUCCESS ||
       vchiq_open_service(khrn_vchiq_instance, FOURCC_KHRN, khrn_callback, NULL, &vchiq_khrn_service) != VCHIQ_SUCCESS ||
       vchiq_open_service(khrn_vchiq_instance, FOURCC_KHHN, khhn_callback, NULL, &vchiq_khhn_service) != VCHIQ_SUCCESS)
   {
      KHRONOS_CLIENT_LOG("* failed to add service - already in use?\n");
      
      exit(1);
   }

   vchiu_queue_init(&khrn_queue, 64);
   vchiu_queue_init(&khhn_queue, 64);

   KHRONOS_CLIENT_LOG("gldemo: connected\n");

   /*
      attach to process (there's just one)
   */

//   bool success = client_process_attach();
//   assert(success);
}
Exemplo n.º 10
0
void vc_vchi_gencmd_init (VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections )
{
   VCOS_STATUS_T status;
   int32_t success;
   int i;

   if (gencmd_client.initialised)
     return;

   // record the number of connections
   memset( &gencmd_client, 0, sizeof(GENCMD_SERVICE_T) );
   gencmd_client.num_connections = (int) num_connections;

   status = vcos_mutex_create(&gencmd_client.lock, "HGencmd");
   vcos_assert(status == VCOS_SUCCESS);
   status = vcos_event_create(&gencmd_client.message_available_event, "HGencmd");
   vcos_assert(status == VCOS_SUCCESS);

   for (i=0; i<gencmd_client.num_connections; i++) {

      // Create a 'LONG' service on the each of the connections
      SERVICE_CREATION_T gencmd_parameters = { VCHI_VERSION(VC_GENCMD_VER),
                                               MAKE_FOURCC("GCMD"),      // 4cc service code
                                               connections[i],           // passed in fn ptrs
                                               0,                        // tx fifo size (unused)
                                               0,                        // tx fifo size (unused)
                                               &gencmd_callback,         // service callback
                                               &gencmd_client.message_available_event, // callback parameter
                                               VC_FALSE,                 // want_unaligned_bulk_rx
                                               VC_FALSE,                 // want_unaligned_bulk_tx
                                               VC_FALSE                  // want_crc
                                               };

      success = vchi_service_open( initialise_instance, &gencmd_parameters, &gencmd_client.open_handle[i] );
      assert( success == 0 );
   }

   gencmd_client.initialised = 1;
   release_gencmd_service();
}
Exemplo n.º 11
0
void vc_vchi_dispmanx_init (VCHI_INSTANCE_T initialise_instance, VCHI_CONNECTION_T **connections, uint32_t num_connections ) {
   VCOS_STATUS_T status;
   int32_t success;
   uint32_t i;

   // record the number of connections
   memset( &dispmanx_client, 0, sizeof(DISPMANX_SERVICE_T) );
   dispmanx_client.num_connections = num_connections;

   status = vcos_mutex_create(&dispmanx_client.lock, "HDispmanx");
   vcos_assert(status == VCOS_SUCCESS);

   status = vcos_event_create(&dispmanx_message_available_event, "HDispmanx");
   vcos_assert(status == VCOS_SUCCESS);

   status = vcos_event_create(&dispmanx_notify_available_event, "HDispmanx");
   vcos_assert(status == VCOS_SUCCESS);

   dispmanx_client.initialised = 1;

   for (i=0; i<dispmanx_client.num_connections; i++) {

      VCOS_THREAD_ATTR_T attrs;

      // Create a 'Client' service on the each of the connections
      SERVICE_CREATION_T dispmanx_parameters = { DISPMANX_CLIENT_NAME,     // 4cc service code
                                                 connections[i],           // passed in fn ptrs
                                                 0,                        // tx fifo size (unused)
                                                 0,                        // tx fifo size (unused)
                                                 &dispmanx_client_callback, // service callback
                                                 &dispmanx_message_available_event,  // callback parameter
                                                 VC_FALSE,                  // want_unaligned_bulk_rx
                                                 VC_FALSE,                  // want_unaligned_bulk_tx
                                                 VC_FALSE,                  // want_crc
                                                 };

      SERVICE_CREATION_T dispmanx_parameters2 = { DISPMANX_NOTIFY_NAME,   // 4cc service code
                                                  connections[i],           // passed in fn ptrs
                                                  0,                        // tx fifo size (unused)
                                                  0,                        // tx fifo size (unused)
                                                  &dispmanx_notify_callback, // service callback
                                                  &dispmanx_notify_available_event,  // callback parameter
                                                  VC_FALSE,                  // want_unaligned_bulk_rx
                                                  VC_FALSE,                  // want_unaligned_bulk_tx
                                                  VC_FALSE,                  // want_crc
                                                   };

      success = vchi_service_open( initialise_instance, &dispmanx_parameters, &dispmanx_client.client_handle[i] );
      vcos_assert( success == 0 );

      // Create the async service of dispman to handle update callback

      success = vchi_service_open( initialise_instance, &dispmanx_parameters2, &dispmanx_client.notify_handle[i] );
      vcos_assert( success == 0 );

      //Create the notifier task
      vcos_thread_attr_init(&attrs);
      vcos_thread_attr_setstacksize(&attrs, 2048);
      vcos_thread_attr_settimeslice(&attrs, 1);

      status = vcos_thread_create(&dispmanx_notify_task, "HDispmanx Notify", &attrs, dispmanx_notify_func, NULL);
      vcos_assert(status == VCOS_SUCCESS);

      // release services until they're actually used
      vchi_service_release(dispmanx_client.client_handle[i]);
      vchi_service_release(dispmanx_client.notify_handle[i]);
   }
}
Exemplo n.º 12
0
static void __inline local_event_create(LOCAL_EVENT_T *event)
{
   vcos_event_create(&event->event, "vchiq");
}
Exemplo n.º 13
0
		CThreadT() : m_pInstance(NULL), m_pThreadProc(NULL)
		{
			CHECK_VCOS(vcos_event_create(&m_InitializedEvent, ""), "failed to create thread initialization event");
			CHECK_VCOS(vcos_event_flags_create(&m_EventFlags, ""), "failed to create thread event flags");
		}