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 30#include <stdlib.h> 31#include <stdio.h> 32#include <sys/types.h> 33#include <sys/ipc.h> 34#include <sys/shm.h> 35#include <sys/mman.h> 36 37#ifndef SHM_HUGETLB 38#define SHM_HUGETLB 04000 39#endif 40 41#define LENGTH (256UL*1024*1024) 42 43#define dprintf(x) printf(x) 44 45/* Only ia64 requires this */ 46#ifdef __ia64__ 47#define ADDR (void *)(0x8000000000000000UL) 48#define SHMAT_FLAGS (SHM_RND) 49#else 50#define ADDR (void *)(0x0UL) 51#define SHMAT_FLAGS (0) 52#endif 53 54int main(void) 55{ 56 int shmid; 57 unsigned long i; 58 char *shmaddr; 59 60 shmid = shmget(2, LENGTH, SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W); 61 if (shmid < 0) { 62 perror("shmget"); 63 exit(1); 64 } 65 printf("shmid: 0x%x\n", shmid); 66 67 shmaddr = shmat(shmid, ADDR, SHMAT_FLAGS); 68 if (shmaddr == (char *)-1) { 69 perror("Shared memory attach failure"); 70 shmctl(shmid, IPC_RMID, NULL); 71 exit(2); 72 } 73 printf("shmaddr: %p\n", shmaddr); 74 75 dprintf("Starting the writes:\n"); 76 for (i = 0; i < LENGTH; i++) { 77 shmaddr[i] = (char)(i); 78 if (!(i % (1024 * 1024))) 79 dprintf("."); 80 } 81 dprintf("\n"); 82 83 dprintf("Starting the Check..."); 84 for (i = 0; i < LENGTH; i++) 85 if (shmaddr[i] != (char)i) { 86 printf("\nIndex %lu mismatched\n", i); 87 exit(3); 88 } 89 dprintf("Done.\n"); 90 91 if (shmdt((const void *)shmaddr) != 0) { 92 perror("Detach failure"); 93 shmctl(shmid, IPC_RMID, NULL); 94 exit(4); 95 } 96 97 shmctl(shmid, IPC_RMID, NULL); 98 99 return 0; 100} 101