#include "../kit/shared_memory.h" #include "../kit/shared_mutex.h" #include "../kit/threads.h" #include #define NAME "kit_test_interprocess" enum { DATA_SIZE = 64, TIMEOUT = 3 }; typedef struct { shared_mutex_t m; i8 state; i8 bytes[DATA_SIZE]; } shared_data_t; enum { STATE_INIT, STATE_READY, STATE_DONE }; int run_writer() { printf("Run writer.\n"); fflush(stdout); shared_memory_t mem = shared_memory_open( SZ(NAME), sizeof(shared_data_t), SHARED_MEMORY_CREATE); if (mem.status != KIT_OK) { printf("%s: kit_shared_memory_open failed.\n", __FUNCTION__); fflush(stdout); return 1; } shared_data_t *p = (shared_data_t *) mem.bytes; shared_mutex_init(&p->m); unique_lock(&p->m); p->state = STATE_INIT; unique_unlock(&p->m); unique_lock(&p->m); for (int i = 0; i < DATA_SIZE; i++) p->bytes[i] = i; p->state = STATE_READY; unique_unlock(&p->m); struct timespec t0; timespec_get(&t0, TIME_UTC); shared_lock(&p->m); while (p->state != STATE_DONE) { shared_unlock(&p->m); struct timespec t1; timespec_get(&t1, TIME_UTC); if (t1.tv_sec - t0.tv_sec > TIMEOUT) { printf("%s: timeout.\n", __FUNCTION__); shared_memory_close(&mem); return 1; } thrd_yield(); shared_lock(&p->m); } shared_unlock(&p->m); if (shared_memory_close(&mem) != KIT_OK) { printf("%s: kit_shared_memory_close failed.\n", __FUNCTION__); fflush(stdout); return 1; } return 0; } int run_reader() { struct timespec delay = { .tv_sec = 0, .tv_nsec = 10000000 }; thrd_sleep(&delay, NULL); printf("Run reader.\n"); fflush(stdout); struct timespec t0; timespec_get(&t0, TIME_UTC); shared_memory_t mem; for (;;) { mem = shared_memory_open(SZ(NAME), sizeof(shared_data_t), SHARED_MEMORY_OPEN); if (mem.status == KIT_OK) break; struct timespec t1; timespec_get(&t1, TIME_UTC); if (t1.tv_sec - t0.tv_sec > TIMEOUT) { printf("%s: timeout.\n", __FUNCTION__); return 1; } thrd_yield(); } if (mem.status != KIT_OK) { printf("%s: kit_shared_memory_open failed.\n", __FUNCTION__); fflush(stdout); return 1; } shared_data_t *p = (shared_data_t *) mem.bytes; shared_lock(&p->m); while (p->state != STATE_READY) { shared_unlock(&p->m); thrd_yield(); shared_lock(&p->m); } i32 status = 0; for (i32 i = 0; i < DATA_SIZE; i++) if (p->bytes[i] != i) { printf("%s: wrong byte %d\n", __FUNCTION__, i); fflush(stdout); status = 1; } shared_unlock(&p->m); unique_lock(&p->m); p->state = STATE_DONE; unique_unlock(&p->m); if (shared_memory_close(&mem) != KIT_OK) { printf("%s: kit_shared_memory_close failed.\n", __FUNCTION__); fflush(stdout); status = 1; } return status; } int main(int argc, char **argv) { if (argc != 2) { printf("Wrong number of command line arguments %d\n", argc); return 1; } if (strcmp(argv[1], "writer") == 0) { struct timespec t0; timespec_get(&t0, TIME_UTC); i32 status = run_writer(); struct timespec t1; timespec_get(&t1, TIME_UTC); i64 sec = t1.tv_sec - t0.tv_sec; i64 nsec = t1.tv_nsec - t0.tv_nsec; printf("Done in %.2lf msec\n", (sec * 1000000000 + nsec) * 0.000001); fflush(stdout); return status; } if (strcmp(argv[1], "reader") == 0) return run_reader(); if (strcmp(argv[1], "clean") == 0) { shared_memory_clean(SZ(NAME)); return 0; } printf("Invalid command line argument \"%s\"\n", argv[1]); return 1; }