hugepage-shm.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. * hugepage-shm:
  3. *
  4. * Example of using huge page memory in a user application using Sys V shared
  5. * memory system calls. In this example the app is requesting 256MB of
  6. * memory that is backed by huge pages. The application uses the flag
  7. * SHM_HUGETLB in the shmget system call to inform the kernel that it is
  8. * requesting huge pages.
  9. *
  10. * For the ia64 architecture, the Linux kernel reserves Region number 4 for
  11. * huge pages. That means that if one requires a fixed address, a huge page
  12. * aligned address starting with 0x800000... will be required. If a fixed
  13. * address is not required, the kernel will select an address in the proper
  14. * range.
  15. * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
  16. *
  17. * Note: The default shared memory limit is quite low on many kernels,
  18. * you may need to increase it via:
  19. *
  20. * echo 268435456 > /proc/sys/kernel/shmmax
  21. *
  22. * This will increase the maximum size per shared memory segment to 256MB.
  23. * The other limit that you will hit eventually is shmall which is the
  24. * total amount of shared memory in pages. To set it to 16GB on a system
  25. * with a 4kB pagesize do:
  26. *
  27. * echo 4194304 > /proc/sys/kernel/shmall
  28. */
  29. #include <stdlib.h>
  30. #include <stdio.h>
  31. #include <sys/types.h>
  32. #include <sys/ipc.h>
  33. #include <sys/shm.h>
  34. #include <sys/mman.h>
  35. #ifndef SHM_HUGETLB
  36. #define SHM_HUGETLB 04000
  37. #endif
  38. #define LENGTH (256UL*1024*1024)
  39. #define dprintf(x) printf(x)
  40. /* Only ia64 requires this */
  41. #ifdef __ia64__
  42. #define ADDR (void *)(0x8000000000000000UL)
  43. #define SHMAT_FLAGS (SHM_RND)
  44. #else
  45. #define ADDR (void *)(0x0UL)
  46. #define SHMAT_FLAGS (0)
  47. #endif
  48. int main(void)
  49. {
  50. int shmid;
  51. unsigned long i;
  52. char *shmaddr;
  53. shmid = shmget(2, LENGTH, SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W);
  54. if (shmid < 0) {
  55. perror("shmget");
  56. exit(1);
  57. }
  58. printf("shmid: 0x%x\n", shmid);
  59. shmaddr = shmat(shmid, ADDR, SHMAT_FLAGS);
  60. if (shmaddr == (char *)-1) {
  61. perror("Shared memory attach failure");
  62. shmctl(shmid, IPC_RMID, NULL);
  63. exit(2);
  64. }
  65. printf("shmaddr: %p\n", shmaddr);
  66. dprintf("Starting the writes:\n");
  67. for (i = 0; i < LENGTH; i++) {
  68. shmaddr[i] = (char)(i);
  69. if (!(i % (1024 * 1024)))
  70. dprintf(".");
  71. }
  72. dprintf("\n");
  73. dprintf("Starting the Check...");
  74. for (i = 0; i < LENGTH; i++)
  75. if (shmaddr[i] != (char)i) {
  76. printf("\nIndex %lu mismatched\n", i);
  77. exit(3);
  78. }
  79. dprintf("Done.\n");
  80. if (shmdt((const void *)shmaddr) != 0) {
  81. perror("Detach failure");
  82. shmctl(shmid, IPC_RMID, NULL);
  83. exit(4);
  84. }
  85. shmctl(shmid, IPC_RMID, NULL);
  86. return 0;
  87. }