diff --git a/c/poll-timing.c b/c/poll-timing.c new file mode 100644 index 0000000..7b96909 --- /dev/null +++ b/c/poll-timing.c @@ -0,0 +1,119 @@ +#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); +}