|
|
@@ -0,0 +1,63 @@ |
|
|
#include <stdio.h> |
|
|
#include <stdlib.h> |
|
|
#include <mach/mach_init.h> |
|
|
#include <mach/mach_error.h> |
|
|
#include <mach/semaphore.h> |
|
|
#include <mach/task.h> |
|
|
#include <sys/mman.h> |
|
|
#include <sys/stat.h> |
|
|
#include <sys/types.h> |
|
|
#include <fcntl.h> |
|
|
#include <unistd.h> |
|
|
|
|
|
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) |
|
|
|
|
|
/* global */ |
|
|
semaphore_t mutex; |
|
|
|
|
|
int main() { |
|
|
int fd, i, nloop, zero = 0; |
|
|
int *ptr = NULL; |
|
|
nloop = 50000; |
|
|
|
|
|
fd = open("./share", O_RDWR | O_CREAT, FILE_MODE); |
|
|
write(fd, &zero, sizeof(int)); |
|
|
ptr = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); |
|
|
close(fd); |
|
|
|
|
|
printf("ready mmap: %d\n", getpid()); |
|
|
|
|
|
mach_port_t self = mach_task_self(); |
|
|
kern_return_t ret = semaphore_create(self, &mutex, SYNC_POLICY_FIFO, 1); |
|
|
if (ret != KERN_SUCCESS) { |
|
|
fprintf(stderr, "semaphore create failed. Error <%d, %s>", ret, mach_error_string(ret)); |
|
|
return ret; |
|
|
} |
|
|
|
|
|
setbuf(stdout, NULL); |
|
|
|
|
|
/* child */ |
|
|
if (fork() == 0) { |
|
|
for (i = 0; i < nloop; i++) { |
|
|
ret = semaphore_wait(mutex); |
|
|
(*ptr)++; |
|
|
(*ptr)--; |
|
|
(*ptr)++; |
|
|
printf("child (%d): %d\n", getpid(), *ptr); |
|
|
ret = semaphore_signal(mutex); |
|
|
} |
|
|
exit(0); |
|
|
} else { |
|
|
/* parent */ |
|
|
for (i = 0; i < nloop; i++) { |
|
|
ret = semaphore_wait(mutex); |
|
|
(*ptr)++; |
|
|
(*ptr)--; |
|
|
(*ptr)++; |
|
|
printf("parent (%d): %d\n", getpid(), *ptr); |
|
|
ret = semaphore_signal(mutex); |
|
|
} |
|
|
} |
|
|
|
|
|
return 0; |
|
|
} |