/* you must be inside a m_mutex lock to invoke this! */ static void insert(NVEventQueue* q, NVEvent* ev) { // Is the queue full? int32_t nextNext = NVNextWrapped(q->m_nextInsertIndex); if (nextNext == q->m_headIndex) { int32_t cur = nextNext; while( (cur != q->m_nextInsertIndex) && isSacred(q->m_events[cur].m_type) ) { cur = NVNextWrapped(cur); } // if we didn't go all the way around, replace the cur and return if( cur != q->m_nextInsertIndex ) { memcpy(q->m_events + cur, ev, sizeof(NVEvent)); __android_log_print(ANDROID_LOG_DEBUG, MODULE, "FULL QUEUE"); return; } } memcpy(q->m_events + q->m_nextInsertIndex, ev, sizeof(NVEvent)); q->m_nextInsertIndex = nextNext; }
/* you must be inside a m_accessLock lock to invoke this! */ bool NVEventQueue::insert(NVEvent const * ev) { // Is the queue full? int32_t nextNext = NVNextWrapped(m_nextInsertIndex); if (nextNext == m_headIndex) { // TBD - what to do when we cannot insert (full queue) return false; } NVEvent * evDest = m_events + m_nextInsertIndex; memcpy(evDest, ev, sizeof(NVEvent)); m_nextInsertIndex = nextNext; return true; }
static void NVEventFlushQueue(NVEventQueue* q) { pthread_mutex_lock(&(q->m_mutex)); int newNextInsertIndex = q->m_headIndex; for(int i = q->m_headIndex; i != q->m_nextInsertIndex; i = NVNextWrapped(i)) { NVEvent* ev = &(q->m_events[i]); if(isSacred(ev->m_type)) { q->m_events[newNextInsertIndex++] = *ev; break; } } pthread_mutex_unlock(&(q->m_mutex)); }
static int32_t NVEventRemoveOldest(NVEventQueue* q, NVEvent* ev, int waitMSecs) { pthread_mutex_lock(&(q->m_mutex)); int retVal = 1; if(q->m_processingPause) { q->m_processingPause = false; signal(&(q->m_javaSync)); } if (q->m_nextInsertIndex == q->m_headIndex) { // We're empty - so what do we do? if (waitMSecs == 0) { // can't wait - gotta go! Return no event; retVal = 0; goto no_event; } else { // wait for the specified time wait(&(q->m_nativeSync), &(q->m_mutex), (unsigned)waitMSecs); } // check again after exiting cond waits, either we had a timeout if (q->m_nextInsertIndex == q->m_headIndex) { // Still nothing retVal = 0; goto no_event; } } // One way or another, we have an event... memcpy(ev, q->m_events + q->m_headIndex, sizeof(NVEvent)); if(ev->m_type == NV_EVENT_PAUSE) q->m_processingPause = true; q->m_headIndex = NVNextWrapped(q->m_headIndex); no_event: pthread_mutex_unlock(&(q->m_mutex)); return retVal; }
/* you must be inside a m_mutex lock to invoke this! */ static bool scanForEvents(NVEventQueue* q) { DEBUG("scanForEvents"); for(int32_t i = 0; i < q->m_waitEventTypeCount; ++i) DEBUG(" event %s", NVEventGetEventStr((NVEventType)q->m_waitEventTypes[i])); // scan events in our queue, return true if found and // set ev if it's not null for(int32_t i = q->m_headIndex; i != q->m_nextInsertIndex; i = NVNextWrapped(i)) { const NVEvent* event = &q->m_events[i]; DEBUG("examining event type [%d]: %s", i, NVEventGetEventStr(event->m_type)); if (isEventType(q, event)) { DEBUG("event matched"); return true; } } DEBUG("event not matched"); return false; }
const NVEvent* NVEventQueue::RemoveOldest(int waitMSecs) { pthread_mutex_lock(&m_accessLock); // Hmm - the last event we got from RemoveOldest was a // blocker, and DoneWithEvent not called. // Default to "false" as a return value if (m_blockerState == PROCESSING_BLOCKER) { m_blockerReturnVal = false; m_blockerState = RETURNED_BLOCKER; broadcast(&m_blockerSync); } // Blocker is waiting - return it // And push the blocker pipeline forward if(m_blockerState == PENDING_BLOCKER) { m_blockerState = PROCESSING_BLOCKER; const NVEvent* ev = m_blocker; pthread_mutex_unlock(&m_accessLock); return ev; } else if (m_nextInsertIndex == m_headIndex) { // We're empty - so what do we do? if (waitMSecs == 0) { goto no_event; } else { // wait for the specified time wait(&m_consumerSync, &m_accessLock, (unsigned)waitMSecs); } // check again after exiting cond waits, either we had a timeout if(m_blockerState == PENDING_BLOCKER) { m_blockerState = PROCESSING_BLOCKER; const NVEvent* ev = m_blocker; pthread_mutex_unlock(&(m_accessLock)); return ev; } else if (m_nextInsertIndex == m_headIndex) { goto no_event; } } { // One way or another, we have an event... NVEvent const * ev = m_events + m_headIndex; m_headIndex = NVNextWrapped(m_headIndex); pthread_mutex_unlock(&m_accessLock); return ev; } no_event: pthread_mutex_unlock(&m_accessLock); return NULL; }