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

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

Fix build error on older kernels that don't have memfd_create

We now fall back to shm_open() if memfd_create isn't available.

  • Property mode set to 100644
File size: 2.4 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/stat.h>
10#include <fcntl.h>
11#include <sys/socket.h>
12
13#include "simple_circular_buffer.h"
14
15DLLEXPORT void libtrace_scb_init(libtrace_scb_t *buf, uint32_t size,
16                uint16_t id) {
17
18        char anonname[32];
19
20        if (size % getpagesize() != 0) {
21                size = ((size / getpagesize()) + 1) * getpagesize();
22        }
23
24        snprintf(anonname, 32, "lt_scb_%u", id);
25#ifdef HAVE_MEMFD_CREATE
26        buf->fd = syscall(__NR_memfd_create, anonname, 0);
27#else
28        buf->fd = shm_open(anonname, O_RDWR | O_CREAT, 0600);
29#endif
30        ftruncate(buf->fd, size);
31
32        buf->address = mmap(NULL, 2 * size, PROT_NONE,
33                        MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
34        mmap(buf->address, size, PROT_READ | PROT_WRITE,
35                        MAP_SHARED | MAP_FIXED, buf->fd, 0);
36        mmap(buf->address + size, size, PROT_READ | PROT_WRITE,
37                        MAP_SHARED | MAP_FIXED, buf->fd, 0);
38        buf->read_offset = 0;
39        buf->write_offset = 0;
40        buf->count_bytes = size;
41}
42
43DLLEXPORT void libtrace_scb_destroy(libtrace_scb_t *buf) {
44        /* TODO shm_unlink the file name if we used shm_open? */
45
46        munmap(buf->address, buf->count_bytes * 2);
47        close(buf->fd);
48}
49
50DLLEXPORT int libtrace_scb_recv_sock(libtrace_scb_t *buf, int sock,
51                int recvflags) {
52        int space = buf->count_bytes - (buf->write_offset - buf->read_offset);
53        int ret;
54
55        if (space == 0) {
56                return buf->count_bytes;
57        }
58
59        ret = recv(sock, buf->address + buf->write_offset, space, recvflags);
60        if (ret < 0) {
61                return ret;
62        }
63        buf->write_offset += ret;
64        return (buf->write_offset - buf->read_offset);
65}
66
67DLLEXPORT uint8_t *libtrace_scb_get_read(libtrace_scb_t *buf,
68                uint32_t *available) {
69
70        *available = buf->write_offset - buf->read_offset;
71        return buf->address + buf->read_offset;
72}
73
74DLLEXPORT void libtrace_scb_advance_read(libtrace_scb_t *buf,
75                uint32_t forward) {
76
77        buf->read_offset += forward;
78        if (buf->read_offset >= buf->count_bytes) {
79                buf->read_offset -= buf->count_bytes;
80                buf->write_offset -= buf->count_bytes;
81        }
82}
Note: See TracBrowser for help on using the repository browser.