vgdb: Handle EAGAIN in read_buf
[valgrind.git] / none / tests / map_unmap.c
blob212d7e363573d4533624606d0333a38a7823be55
1 #include <stdio.h>
2 #include "tests/sys_mman.h"
3 #include <stdlib.h>
4 #include <unistd.h>
6 /* The code testing MAP_HUGETLB huge pages is disabled by default,
7 as many distros do not have huge pages configured
8 by default.
9 To have e.g. 20 huge pages configured, do (as root)
10 echo 20 > /proc/sys/vm/nr_hugepages
11 Once this is done, uncomment the below, and recompile.
13 //#define TEST_MAP_HUGETLB 1
15 /* Similarly, testing SHM_HUGETLB huge pages is disabled by default.
16 To have shmget/shmat big pages working, do (as root)
17 echo 500 > /proc/sys/vm/hugetlb_shm_group
18 where 500 is the groupid of the user that runs this test
19 Once this is done, uncomment the below, and recompile.
21 //#define TEST_SHM_HUGETLB 1
23 // Size to use for huge pages
24 #define HUGESZ (4 * 1024 * 1024)
26 #ifdef TEST_MAP_HUGETLB
27 /* Ensure this compiles on pre 2.6 systems, or on glibc missing MAP_HUGETLB */
28 #ifndef MAP_HUGETLB
29 /* The below works for me on an f12/x86 linux */
30 #define MAP_HUGETLB 0x40000
31 #endif
33 #endif /* TEST_MAP_HUGETLB */
35 #ifdef TEST_SHM_HUGETLB
36 #include <sys/ipc.h>
37 #include <sys/shm.h>
38 #include <sys/stat.h>
39 #ifndef SHM_HUGETLB
40 #define SHM_HUGETLB 04000
41 #endif
42 #endif /* TEST_SHM_HUGETLB */
44 static unsigned int pagesize;
46 #define PAGES 1024u
47 #define LEN (PAGES*pagesize)
49 static void *domap(size_t len, int addflags)
51 void *ret = mmap(0, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|addflags, -1, 0);
53 if (ret == (void *)-1) {
54 perror("mmap");
55 exit(1);
58 return ret;
61 /* unmap in pieces to exercise munmap more */
62 static void nibblemap(void *p)
64 int off;
65 int i;
67 off = (random() % LEN) & ~(pagesize-1);
69 for(i = 0; i < PAGES; i++) {
70 /* printf("unmapping off=%d\n", off/pagesize); */
71 munmap((char *)p + off, pagesize);
72 off += 619*pagesize;
73 off %= LEN;
77 static void prmaps()
79 char buf[100];
80 sprintf(buf, "/bin/cat /proc/%ld/maps", (long) getpid());
81 system(buf);
82 exit(1);
85 int main()
87 int i;
88 void *expect1, *expect2;
90 pagesize = getpagesize();
92 expect1 = domap(LEN, 0);
93 expect2 = domap(LEN, 0);
94 munmap(expect1, LEN);
95 munmap(expect2, LEN);
97 for(i = 0; i < 5; i++) {
98 void *m1, *m2;
100 m1 = domap(LEN, 0);
101 if (m1 != expect1) {
102 printf("FAIL i=%d: m1=%p expect1=%p\n",
103 i, m1, expect1);
104 prmaps();
105 return 1;
107 m2 = domap(LEN, 0);
108 if (m2 != expect2) {
109 printf("FAIL i=%d: m2=%p expect2=%p\n",
110 i, m2, expect2);
111 prmaps();
112 return 1;
114 nibblemap(m2);
115 munmap(m1, LEN);
118 #ifdef TEST_MAP_HUGETLB
120 void *expect3;
121 expect3 = domap(HUGESZ, MAP_HUGETLB);
122 munmap(expect3, HUGESZ);
124 #endif
126 #ifdef TEST_SHM_HUGETLB
128 int shmid;
129 void *expect4;
132 shmid = shmget(IPC_PRIVATE, HUGESZ,
133 IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR | SHM_HUGETLB);
134 if (shmid == -1) {
135 perror("shmget");
136 exit(1);
138 expect4 = shmat(shmid, NULL, 0);
139 if (expect4 == (void*) -1){
140 perror("shmat");
141 exit(1);
143 if (shmdt(expect4) != 0) {
144 perror("shmdt");
145 exit(1);
147 if (shmctl(shmid, IPC_RMID, 0) != 0) {
148 perror("shmctl IPC_RMID");
149 exit(1);
152 #endif
154 printf("PASS\n");
155 return 0;