summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2023-09-14 22:55:59 +0200
committerMitya Selivanov <automainint@guattari.tech>2023-09-14 22:55:59 +0200
commitb2666b7ec2c923c2d33627f75d032eb4dbbf2937 (patch)
tree0e2e725ecabf083a1732640bce9ea2a3cecdd154 /source
parent909bd8e0b36183e6d9d6fc059d98c386dff3740b (diff)
downloadkit-b2666b7ec2c923c2d33627f75d032eb4dbbf2937.zip
interprocess test
Diffstat (limited to 'source')
-rw-r--r--source/tests/test_interprocess.c124
1 files changed, 124 insertions, 0 deletions
diff --git a/source/tests/test_interprocess.c b/source/tests/test_interprocess.c
new file mode 100644
index 0000000..df2a375
--- /dev/null
+++ b/source/tests/test_interprocess.c
@@ -0,0 +1,124 @@
+#ifdef _WIN32
+int main() {
+ return 0;
+}
+#else
+# include "../kit/threads.h"
+
+# include <stdio.h>
+# include <string.h>
+# include <sys/mman.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+# include <unistd.h>
+
+# define NAME "/kit_test_interprocess"
+
+enum { STATE_INIT, STATE_READY, STATE_DONE };
+
+enum { SIZE = 64 };
+
+int run_writer() {
+ int f = shm_open(NAME, O_RDWR | O_CREAT, 0660);
+
+ if (f == -1) {
+ printf("%s: shm_open failed.\n", __FUNCTION__);
+ return 1;
+ }
+
+ if (ftruncate(f, SIZE) == -1) {
+ printf("%s: ftruncate failed.\n", __FUNCTION__);
+ fflush(stdout);
+ return 1;
+ }
+
+ void *p = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, f,
+ 0);
+
+ if (p == MAP_FAILED) {
+ printf("%s: mmap failed.\n", __FUNCTION__);
+ fflush(stdout);
+ return 1;
+ }
+
+ unsigned char *bytes = (unsigned char *) p;
+
+ bytes[0] = STATE_INIT;
+ for (int i = 1; i < SIZE; i++) bytes[i] = i;
+ bytes[0] = STATE_READY;
+
+ while (bytes[0] != STATE_DONE) thrd_yield();
+
+ shm_unlink(NAME);
+
+ return 0;
+}
+
+int run_reader() {
+ int f = -1;
+
+ while (f == -1) {
+ f = shm_open(NAME, O_RDWR, 0);
+ thrd_yield();
+ }
+
+ void *p = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, f,
+ 0);
+
+ if (p == MAP_FAILED) {
+ printf("%s: mmap failed.\n", __FUNCTION__);
+ fflush(stdout);
+ return 1;
+ }
+
+ unsigned char *bytes = (unsigned char *) p;
+
+ while (bytes[0] != STATE_READY) thrd_yield();
+
+ int status = 0;
+
+ for (int i = 1; i < SIZE; i++)
+ if (bytes[i] != i) {
+ printf("%s: wrong byte %d\n", __FUNCTION__, i);
+ fflush(stdout);
+ status = 1;
+ }
+
+ bytes[0] = STATE_DONE;
+
+ return status;
+}
+
+int main(int argc, char **argv) {
+ if (argc != 2) {
+ printf("Wrong number of command line arguments %d\n", argc);
+ return 1;
+ }
+
+ int status = 0;
+
+ struct timespec t0;
+ timespec_get(&t0, TIME_UTC);
+
+ if (strcmp(argv[1], "writer") == 0)
+ status = run_writer();
+ else if (strcmp(argv[1], "reader") == 0)
+ status = run_reader();
+ else {
+ printf("Invalid command line argument \"%s\"\n", argv[1]);
+ return 1;
+ }
+
+ struct timespec t1;
+ timespec_get(&t1, TIME_UTC);
+
+ long long sec = t1.tv_sec - t0.tv_sec;
+ long long nsec = t1.tv_nsec - t0.tv_nsec;
+
+ printf("%s: done in %.2lf msec\n", argv[1],
+ (sec * 1000000000 + nsec) * 0.000001);
+ fflush(stdout);
+
+ return status;
+}
+#endif