#include <sys/eventfd.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#define handle_error(msg) \
do { \
perror(msg); \
exit(EXIT_FAILURE); \
} while (0)
int
main(int argc, char *argv[])
{
eventfd_t u;
int efd, j;
int error;
if (argc < 2) {
fprintf(stderr, "Usage: %s <num>...\n", argv[0]); exit(EXIT_FAILURE);
}
efd = eventfd(0, EFD_CLOEXEC);
if (efd == -1)
handle_error("eventfd");
switch (fork()) {
case 0:
for (j = 1; j < argc; j++) { printf("Child writing %s to efd\n", argv[j]); u = strtoull(argv[j], NULL, 0); error = eventfd_write(efd, u); if (error != 0) handle_error("write"); } printf("Child completed write loop\n"); exit(EXIT_SUCCESS);
default:
sleep(2); printf("Parent about to read\n"); error = eventfd_read(efd, &u); if (error != 0) handle_error("read"); printf("Parent read %llu (0x%llx) from efd\n", (unsigned long long) u, (unsigned long long) u); exit(EXIT_SUCCESS);
case -1:
handle_error("fork");
}
}
/* EFD_SEMAPHORE */
#include <sys/eventfd.h>
#include <sys/wait.h>
#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
static void xsem_wait(int fd)
{
eventfd_t cntr;
if (eventfd_read(fd, &cntr) != 0) {
perror("reading eventfd"); exit(1);
}
fprintf(stdout, "[%u] wait completed on %d: count=%" PRIu64 "\n",
getpid(), fd, cntr);
}
static void xsem_post(int fd, int count)
{
eventfd_t cntr = count;
if (eventfd_write(fd, cntr) != 0) {
perror("writing eventfd"); exit(1);
}
}
static void sem_player(int fd1, int fd2)
{
fprintf(stdout, "[%u] posting 1 on %d\n", getpid(), fd1);
xsem_post(fd1, 1);
fprintf(stdout, "[%u] waiting on %d\n", getpid(), fd2);
xsem_wait(fd2);
fprintf(stdout, "[%u] posting 1 on %d\n", getpid(), fd1);
xsem_post(fd1, 1);
fprintf(stdout, "[%u] waiting on %d\n", getpid(), fd2);
xsem_wait(fd2);
fprintf(stdout, "[%u] posting 5 on %d\n", getpid(), fd1);
xsem_post(fd1, 5);
fprintf(stdout, "[%u] waiting 5 times on %d\n", getpid(), fd2);
xsem_wait(fd2);
xsem_wait(fd2);
xsem_wait(fd2);
xsem_wait(fd2);
xsem_wait(fd2);
}
static void usage(char const *prg)
{
fprintf(stderr, "use: %s [-h]\n", prg);
}
int main(int argc, char **argv)
{
int c, fd1, fd2, status;
pid_t cpid_poster, cpid_waiter;
while ((c = getopt(argc, argv, "h")) != -1) {
switch (c) { default: usage(argv[0]); return 1; }
}
if ((fd1 = eventfd(0, EFD_SEMAPHORE)) == -1 ||
(fd2 = eventfd(0, EFD_SEMAPHORE)) == -1) { perror("eventfd"); return 1;
}
if ((cpid_poster = fork()) == 0) {
sem_player(fd1, fd2); exit(0);
}
if ((cpid_waiter = fork()) == 0) {
sem_player(fd2, fd1); exit(0);
}
waitpid(cpid_poster, &status, 0);
waitpid(cpid_waiter, &status, 0);
exit(0);
}