Commit | Line | Data |
---|---|---|
70bace8c RD |
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 | ||
54 | int main(void) | |
55 | { | |
56 | int shmid; | |
57 | unsigned long i; | |
58 | char *shmaddr; | |
59 | ||
60 | if ((shmid = shmget(2, LENGTH, | |
61 | SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W)) < 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 | dprintf("Done.\n"); | |
88 | ||
89 | if (shmdt((const void *)shmaddr) != 0) { | |
90 | perror("Detach failure"); | |
91 | shmctl(shmid, IPC_RMID, NULL); | |
92 | exit(3); | |
93 | } | |
94 | ||
95 | shmctl(shmid, IPC_RMID, NULL); | |
96 | ||
97 | return 0; | |
98 | } |