source: lib/data-struct/simple_circular_buffer.c @ bd51874

cachetimestampsdevelopetsiliverc-4.0.4ringdecrementfixringperformance
Last change on this file since bd51874 was bd51874, checked in by Shane Alcock <salcock@…>, 3 years ago

Add simple circular buffer data struct

Designed for receiving streamed octets, e.g. over TCP.

  • Property mode set to 100644
File size: 2.0 KB
Line 
1#define _GNU_SOURCE
2
3#include <sys/mman.h>
4#include <stdlib.h>
5#include <unistd.h>
6#include <stdint.h>
7#include <stdio.h>
8#include <sys/syscall.h>
9#include <sys/socket.h>
10
11#include "simple_circular_buffer.h"
12
13void libtrace_scb_init(libtrace_scb_t *buf, uint32_t size, uint16_t id) {
14
15        char anonname[32];
16
17        if (size % getpagesize() != 0) {
18                size = ((size / getpagesize()) + 1) * getpagesize();
19        }
20
21        snprintf(anonname, 32, "lt_scb_%u", id);
22        buf->fd = syscall(__NR_memfd_create, anonname, 0);
23        ftruncate(buf->fd, size);
24
25        buf->address = mmap(NULL, 2 * size, PROT_NONE,
26                        MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
27        mmap(buf->address, size, PROT_READ | PROT_WRITE,
28                        MAP_SHARED | MAP_FIXED, buf->fd, 0);
29        mmap(buf->address + size, size, PROT_READ | PROT_WRITE,
30                        MAP_SHARED | MAP_FIXED, buf->fd, 0);
31        buf->read_offset = 0;
32        buf->write_offset = 0;
33        buf->count_bytes = size;
34}
35
36void libtrace_scb_destroy(libtrace_scb_t *buf) {
37        munmap(buf->address, buf->count_bytes * 2);
38}
39
40int libtrace_scb_recv_sock(libtrace_scb_t *buf, int sock, int recvflags) {
41        int space = buf->count_bytes - (buf->write_offset - buf->read_offset);
42        int ret;
43
44        if (space == 0) {
45                return buf->count_bytes;
46        }
47
48        ret = recv(sock, buf->address + buf->write_offset, space, recvflags);
49        if (ret < 0) {
50                return ret;
51        }
52        buf->write_offset += ret;
53        return (buf->write_offset - buf->read_offset);
54}
55
56uint8_t *libtrace_scb_get_read(libtrace_scb_t *buf, uint32_t *available) {
57
58        *available = buf->write_offset - buf->read_offset;
59        return buf->address + buf->read_offset;
60}
61
62void libtrace_scb_advance_read(libtrace_scb_t *buf, uint32_t forward) {
63
64        buf->read_offset += forward;
65        if (buf->read_offset >= buf->count_bytes) {
66                buf->read_offset -= buf->count_bytes;
67                buf->write_offset -= buf->count_bytes;
68        }
69}
Note: See TracBrowser for help on using the repository browser.