uint32_t popMsgFromBuf(tBufObject* psBuffer, tMsgObject* psMsgObject) { if(isBufEmpty(psBuffer)) { // nothing to drop, so just set status... psBuffer->ui32Flags |= BUF_OBJ_EMPTY_POP; // then, return empty message object stageMsgObject(psMsgObject, 0x00, 0x00, 0); return psBuffer->ui32Flags; } // pop data from an offset based on the actual size of the psBufferfer *psMsgObject = psBuffer->psMessages[psBuffer->ui64ReadIdx++ % psBuffer->ui64BufferDepth]; if((psBuffer->ui32Flags & BUF_OBJ_DATA_LOST) && !(isBufFull(psBuffer))) { // if the error bit for pushing to a full // buffer was previously set, popping one // *might* have corrected that condition. // we can surmise here that if the buffer // is not full, then data will not be lost // on the next push, so we will just count on // that condition being tracked by the caller // when it occurs in push operations psBuffer->ui32Flags &= ~(BUF_OBJ_DATA_LOST); } return getBufStatus(psBuffer); }
static void clearBufPackets(PacketNode *tail) { PacketNode *oldLast = tail->prev; LOG("Cap end, send all %d packets. Buffer at max: %s", bufSize, bufSize); while (!isBufEmpty()) { insertAfter(popNode(bufTail->prev), oldLast); --bufSize; } }
static void clearBufPackets(PacketNode *tail) { PacketNode *oldLast = tail->prev; LOG("Throttled end, send all %d packets. Buffer at max: %s", bufSize, bufSize == KEEP_AT_MOST ? "YES" : "NO"); while (!isBufEmpty()) { bufSizeByte -= bufTail->prev->packetLen; insertAfter(popNode(bufTail->prev), oldLast); --bufSize; } BWLimiterStartTick = 0; }
static void capStartUp() { if (bufHead->next == NULL && bufTail->next == NULL) { bufHead->next = bufTail; bufTail->prev = bufHead; bufSize = 0; } else { assert(isBufEmpty()); } startTimePeriod(); capLastTick = timeGetTime(); }
static void BWLimiterStartUp() { if (bufHead->next == NULL && bufTail->next == NULL) { bufHead->next = bufTail; bufTail->prev = bufHead; bufSize = 0; } else { assert(isBufEmpty()); } BWLimiterStartTick = 0; startTimePeriod(); }
static short BWLimiterProcess(PacketNode *head, PacketNode *tail) { int dropped = 0; DWORD currentTime = timeGetTime(); PacketNode *pac = tail->prev; // pick up all packets and fill in the current time while (pac != head) { if (checkDirection(pac->addr.Direction, BWLimiterInbound, BWLimiterOutbound)) { if ( bufSizeByte >= ((DWORD)BWQueueSizeValue*1024)) { LOG("droped with chance, direction %s", BOUND_TEXT(pac->addr.Direction)); freeNode(popNode(pac)); ++dropped; } else { insertAfter(popNode(pac), bufHead)->timestamp = timeGetTime(); ++bufSize; bufSizeByte += pac->packetLen; pac = tail->prev; } } else { pac = pac->prev; } } while (!isBufEmpty() && canSendPacket(currentTime)) { PacketNode *pac = bufTail->prev; bufSizeByte -= pac->packetLen; recordSentPacket(currentTime, pac->packetLen); insertAfter(popNode(bufTail->prev), head); --bufSize; } if (bufSize > 0) { LOG("Queued buffers : %d", bufSize); } return (bufSize>0) || (dropped>0); }
static short capProcess(PacketNode *head, PacketNode *tail) { short capped = FALSE; PacketNode *pac, *pacTmp, *oldLast; DWORD curTick = timeGetTime(); DWORD deltaTick = curTick - capLastTick; int bytesCapped = (int)(deltaTick * 0.001 * kps * FIXED_EPSILON * 1024); int totalBytes = 0; LOG("kps val: %d, capped kps %.2f, capped at %d bytes", kps, kps * FIXED_EPSILON, bytesCapped); capLastTick = curTick; // process buffered packets oldLast = tail->prev; while (!isBufEmpty()) { // TODO should check direction in buffer? // sends at least one from buffer or it would get stuck pac = bufTail->prev; totalBytes += pac->packetLen; insertAfter(popNode(pac), oldLast); --bufSize; LOG("sending out packets of %d bytes", totalBytes); if (totalBytes > bytesCapped) { break; } } // process live packets pac = oldLast; while (pac != head) { if (!checkDirection(pac->addr.Direction, capInbound, capOutbound)) { pac = pac->prev; continue; } // live packets can all be kept totalBytes += pac->packetLen; if (totalBytes > bytesCapped) { int capCnt = 0; capped = TRUE; // buffer from pac to head while (bufSize < KEEP_AT_MOST && pac != head) { pacTmp = pac->prev; insertAfter(popNode(pac), bufHead); ++bufSize; ++capCnt; pac = pacTmp; } if (pac != head) { LOG("! hitting cap max, dropping all remaining"); while (pac != head) { pacTmp = pac->prev; freeNode(pac); pac = pacTmp; } } assert(pac == head); LOG("capping %d packets", capCnt); break; } else { pac = pac->prev; } } return capped; }