void v_networkReaderFree( v_networkReader reader) { c_bool sendTo, more; v_message message; c_ulong sequenceNumber, priority; v_gid sender, receiver; os_timeE sendBefore; v_networkReaderEntry entry; c_ulong i; c_keep(reader); /* call inherited free, * which will remove the entry from the associated groups */ v_readerFree(v_reader(reader)); /* remove the messages still pressent in the network queues */ for (i = 0; i < reader->nofQueues; i++) { while (v_networkQueueTakeFirst ( v_networkQueue(reader->queues[i]), &message, &entry, &sequenceNumber, &sender, &sendTo, &receiver, &sendBefore, &priority, &more)) { c_free(message); c_free(entry); } } c_free(reader); }
v_networkReaderWaitResult v_networkReaderWaitDelayed( v_networkReader reader, c_ulong queueId, v_networkQueue *queue) { c_time sleep = {0,1000000}; /* Simply sleeping here for resolution time, is not correct. We should wakeup on, or just after the next wakeuptime.*/ sleep = c_timeAdd(sleep,v_networkQueue(reader->queues[queueId-1])->nextWakeup); sleep = c_timeSub(v_networkQueue(reader->queues[queueId-1])->nextWakeup, v_timeGet()); c_timeNanoSleep(sleep); return V_WAITRESULT_TIMEOUT | v_networkReaderWait(reader, queueId, queue); }
v_networkReaderWaitResult v_networkReaderWaitDelayed( v_networkReader reader, c_ulong queueId, v_networkQueue *queue) { os_duration sleep; /* Simply sleeping here for resolution time, is not correct. * We should wakeup on, or just after the next wakeuptime. */ sleep = os_timeEDiff(v_networkQueue(reader->queues[queueId-1])->nextWakeup, os_timeEGet()); v__kernelProtectWaitEnter(NULL, NULL); ospl_os_sleep(sleep); v__kernelProtectWaitExit(); return V_WAITRESULT_TIMEOUT | v_networkReaderWait(reader, queueId, queue); }
v_networkQueue v_networkQueueNew( c_base base, c_ulong queueSize, c_ulong priority, c_bool reliable, c_bool P2P, c_time resolution, v_networkQueueStatistics statistics) { v_networkQueue result = NULL; c_type type; c_equality equality; c_bool hasChanged; c_time now; type = c_resolve(base, "kernelModule::v_networkQueue"); assert(type); result = v_networkQueue(c_new(type)); c_free(type); if (result) { /* Queue properties */ result->maxMsgCount = queueSize; result->currentMsgCount = 0; /* Cached type */ result->statusMarkerType = c_resolve(base, "kernelModule::v_networkStatusMarker"); assert(result->statusMarkerType != NULL); result->sampleType = c_resolve(base, "kernelModule::v_networkQueueSample"); assert(result->sampleType != NULL); /* Linked list of in-use marker items */ result->firstStatusMarker = NULL; result->lastStatusMarker = NULL; /* Linked list of free marker and message items */ result->freeStatusMarkers = NULL; result->freeSamples = NULL; /* Init cv stuff */ c_mutexInit(&result->mutex, SHARED_MUTEX); c_condInit(&result->cv, &result->mutex, SHARED_COND); /* Currently no differentiation wrt qos */ result->priority = priority; result->reliable = reliable; result->P2P = P2P; result->statistics = statistics; equality = c_timeCompare(C_TIME_ZERO, resolution); if (equality == C_EQ) { result->periodic = FALSE; result->resolution = C_TIME_INFINITE; result->msecsResolution = 0xFFFFFFFF; result->phaseMilliSeconds = 0; result->nextWakeup = C_TIME_INFINITE; } else { assert(equality == C_LT); result->periodic = TRUE; result->resolution = resolution; TIME_TO_MSEC(resolution, result->msecsResolution); /* A semi-random phase to avoid wake-ups at the same time */ now = v_timeGet(); result->phaseMilliSeconds = ((c_ulong)(now.nanoseconds/1000000 * 1.618)) % result->msecsResolution; v_networkQueueUpdateNextWakeup(result, &hasChanged); assert(hasChanged); } result->threadWaiting = FALSE; } else { OS_REPORT(OS_ERROR, "v_networkQueueNew",0, "Failed to allocate network queue."); } return result; }