// SPDX-License-Identifier: GPL-2.0
/*
* This program reserves and uses hugetlb memory, supporting a bunch of
* scenarios needed by the charged_reserved_hugetlb.sh test.
*/
#include <err.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
/* Global definitions. */
enum method {
HUGETLBFS,
MMAP_MAP_HUGETLB,
SHM,
MAX_METHOD
};
/* Global variables. */
static const char *self;
static int *shmaddr;
static int shmid;
/*
* Show usage and exit.
*/
static void exit_usage(void )
{
printf("Usage: %s -p <path to hugetlbfs file> -s <size to map> "
"[-m <0=hugetlbfs | 1=mmap(MAP_HUGETLB)>] [-l] [-r] "
"[-o] [-w] [-n]\n" ,
self);
exit (EXIT_FAILURE);
}
void sig_handler(int signo)
{
printf("Received %d.\n" , signo);
if (signo == SIGINT) {
if (shmaddr) {
printf("Deleting the memory\n" );
if (shmdt((const void *)shmaddr) != 0 ) {
perror("Detach failure" );
shmctl(shmid, IPC_RMID, NULL);
exit (4 );
}
shmctl(shmid, IPC_RMID, NULL);
printf("Done deleting the memory\n" );
}
}
exit (2 );
}
int main(int argc, char **argv)
{
int fd = 0 ;
int key = 0 ;
int *ptr = NULL;
int c = 0 ;
int size = 0 ;
char path[256 ] = "" ;
enum method method = MAX_METHOD;
int want_sleep = 0 , private = 0 ;
int populate = 0 ;
int write = 0 ;
int reserve = 1 ;
if (signal(SIGINT, sig_handler) == SIG_ERR)
err(1 , "\ncan't catch SIGINT\n" );
/* Parse command-line arguments. */
setvbuf(stdout, NULL, _IONBF, 0 );
self = argv[0 ];
while ((c = getopt(argc, argv, "s:p:m:owlrn" )) != -1 ) {
switch (c) {
case 's' :
size = atoi(optarg);
break ;
case 'p' :
strncpy(path, optarg, sizeof (path) - 1 );
break ;
case 'm' :
if (atoi(optarg) >= MAX_METHOD) {
errno = EINVAL;
perror("Invalid -m." );
exit_usage();
}
method = atoi(optarg);
break ;
case 'o' :
populate = 1 ;
break ;
case 'w' :
write = 1 ;
break ;
case 'l' :
want_sleep = 1 ;
break ;
case 'r' :
private
= 1 ;
break ;
case 'n' :
reserve = 0 ;
break ;
default :
errno = EINVAL;
perror("Invalid arg" );
exit_usage();
}
}
if (strncmp(path, "" , sizeof (path)) != 0 ) {
printf("Writing to this path: %s\n" , path);
} else {
errno = EINVAL;
perror("path not found" );
exit_usage();
}
if (size != 0 ) {
printf("Writing this size: %d\n" , size);
} else {
errno = EINVAL;
perror("size not found" );
exit_usage();
}
if (!populate)
printf("Not populating.\n" );
else
printf("Populating.\n" );
if (!write)
printf("Not writing to memory.\n" );
if (method == MAX_METHOD) {
errno = EINVAL;
perror("-m Invalid" );
exit_usage();
} else
printf("Using method=%d\n" , method);
if (!private )
printf("Shared mapping.\n" );
else
printf("Private mapping.\n" );
if (!reserve)
printf("NO_RESERVE mapping.\n" );
else
printf("RESERVE mapping.\n" );
switch (method) {
case HUGETLBFS:
printf("Allocating using HUGETLBFS.\n" );
fd = open(path, O_CREAT | O_RDWR, 0777 );
if (fd == -1 )
err(1 , "Failed to open file." );
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
(private ? MAP_PRIVATE : MAP_SHARED) |
(populate ? MAP_POPULATE : 0 ) |
(reserve ? 0 : MAP_NORESERVE),
fd, 0 );
if (ptr == MAP_FAILED) {
close(fd);
err(1 , "Error mapping the file" );
}
break ;
case MMAP_MAP_HUGETLB:
printf("Allocating using MAP_HUGETLB.\n" );
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
(private ? (MAP_PRIVATE | MAP_ANONYMOUS) :
MAP_SHARED) |
MAP_HUGETLB | (populate ? MAP_POPULATE : 0 ) |
(reserve ? 0 : MAP_NORESERVE),
-1 , 0 );
if (ptr == MAP_FAILED)
err(1 , "mmap" );
printf("Returned address is %p\n" , ptr);
break ;
case SHM:
printf("Allocating using SHM.\n" );
shmid = shmget(key, size,
SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W);
if (shmid < 0 ) {
shmid = shmget(++key, size,
SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W);
if (shmid < 0 )
err(1 , "shmget" );
}
printf("shmid: 0x%x, shmget key:%d\n" , shmid, key);
ptr = shmat(shmid, NULL, 0 );
if (ptr == (int *)-1 ) {
perror("Shared memory attach failure" );
shmctl(shmid, IPC_RMID, NULL);
exit (2 );
}
shmaddr = ptr;
printf("shmaddr: %p\n" , shmaddr);
break ;
default :
errno = EINVAL;
err(1 , "Invalid method." );
}
if (write) {
printf("Writing to memory.\n" );
memset(ptr, 1 , size);
}
if (want_sleep) {
/* Signal to caller that we're done. */
printf("DONE\n" );
/* Hold memory until external kill signal is delivered. */
while (1 )
sleep(100 );
}
if (method == HUGETLBFS)
close(fd);
return 0 ;
}
Messung V0.5 in Prozent C=94 H=88 G=90
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-06-07)
¤
*© Formatika GbR, Deutschland