summaryrefslogtreecommitdiff
path: root/schulung_tools/ipc_pipe
diff options
context:
space:
mode:
Diffstat (limited to 'schulung_tools/ipc_pipe')
-rw-r--r--schulung_tools/ipc_pipe/Makefile12
-rw-r--r--schulung_tools/ipc_pipe/README10
-rw-r--r--schulung_tools/ipc_pipe/main.c115
3 files changed, 137 insertions, 0 deletions
diff --git a/schulung_tools/ipc_pipe/Makefile b/schulung_tools/ipc_pipe/Makefile
new file mode 100644
index 0000000..a5c8404
--- /dev/null
+++ b/schulung_tools/ipc_pipe/Makefile
@@ -0,0 +1,12 @@
+CFLAGS=-O0 -g -Wall -pedantic -lpthread -std=gnu99
+LDFLAGS=-lpthread
+
+all: main
+
+main.o: main.c
+main: main.o
+
+clean:
+ rm -rf main *.o
+
+.PHONY: clean
diff --git a/schulung_tools/ipc_pipe/README b/schulung_tools/ipc_pipe/README
new file mode 100644
index 0000000..c0fccac
--- /dev/null
+++ b/schulung_tools/ipc_pipe/README
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+# run test program
+sudo trace-cmd record \
+ -e sched:sched_switch \
+ -e sched:sched_wakeup \
+ taskset 1 chrt -f 80 ./main -s 1000000
+
+# view results
+kernelshark
diff --git a/schulung_tools/ipc_pipe/main.c b/schulung_tools/ipc_pipe/main.c
new file mode 100644
index 0000000..bda2da7
--- /dev/null
+++ b/schulung_tools/ipc_pipe/main.c
@@ -0,0 +1,115 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <errno.h>
+
+/* pipe file descriptors */
+static int fd[2];
+
+/* send/write size */
+static size_t size;
+
+/* options */
+static struct option long_opts[] = {
+ { "size", required_argument, NULL, 's' },
+ { NULL, 0, NULL, 0 },
+};
+
+static void *reader(void *arg)
+{
+ unsigned char buf[size];
+ ssize_t read_ = 0;
+
+ while (read_ < size) {
+ ssize_t ret;
+
+ ret = read(fd[0], buf + read_, size - read_);
+ if (ret < 0) {
+ perror("read() failed");
+ exit(EXIT_FAILURE);
+ }
+ read_ += ret;
+ }
+
+ printf("Reader: got data\n");
+ return NULL;
+}
+
+static void *writer(void *arg)
+{
+ unsigned char buf[size];
+ ssize_t written = 0;
+
+ sleep(1);
+
+ while (written < size) {
+ ssize_t ret;
+
+ ret = write(fd[1], buf + written, size - written);
+ if (ret < 0) {
+ perror("write() failed");
+ exit(EXIT_FAILURE);
+ }
+
+ written += ret;
+ }
+
+ printf("Writer: sent data\n");
+
+ sleep(1);
+
+ return NULL;
+}
+
+static inline void print_usage_and_die(void)
+{
+ fprintf(stderr, "usage: pipedemo [-s <size>]\n");
+ exit(EXIT_FAILURE);
+}
+
+int main(int argc, char **argv)
+{
+ pthread_t tid1, tid2;
+ char *end;
+ int c;
+
+ size = 4 << 10;
+ while ((c = getopt_long(argc, argv, "s:", long_opts, NULL)) != -1) {
+ switch (c) {
+ case 's':
+ size = strtoull(optarg, &end, 10);
+ if (end == optarg || *end != '\0' || errno == ERANGE) {
+ fprintf(stderr, "given size is not valid\n");
+ return EXIT_FAILURE;
+ }
+ break;
+ default:
+ print_usage_and_die();
+ }
+ }
+
+ if (pipe(fd) < 0) {
+ perror("pipe() failed");
+ return EXIT_FAILURE;
+ }
+
+ if (pthread_create(&tid1, NULL, reader, NULL) ||
+ pthread_create(&tid2, NULL, writer, NULL)) {
+ fprintf(stderr, "pthread_create() failed\n");
+ return EXIT_FAILURE;
+ }
+
+ if (pthread_setname_np(tid1, "pipedemo-reader") ||
+ pthread_setname_np(tid2, "pipedemo-writer")) {
+ fprintf(stderr, "pthread_create() failed\n");
+ return EXIT_FAILURE;
+ }
+
+ pthread_join(tid1, NULL);
+ pthread_join(tid2, NULL);
+
+ return EXIT_SUCCESS;
+}