hugepage-shm.c 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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. if ((shmid = shmget(2, LENGTH,
  54. SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W)) < 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. dprintf("Done.\n");
  78. if (shmdt((const void *)shmaddr) != 0) {
  79. perror("Detach failure");
  80. shmctl(shmid, IPC_RMID, NULL);
  81. exit(3);
  82. }
  83. shmctl(shmid, IPC_RMID, NULL);
  84. return 0;
  85. }