divers/c/poll-timing.c
2025-02-03 08:57:30 +01:00

119 lines
2.6 KiB
C

#include <stdio.h>
//#include <sys/time.h>
#include <time.h>
#include <stdlib.h>
// For poll-related stuff.
#include <fcntl.h>
#include <poll.h>
#include <sys/types.h>
#include <unistd.h>
#define err(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)
#define BILLION 1000000000L
#define MILLION 1000000L
#define THOUSAND 1000L
void get_time_ts(struct timespec *t0) {
if (clock_gettime(CLOCK_REALTIME, t0) == -1) {
perror("clock_gettime");
exit(1);
}
}
long long duration_ns(struct timespec t0, struct timespec t1) {
return ((t1.tv_sec - t0.tv_sec)*BILLION) + (t1.tv_nsec - t0.tv_nsec);
}
void print_time_ns(long long time) {
printf("%llds %lldms %lldµ %lldns\n"
, time/BILLION
, (time/MILLION)%THOUSAND
, (time/THOUSAND)%THOUSAND
, time%THOUSAND
);
}
int main(int argc, char *argv[])
{
// Time-related structures.
struct timespec t0, t1;
int ready;
char buf[10];
nfds_t num_open_fds, nfds;
ssize_t s;
struct pollfd *pfds;
if (argc < 2) {
fprintf(stderr, "Usage: %s file...\n", argv[0]);
exit(EXIT_FAILURE);
}
num_open_fds = nfds = argc - 1;
pfds = calloc(nfds, sizeof(struct pollfd));
if (pfds == NULL)
err("malloc");
/* Open each file on command line, and add it to 'pfds' array. */
for (nfds_t j = 0; j < nfds; j++) {
pfds[j].fd = open(argv[j + 1], O_RDONLY);
if (pfds[j].fd == -1)
err("open");
printf("Opened \"%s\" on fd %d\n", argv[j + 1], pfds[j].fd);
pfds[j].events = POLLIN;
}
/* Keep calling poll() as long as at least one file descriptor is
open. */
while (num_open_fds > 0) {
printf("About to poll()\n");
get_time_ts(&t0);
ready = poll(pfds, nfds, -1);
get_time_ts(&t1);
if (ready == -1)
err("poll");
printf("polling duration: ");
print_time_ns(duration_ns(t0, t1));
printf("Ready: %d\n", ready);
/* Deal with array returned by poll(). */
for (nfds_t j = 0; j < nfds; j++) {
if (pfds[j].revents != 0) {
printf(" fd=%d; events: %s%s%s\n", pfds[j].fd,
(pfds[j].
revents & POLLIN) ? "POLLIN " : "",
(pfds[j].
revents & POLLHUP) ? "POLLHUP " : "",
(pfds[j].
revents & POLLERR) ? "POLLERR " : "");
if (pfds[j].revents & POLLIN) {
s = read(pfds[j].fd, buf, sizeof(buf));
if (s == -1)
err("read");
printf(" read %zd bytes: %.*s\n",
s, (int)s, buf);
} else { /* POLLERR | POLLHUP */
printf(" closing fd %d\n",
pfds[j].fd);
if (close(pfds[j].fd) == -1)
err("close");
num_open_fds--;
}
}
}
}
printf("All file descriptors closed; bye\n");
exit(EXIT_SUCCESS);
}