You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
3.6 KiB

  1. /* Test pthread rwlocks in multiprocess environment. */
  2. /* How expensive is
  3. * - Obtaining a read-only lock for the first obtainer.
  4. * - Obtaining it for the second one?
  5. * - The third one? */
  6. #include <assert.h>
  7. #include <fcntl.h>
  8. #include <errno.h>
  9. #include <pthread.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <sys/mman.h>
  13. #include <sys/stat.h>
  14. #include <sys/time.h>
  15. #include <sys/types.h>
  16. #include <sys/wait.h>
  17. #include <unistd.h>
  18. float tdiff (struct timeval *start, struct timeval *end) {
  19. return 1e6*(end->tv_sec-start->tv_sec) +(end->tv_usec - start->tv_usec);
  20. }
  21. #define FILE "process.data"
  22. int main (int argc __attribute__((__unused__)), char *argv[] __attribute__((__unused__))) {
  23. int r;
  24. int fd;
  25. void *p;
  26. fd=open(FILE, O_CREAT|O_RDWR|O_TRUNC, 0666); assert(fd>=0);
  27. int i;
  28. for (i=0; i<4096; i++) {
  29. r=write(fd, "\000", 1);
  30. assert(r==1);
  31. }
  32. p=mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
  33. if (p==MAP_FAILED) {
  34. printf("err=%d %s (EPERM=%d)\n", errno, strerror(errno), EPERM);
  35. }
  36. assert(p!=MAP_FAILED);
  37. r=close(fd); assert(r==0);
  38. pthread_rwlockattr_t attr;
  39. pthread_rwlock_t *lock=p;
  40. r=pthread_rwlockattr_init(&attr); assert(r==0);
  41. r=pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); assert(r==0);
  42. r=pthread_rwlock_init(lock, &attr); assert(r==0);
  43. r=pthread_rwlock_init(lock+1, &attr); assert(r==0);
  44. r=pthread_rwlock_wrlock(lock);
  45. pid_t pid;
  46. if ((pid=fork())==0) {
  47. // I'm the child
  48. r = munmap(p, 4096); assert(r==0);
  49. fd = open(FILE, O_RDWR, 0666); assert(fd>=0);
  50. p=mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
  51. assert(p!=MAP_FAILED);
  52. r=close(fd); assert(r==0);
  53. printf("A0\n");
  54. r=pthread_rwlock_wrlock(lock);
  55. printf("C\n");
  56. sleep(1);
  57. r=pthread_rwlock_unlock(lock);
  58. printf("D\n");
  59. r=pthread_rwlock_rdlock(lock);
  60. printf("E0\n");
  61. sleep(1);
  62. } else {
  63. printf("A1\n");
  64. sleep(1);
  65. printf("B\n");
  66. r=pthread_rwlock_unlock(lock); // release the lock grabbed before the fork
  67. assert(r==0);
  68. sleep(1);
  69. r=pthread_rwlock_rdlock(lock);
  70. assert(r==0);
  71. printf("E1\n");
  72. sleep(1);
  73. int status;
  74. pid_t waited=wait(&status);
  75. assert(waited==pid);
  76. }
  77. return 0;
  78. #if 0
  79. int j;
  80. int i;
  81. int r;
  82. struct timeval start, end;
  83. for (j=0; j<3; j++) {
  84. for (i=0; i<K; i++) {
  85. r=pthread_rwlock_init(&rwlocks[i], NULL);
  86. assert(r==0);
  87. }
  88. gettimeofday(&start, 0);
  89. for (i=0; i<K; i++) {
  90. r = pthread_rwlock_tryrdlock(&rwlocks[i]);
  91. assert(r==0);
  92. }
  93. gettimeofday(&end, 0);
  94. printf("pthread_rwlock_tryrdlock took %9.3fus for %d ops: %9.3fus/lock (%9.3fMops/s)\n", tdiff(&start,&end), K, tdiff(&start,&end)/K, K/tdiff(&start,&end));
  95. }
  96. for (j=0; j<3; j++) {
  97. for (i=0; i<K; i++) {
  98. r=pthread_rwlock_init(&rwlocks[i], NULL);
  99. assert(r==0);
  100. }
  101. gettimeofday(&start, 0);
  102. for (i=0; i<K; i++) {
  103. r = pthread_rwlock_rdlock(&rwlocks[i]);
  104. assert(r==0);
  105. }
  106. gettimeofday(&end, 0);
  107. printf("pthread_rwlock_rdlock took %9.3fus for %d ops: %9.3fus/lock (%9.3fMops/s)\n", tdiff(&start,&end), K, tdiff(&start,&end)/K, K/tdiff(&start,&end));
  108. }
  109. for (j=0; j<3; j++) {
  110. for (i=0; i<K; i++) {
  111. blocks[i].state=0;
  112. blocks[i].mutex=0;
  113. }
  114. gettimeofday(&start, 0);
  115. for (i=0; i<K; i++) {
  116. brwl_rlock(&blocks[i]);
  117. }
  118. gettimeofday(&end, 0);
  119. printf("brwl_rlock took %9.3fus for %d ops: %9.3fus/lock (%9.3fMops/s)\n", tdiff(&start,&end), K, tdiff(&start,&end)/K, K/tdiff(&start,&end));
  120. }
  121. return 0;
  122. #endif
  123. }