EtherLib/msg_queue.c
Wiesner András ab8d45932f Timestamping and bunch of bugfix and optimization
- Timestamping management added
- Errors due to reading uninitialized data in ARP fixed
- EthInterface reworked, incoming packet notification and payload readout separated (through which fixing concurrent access problems)
- RX and TX offloads added
- Capability to add a packet sieve layer without prior registration of specific packet class added (this makes it possible to register arbitrary EtherType connection blocks, for example)
2023-04-27 09:38:26 +02:00

63 lines
1.3 KiB
C

//
// Created by epagris on 2023.01.13..
//
#include <memory.h>
#include <stdbool.h>
#include "msg_queue.h"
#include "dynmem.h"
#include <stdio.h>
MsgQueue *mq_create(uint32_t size) {
MsgQueue *mq = (MsgQueue *) dynmem_alloc(sizeof(MsgQueue) + size * sizeof(RawPckt));
mq->size = size;
mq->readIdx = 0;
mq->writeIdx = 0;
memset(mq->pckts, 0, mq->size * sizeof(RawPckt));
return mq;
}
void mq_clear(MsgQueue *mq) {
mq->readIdx = 0;
mq->writeIdx = 0;
memset(mq->pckts, 0, mq->size * sizeof(RawPckt));
}
uint32_t mq_avail(const MsgQueue *mq) {
int32_t delta = (int32_t) (mq->writeIdx - mq->readIdx);
if (delta < 0) { // modulo...
delta += (int32_t) mq->size;
}
return delta;
}
#define MQ_NEXT(size, current) (((current)+1)%(size))
bool mq_push(MsgQueue *mq, const RawPckt *raw) {
if (MQ_NEXT(mq->size, mq->writeIdx) == mq->readIdx) { // cannot push, queue is full
return false;
}
// can push
mq->pckts[mq->writeIdx] = *raw;
// advance write pointer
mq->writeIdx = MQ_NEXT(mq->size, mq->writeIdx);
return true;
}
RawPckt mq_top(MsgQueue *mq) {
return mq->pckts[mq->readIdx];
}
void mq_pop(MsgQueue *mq) {
if (mq_avail(mq) > 0) { // if there's anything to pop
mq->readIdx = MQ_NEXT(mq->size, mq->readIdx);
}
}