#ifdef _WIN32 int main() { return 0; } #else # include "../kit/threads.h" # include # include # include # include # include # include # 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