_info 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #include "config.h"
  2. #include <stdio.h>
  3. #include <string.h>
  4. /**
  5. * rszshm - resizable pointer-safe shared memory
  6. *
  7. * If two separate processes have shared mappings of the same file at the
  8. * same address, then pointers to addresses within the region can be shared
  9. * between the processes and safely dereferenced.
  10. *
  11. * Mapping to the same address in unrelated processes is nontrivial. One can
  12. * request a specific address, but mmap will return another in case of an
  13. * overlap. One can require a specific address, but mmap will unmap anything
  14. * overlapped. On Linux boxes it can be seen that the used addresses clump
  15. * at either end of the address range. rszshm tries to mmap in the middle
  16. * of the address range, and checks if the requested address matches the
  17. * returned address. If not, additional addresses are tried. Once mapped,
  18. * the address is recorded to a header in the file. Another process reads the
  19. * header and requests the saved address from mmap. If the returned address
  20. * matches, work proceeds. While the defaults provide a propitious search,
  21. * all the search parameters may be specified.
  22. *
  23. * To accommodate resizing, rszshm first maps a large, private, noreserve map.
  24. * This serves to claim a span of addresses. The shared file mapping then
  25. * overlays the beginning of the span. Later calls to extend the mapping
  26. * overlay more of the span. Attempts to extend beyond the end of the span
  27. * return an error.
  28. *
  29. * Example:
  30. * // fork x times, grow and fill shared memory cooperatively
  31. * #include <assert.h>
  32. * #include <err.h>
  33. * #include <signal.h>
  34. * #include <stdio.h>
  35. * #include <unistd.h>
  36. * #include <ccan/rszshm/rszshm.h>
  37. *
  38. * #define ok(x) ({ int n = (x); if (n == -1) err(1, "%s", #x); n; })
  39. *
  40. * int main(int argc, char *argv[]) {
  41. * int pidcnt, stopval, n, i;
  42. * struct rszshm *r;
  43. * char *m;
  44. *
  45. * assert(argc == 3);
  46. * pidcnt = atoi(argv[1]);
  47. * stopval = atoi(argv[2]);
  48. * assert(pidcnt > 0 && stopval > 0);
  49. *
  50. * if (!rszshm_mkm(r, 4096, NULL))
  51. * err(1, "rszshm_mkm");
  52. *
  53. * printf("%s\n", r->fname);
  54. *
  55. * for (n = 0; n < pidcnt - 1; n++)
  56. * if (ok(fork()) == 0)
  57. * break;
  58. *
  59. * m = (char *) r->dat + sizeof(int);
  60. * #define next() (__sync_fetch_and_add((int *) r->dat, 1))
  61. *
  62. * for(i = next(); i < stopval; i = next()) {
  63. * if (i >= r->cap - sizeof(int))
  64. * ok(rszshm_grow(r));
  65. * assert(m[i] == '\0');
  66. * m[i] = 'A' + n;
  67. * kill(0, 0); // busy work
  68. * }
  69. *
  70. * rszshm_free(r);
  71. * return 0;
  72. * }
  73. * // $ ./foo 8 $((4*1024*1024-28))
  74. * // /dev/shm/rszshm_LAsEvt/0
  75. * // $ tail -c +29 /dev/shm/rszshm_LAsEvt/0 | sed 's/./&\n/g' | sort | uniq -c | tr '\n' '\t'; echo
  76. * // 515532 A 527251 B 512930 C 513062 D 544326 E 545876 F 512936 G 522363 H
  77. *
  78. * Ccanlint: tests_pass_valgrind FAIL
  79. * License: APACHE-2
  80. * Author: Dan Good <dan@dancancode.com>
  81. *
  82. * Ccanlint:
  83. * // tests use optional macros containing statement expressions
  84. * tests_compile_without_features FAIL
  85. */
  86. int main(int argc, char *argv[])
  87. {
  88. /* Expect exactly one argument */
  89. if (argc != 2)
  90. return 1;
  91. if (strcmp(argv[1], "depends") == 0)
  92. return 0;
  93. return 1;
  94. }