-
Notifications
You must be signed in to change notification settings - Fork 0
/
ring.h
81 lines (60 loc) · 2.02 KB
/
ring.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
75
76
77
78
79
80
81
/*
* Copyright (c) 2013 Pavel Shramov <shramov@mexmat.net>
*
* ring is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
*/
#ifndef __LL_RING_H__
#define __LL_RING_H__
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
int32_t magic;
int32_t version;
// mah: see [1],[4]: shouldnt head+tail be volatile?
size_t size;
/* volatile */ size_t head __attribute__((aligned(16)));
/* volatile */ uint64_t generation;
/* volatile */ size_t tail __attribute__((aligned(16)));;
} ring_header_t;
#define _S(x, s) (((int32_t) (x)) << 8 * (s))
static const int32_t ring_magic = _S('r', 3) | _S('i', 2) | _S('n', 1) | 'g';
#undef _S
typedef int32_t ring_size_t; // Negative numbers are needed for skips
typedef struct ringbuffer_t
{
ring_header_t * header;
char * buf;
} ringbuffer_t;
typedef struct
{
const ringbuffer_t *ring;
uint64_t generation;
size_t offset;
} ringiter_t;
int ring_init(ringbuffer_t *ring, size_t size, void * memory);
int ring_init_file(ringbuffer_t *ring, size_t size, int fd);
void ring_free(ringbuffer_t *ring);
void ring_clear(ringbuffer_t *ring);
int ring_write_begin(ringbuffer_t *ring, void ** data, size_t size);
int ring_write_end(ringbuffer_t *ring, void * data, size_t size);
int ring_write(ringbuffer_t *ring, const void * data, size_t size);
int ring_read(const ringbuffer_t *ring, const void **data, size_t *size);
int ring_shift(ringbuffer_t *ring);
size_t ring_available(const ringbuffer_t *ring);
// Wrappers, not needed
const void * ring_next(ringbuffer_t *ring);
ring_size_t ring_next_size(ringbuffer_t *ring);
int ring_iter_init(const ringbuffer_t *ring, ringiter_t *iter);
int ring_iter_invalid(const ringiter_t *iter);
int ring_iter_shift(ringiter_t *iter);
int ring_iter_read(const ringiter_t *iter, const void **data, size_t *size);
void ring_dump(ringbuffer_t *ring, const char *name);
#ifdef __cplusplus
}; //extern "C"
#endif
#endif//__LL_RING_H__