summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build_and_test.sh20
-rw-r--r--source/tests/test_interprocess.c124
2 files changed, 143 insertions, 1 deletions
diff --git a/build_and_test.sh b/build_and_test.sh
index 157f88a..bd347f2 100644
--- a/build_and_test.sh
+++ b/build_and_test.sh
@@ -172,6 +172,15 @@ if [ $? -ne 0 ]; then
exit 1
fi
+$COMPILEPP ${FLAGS} \
+ ${FLAG_EXE}"build/test_interprocess${EXE_POSTFIX}" \
+ "build/kit${OBJ_POSTFIX}" \
+ "source/tests/test_interprocess.c" \
+ ${LINK_FLAGS}
+if [ $? -ne 0 ]; then
+ exit 1
+fi
+
echo "Run tests"
echo ""
@@ -206,7 +215,7 @@ else
STATUS=1
fi
-./build/test_signals
+./build/test_signals --quiet
if [ $? -eq 0 ]; then
echo "signals - OK"
else
@@ -214,4 +223,13 @@ else
STATUS=1
fi
+./build/test_interprocess writer &
+./build/test_interprocess reader
+if [ $? -eq 0 ]; then
+ echo "interprocess - OK"
+else
+ echo "interprocess - FAILED (code $?)"
+ STATUS=1
+fi
+
exit $STATUS
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