static void *guard_func(void *param) { GUARD_T *st = (GUARD_T *) param; uint32_t set; while(1) { int i; vcos_event_flags_get(&st->event, -1, VCOS_OR_CONSUME, 0, &set); vcos_semaphore_wait(&st->go); if(st->quit) break; for(i=0; i<2; i++) { if(vcos_event_flags_get(&st->event, 1, VCOS_OR, st->wait[i], &set) != VCOS_SUCCESS) { int j; st->timeout[i] = 1; for(j=0; j<st->post[i]; j++) vcos_semaphore_post(st->guard); } else st->timeout[i] = 0; } vcos_semaphore_post(&st->done); } vcos_thread_exit(NULL); return NULL; }
static int wait_event( VC_POOL_T *pool, uint32_t usecs ) { VCOS_STATUS_T status; VCOS_UNSIGNED timeout; VCOS_UNSIGNED event; if (pool->callback) { vcos_assert(!usecs); //definitely shouldn't be using timeouts with callbacks return -1; //don't try to wait with a callback set } if ( usecs == 0 ) timeout = VCOS_NO_SUSPEND; else if ( usecs == 0xffffffff ) timeout = VCOS_SUSPEND; else timeout = usecs / 1000; status = vcos_event_flags_get( &pool->event, RELEASE_EVENT, VCOS_OR_CONSUME, timeout, &event ); if ( status == VCOS_SUCCESS ) return 0; // success else return -1; // timed out }
static void check_value(VCOS_EVENT_FLAGS_T *event, int expected, int consume, int *passed) { uint32_t set = 0; vcos_event_flags_get(event, -1, consume ? VCOS_OR_CONSUME : VCOS_OR, 0, &set); if(set != expected && passed) *passed = 0; }
static int basic_timeout(void) { int delay = 10; #ifdef VCOS_TIMER_MARGIN_EARLY int margin_early = VCOS_TIMER_MARGIN_EARLY; int margin_late = VCOS_TIMER_MARGIN_LATE; #else int margin_early = SLACK; int margin_late = SLACK; #endif VCOS_EVENT_FLAGS_T flags; VCOS_STATUS_T st = vcos_event_flags_create(&flags, "test"); VCOS_UNSIGNED elapsed_time = vcos_get_ms(), actual; st = vcos_event_flags_get(&flags, 1, VCOS_OR, delay, &actual); if (st == VCOS_EAGAIN) { elapsed_time = vcos_get_ms()-elapsed_time; if (((int) elapsed_time >= (delay - margin_early)) && ((int) elapsed_time <= (delay + margin_late))) { vcos_log("Good delay: %d ms", elapsed_time); vcos_event_flags_delete(&flags); return 1; } vcos_log("Wrong delay: %d ms, expected %d ms", elapsed_time, delay); } vcos_event_flags_delete(&flags); return 0; }
void *CComponent::EventThreadProc(VCOS_EVENT_FLAGS_T& EventFlags, VCOS_EVENT_T& InitialzedEvent) { vcos_event_signal(&InitialzedEvent); VCOS_UNSIGNED nEvents; try { for (;;) { CHECK_VCOS(vcos_event_flags_get(&EventFlags, CThread::s_nTerminationFlag | s_nNewEventFlag, VCOS_CONSUME, VCOS_SUSPEND, &nEvents), "failed to wait for events"); if (nEvents & CThread::s_nTerminationFlag) { // Component is being destoryed break; } else if (nEvents & s_nNewEventFlag) { // New event that cannot be handled in the notification callback bool bEventsPending = false; do { CComponentEvent Event; { CHECK_VCOS(vcos_mutex_lock(&m_EventQueueMutex), "failed to lock event queue mutex"); Event = m_EventQueue.front(); m_EventQueue.pop_front(); bEventsPending = !m_EventQueue.empty(); vcos_mutex_unlock(&m_EventQueueMutex); } switch (Event.m_EventType) { case OMX_EventPortSettingsChanged: { if (m_pGraph) { m_pGraph->OnPortSettingsChanged(this, Event.m_nData1); } } break; default: break; } } while (bEventsPending); } } } catch (std::exception& Exception) { std::cerr << "Error: " << Exception.what() << std::endl; } return NULL; }
static void try_get_value(int *num, VCOS_EVENT_FLAGS_T *event, uint32_t start, uint32_t bitmask, VCOS_OPTION operation, VCOS_STATUS_T expected, int after, int *passed) { VCOS_STATUS_T rc; uint32_t set = 0; vcos_event_flags_get(event, -1, VCOS_OR_CONSUME, 0, &set); vcos_event_flags_set(event, start, VCOS_OR); VCOS_TRACE("%s: mask %x op %s", __FUNCTION__, bitmask, op2str(operation)); if((rc=vcos_event_flags_get(event, bitmask, operation, 0, &set)) != expected) { *passed = 0; } if(expected == VCOS_SUCCESS && set != start) { *passed = 0; } check_value(event, after, 1, passed); }
static void run_waiters(WAITER_T *waiter, int num, int *sleep, uint32_t *bitmask, VCOS_EVENTGROUP_OPERATION_T *operation, int32_t *suspend, int set_sleep, uint32_t set_bitmask, VCOS_STATUS_T *expected, uint32_t after, int *passed) { int i; uint32_t set; VCOS_STATUS_T st; for(i=0; i<num; i++) { waiter[i].sleep_first = sleep ? sleep[i] : 0; waiter[i].bitmask = bitmask[i]; waiter[i].operation = operation[i]; waiter[i].suspend = suspend[i]; vcos_semaphore_post(&waiter[i].go); } if(set_sleep) vcos_sleep(set_sleep); vcos_log("ORring in 0x%x", set_bitmask); vcos_event_flags_set(waiter[0].event, set_bitmask, VCOS_OR); for(i=0; i<num; i++) { vcos_semaphore_wait(&waiter[i].done); if(waiter[i].result != expected[i] || (waiter[i].result == VCOS_SUCCESS && waiter[i].retrieved_bits != set_bitmask)) *passed = 0; } st = vcos_event_flags_get(waiter[0].event, -1, VCOS_OR_CONSUME, 0, &set); if (after == 0 && st != VCOS_EAGAIN) { // we were expecting to retrieve nothing this time, but instead we got something! *passed = 0; vcos_log("run_waiters: got unexpected events back afterwards"); } else if (after && (st != VCOS_SUCCESS) && (set != after)) { // we were expecting to retrieve something, but instead got nothing, or not the right thing! vcos_log("run_waiters: got wrong events back afterwards"); *passed = 0; } }
static void *waiter_func(void *param) { WAITER_T *st = (WAITER_T *) param; while(1) { vcos_semaphore_wait(&st->go); if(st->quit) break; if(st->sleep_first) vcos_sleep(st->sleep_first); st->result = vcos_event_flags_get(st->event, st->bitmask, st->operation, st->suspend, &st->retrieved_bits); vcos_semaphore_post(&st->done); } return 0; }
static int create_test() { int passed = 1; VCOS_EVENT_FLAGS_T events[MAX_TESTED]; int i; for(i=0; i<MAX_TESTED; i++) if(vcos_event_flags_create(events+i,"test") != VCOS_SUCCESS) passed = 0; for(i=0; i<MAX_TESTED; i+=2) vcos_event_flags_delete(events+i); for(i=0; i<MAX_TESTED; i+=2) if(vcos_event_flags_create(events+i,"test") != VCOS_SUCCESS) passed = 0; if(passed) { /* see if the bits appear to be independent */ for(i=0; i<MAX_TESTED; i++) vcos_event_flags_set(events+i, i | (1<<i), VCOS_OR); for(i=0; i<MAX_TESTED; i++) { uint32_t set; if(vcos_event_flags_get(events+i, -1, VCOS_OR, VCOS_NO_SUSPEND, &set) != VCOS_SUCCESS) passed = 0; if(set != (i | (1<<i))) passed = 0; } for(i=0; i<MAX_TESTED; i++) vcos_event_flags_delete(events+i); } return passed; }