/*********************************************************** * 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; }
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 }
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; }
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; }
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); }
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(); }
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]); } }
static void __inline local_event_create(LOCAL_EVENT_T *event) { vcos_event_create(&event->event, "vchiq"); }
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"); }