0001
0002
0003
0004
0005
0006
0007 #include <err.h>
0008 #include <errno.h>
0009 #include <signal.h>
0010 #include <stdio.h>
0011 #include <stdlib.h>
0012 #include <string.h>
0013 #include <unistd.h>
0014 #include <fcntl.h>
0015 #include <sys/types.h>
0016 #include <sys/shm.h>
0017 #include <sys/stat.h>
0018 #include <sys/mman.h>
0019
0020
0021 enum method {
0022 HUGETLBFS,
0023 MMAP_MAP_HUGETLB,
0024 SHM,
0025 MAX_METHOD
0026 };
0027
0028
0029
0030 static const char *self;
0031 static char *shmaddr;
0032 static int shmid;
0033
0034
0035
0036
0037 static void exit_usage(void)
0038 {
0039 printf("Usage: %s -p <path to hugetlbfs file> -s <size to map> "
0040 "[-m <0=hugetlbfs | 1=mmap(MAP_HUGETLB)>] [-l] [-r] "
0041 "[-o] [-w] [-n]\n",
0042 self);
0043 exit(EXIT_FAILURE);
0044 }
0045
0046 void sig_handler(int signo)
0047 {
0048 printf("Received %d.\n", signo);
0049 if (signo == SIGINT) {
0050 printf("Deleting the memory\n");
0051 if (shmdt((const void *)shmaddr) != 0) {
0052 perror("Detach failure");
0053 shmctl(shmid, IPC_RMID, NULL);
0054 exit(4);
0055 }
0056
0057 shmctl(shmid, IPC_RMID, NULL);
0058 printf("Done deleting the memory\n");
0059 }
0060 exit(2);
0061 }
0062
0063 int main(int argc, char **argv)
0064 {
0065 int fd = 0;
0066 int key = 0;
0067 int *ptr = NULL;
0068 int c = 0;
0069 int size = 0;
0070 char path[256] = "";
0071 enum method method = MAX_METHOD;
0072 int want_sleep = 0, private = 0;
0073 int populate = 0;
0074 int write = 0;
0075 int reserve = 1;
0076
0077 if (signal(SIGINT, sig_handler) == SIG_ERR)
0078 err(1, "\ncan't catch SIGINT\n");
0079
0080
0081 setvbuf(stdout, NULL, _IONBF, 0);
0082 self = argv[0];
0083
0084 while ((c = getopt(argc, argv, "s:p:m:owlrn")) != -1) {
0085 switch (c) {
0086 case 's':
0087 size = atoi(optarg);
0088 break;
0089 case 'p':
0090 strncpy(path, optarg, sizeof(path));
0091 break;
0092 case 'm':
0093 if (atoi(optarg) >= MAX_METHOD) {
0094 errno = EINVAL;
0095 perror("Invalid -m.");
0096 exit_usage();
0097 }
0098 method = atoi(optarg);
0099 break;
0100 case 'o':
0101 populate = 1;
0102 break;
0103 case 'w':
0104 write = 1;
0105 break;
0106 case 'l':
0107 want_sleep = 1;
0108 break;
0109 case 'r':
0110 private
0111 = 1;
0112 break;
0113 case 'n':
0114 reserve = 0;
0115 break;
0116 default:
0117 errno = EINVAL;
0118 perror("Invalid arg");
0119 exit_usage();
0120 }
0121 }
0122
0123 if (strncmp(path, "", sizeof(path)) != 0) {
0124 printf("Writing to this path: %s\n", path);
0125 } else {
0126 errno = EINVAL;
0127 perror("path not found");
0128 exit_usage();
0129 }
0130
0131 if (size != 0) {
0132 printf("Writing this size: %d\n", size);
0133 } else {
0134 errno = EINVAL;
0135 perror("size not found");
0136 exit_usage();
0137 }
0138
0139 if (!populate)
0140 printf("Not populating.\n");
0141 else
0142 printf("Populating.\n");
0143
0144 if (!write)
0145 printf("Not writing to memory.\n");
0146
0147 if (method == MAX_METHOD) {
0148 errno = EINVAL;
0149 perror("-m Invalid");
0150 exit_usage();
0151 } else
0152 printf("Using method=%d\n", method);
0153
0154 if (!private)
0155 printf("Shared mapping.\n");
0156 else
0157 printf("Private mapping.\n");
0158
0159 if (!reserve)
0160 printf("NO_RESERVE mapping.\n");
0161 else
0162 printf("RESERVE mapping.\n");
0163
0164 switch (method) {
0165 case HUGETLBFS:
0166 printf("Allocating using HUGETLBFS.\n");
0167 fd = open(path, O_CREAT | O_RDWR, 0777);
0168 if (fd == -1)
0169 err(1, "Failed to open file.");
0170
0171 ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
0172 (private ? MAP_PRIVATE : MAP_SHARED) |
0173 (populate ? MAP_POPULATE : 0) |
0174 (reserve ? 0 : MAP_NORESERVE),
0175 fd, 0);
0176
0177 if (ptr == MAP_FAILED) {
0178 close(fd);
0179 err(1, "Error mapping the file");
0180 }
0181 break;
0182 case MMAP_MAP_HUGETLB:
0183 printf("Allocating using MAP_HUGETLB.\n");
0184 ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
0185 (private ? (MAP_PRIVATE | MAP_ANONYMOUS) :
0186 MAP_SHARED) |
0187 MAP_HUGETLB | (populate ? MAP_POPULATE : 0) |
0188 (reserve ? 0 : MAP_NORESERVE),
0189 -1, 0);
0190
0191 if (ptr == MAP_FAILED)
0192 err(1, "mmap");
0193
0194 printf("Returned address is %p\n", ptr);
0195 break;
0196 case SHM:
0197 printf("Allocating using SHM.\n");
0198 shmid = shmget(key, size,
0199 SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W);
0200 if (shmid < 0) {
0201 shmid = shmget(++key, size,
0202 SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W);
0203 if (shmid < 0)
0204 err(1, "shmget");
0205 }
0206 printf("shmid: 0x%x, shmget key:%d\n", shmid, key);
0207
0208 ptr = shmat(shmid, NULL, 0);
0209 if (ptr == (int *)-1) {
0210 perror("Shared memory attach failure");
0211 shmctl(shmid, IPC_RMID, NULL);
0212 exit(2);
0213 }
0214 printf("shmaddr: %p\n", ptr);
0215
0216 break;
0217 default:
0218 errno = EINVAL;
0219 err(1, "Invalid method.");
0220 }
0221
0222 if (write) {
0223 printf("Writing to memory.\n");
0224 memset(ptr, 1, size);
0225 }
0226
0227 if (want_sleep) {
0228
0229 printf("DONE\n");
0230
0231
0232 while (1)
0233 sleep(100);
0234 }
0235
0236 if (method == HUGETLBFS)
0237 close(fd);
0238
0239 return 0;
0240 }