2 Copyright (c) 2020 Peter Hsu. All Rights Reserved. See LICENCE file for details.
20 #define DEFAULT_BUFSIZE 12
23 /* Producer side fifo initialization.
24 bufid - number = file descriptor (already opened)
25 $name = shared memory segment /dev/shm/name
26 otherwise = trace file path name
27 bufsize - log-base-2 number of bytes
29 struct fifo_t
* fifo_create( const char* bufid
, int bufsize
)
31 // assert(sizeof(struct fifo_t) == 2*64);
33 bufsize
= DEFAULT_BUFSIZE
;
35 int fd
= shm_open(bufid
, O_CREAT
|O_TRUNC
|O_RDWR
, S_IRWXU
);
36 dieif(fd
<0, "shm_open() failed in fifo_create");
37 size_t fsize
= (1<<bufsize
) + sizeof(struct fifo_t
);
38 dieif(ftruncate(fd
, fsize
)<0, "ftruncate() failed in fifo_create");
39 struct fifo_t
* fifo
= (struct fifo_t
*)mmap(NULL
, fsize
, PROT_READ
|PROT_WRITE
, MAP_SHARED
, fd
, 0);
40 dieif(fifo
==0, "mmap() failed in fifo_create");
41 assert(((uint64_t)fifo
& 0x3fL
) == 0L);
42 memset((char*)fifo
, 0, fsize
);
45 fifo
->get_mask
= fifo
->put_mask
= (1<<(bufsize
-3))-1;
51 /* Consumer side fifo initialization.
52 bufid - number = file descriptor (already opened)
53 $name = shared memory segment /dev/shm/name
54 otherwise = trace file path name
56 struct fifo_t
* fifo_open( const char* bufid
)
58 int fd
= shm_open(bufid
, O_RDWR
, 0);
59 dieif(fd
<0, "shm_open() failed in fifo_open");
60 struct fifo_t
* fifo
= (struct fifo_t
*)mmap(NULL
, sizeof(struct fifo_t
), PROT_READ
|PROT_WRITE
, MAP_SHARED
, fd
, 0);
61 dieif(fifo
==0, "first mmap() failed in fifo_open");
62 size_t fsize
= (1<<fifo
->size
) + sizeof(struct fifo_t
);
63 dieif(munmap(fifo
, sizeof(struct fifo_t
))<0, "munmap() failed in fifo_open");
64 fifo
= (struct fifo_t
*)mmap(NULL
, fsize
, PROT_READ
|PROT_WRITE
, MAP_SHARED
, fd
, 0);
65 dieif(fifo
==0, "second mmap() failed in fifo_open");
66 assert(((uint64_t)fifo
& 0x3fL
) == 0L);
71 /* Consumer side fifo termination. */
72 void fifo_close( struct fifo_t
* fifo
)
75 futex_wake(&fifo
->finished
);
76 size_t fsize
= (1<<fifo
->size
) + sizeof(struct fifo_t
);
77 dieif(munmap(fifo
, fsize
)<0, "munmap() failed in fifo_close");
81 /* Producer side fifo termination. */
82 void fifo_finish( struct fifo_t
* fifo
)
85 /* wait for consumer to finish */
86 futex_hibernate(&fifo
->finished
, 0);
87 size_t fsize
= (1<<fifo
->size
) + sizeof(struct fifo_t
);
88 dieif(munmap(fifo
, fsize
)<0, "munmap() failed in fifo_finish");
92 void fifo_debug( struct fifo_t
* fifo
, const char* msg
)
94 fprintf(stderr
, "%s: HEAD=%d, head=%d, TAIL=%d, tail=%d\n",
95 msg
, fifo
->HEAD
, fifo
->head
, fifo
->TAIL
, fifo
->tail
);