-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathframe_queue.h
74 lines (63 loc) · 1.97 KB
/
frame_queue.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// Copyright 2020 ETH Zurich
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef HERCULES_FRAME_QUEUE_H
#define HERCULES_FRAME_QUEUE_H
#include "utils.h"
struct frame_queue {
// reduce the memory footprint by using 16 bit ints instead of full 64 bits
u16 *addrs;
u64 prod;
u64 cons;
u16 size;
u16 index_mask;
};
inline int frame_queue__init(struct frame_queue *fq, u16 size)
{
if((size == 0) || ((size & (size - 1)) != 0)) {
return EINVAL; // size is zero or not a power of two
}
fq->addrs = calloc(size, sizeof(__u16));
if(fq->addrs == NULL) {
return ENOMEM;
}
fq->size = size;
fq->cons = fq->size;
fq->index_mask = fq->size - 1;
return EXIT_SUCCESS;
}
inline u16 frame_queue__prod_reserve(struct frame_queue *fq, u16 num)
{
return umin16(atomic_load(&fq->cons) - fq->prod, num);
}
inline void frame_queue__prod_fill(struct frame_queue *fq, u16 offset, u64 addr)
{
fq->addrs[(fq->prod + offset) & fq->index_mask] = addr >> XSK_UMEM__DEFAULT_FRAME_SHIFT;
}
inline void frame_queue__push(struct frame_queue *fq, u16 num)
{
atomic_fetch_add(&fq->prod, num);
}
inline u16 frame_queue__cons_reserve(struct frame_queue *fq, u16 num)
{
return umin16(atomic_load(&fq->prod) - fq->cons + fq->size, num);
}
inline u64 frame_queue__cons_fetch(struct frame_queue *fq, u16 offset)
{
return fq->addrs[(fq->cons + offset) & fq->index_mask] << XSK_UMEM__DEFAULT_FRAME_SHIFT;
}
inline void frame_queue__pop(struct frame_queue *fq, u16 num)
{
atomic_fetch_add(&fq->cons, num);
}
#endif