Back to index

numactl  2.0.8~rc4
memhog.c
Go to the documentation of this file.
00001 /* Copyright (C) 2003,2004 Andi Kleen, SuSE Labs.
00002    Allocate memory with policy for testing.
00003 
00004    numactl is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU General Public
00006    License as published by the Free Software Foundation; version
00007    2.
00008 
00009    numactl is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    General Public License for more details.
00013 
00014    You should find a copy of v2 of the GNU General Public License somewhere
00015    on your Linux system; if not, write to the Free Software Foundation,
00016    Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
00017 
00018 #include <stdlib.h>
00019 #include <stdio.h>
00020 #include <sys/mman.h>
00021 #include <sys/fcntl.h>
00022 #include <string.h>
00023 #include <stdbool.h>
00024 #include "numa.h"
00025 #include "numaif.h"
00026 #include "util.h"
00027 
00028 #define terr(x) perror(x)
00029 
00030 enum {
00031        UNIT = 10*1024*1024,
00032 };
00033 
00034 #ifndef MADV_NOHUGEPAGE
00035 #define MADV_NOHUGEPAGE 15
00036 #endif
00037 
00038 int repeat = 1;
00039 
00040 void usage(void)
00041 {
00042        printf("memhog [-rNUM] size[kmg] [policy [nodeset]]\n");
00043        printf("-rNUM repeat memset NUM times\n");
00044        printf("-H disable transparent hugepages\n");
00045        print_policies();
00046        exit(1);
00047 }
00048 
00049 long length;
00050 
00051 void hog(void *map)
00052 {
00053        long i;
00054        for (i = 0;  i < length; i += UNIT) {
00055               long left = length - i;
00056               if (left > UNIT)
00057                      left = UNIT;
00058               putchar('.');
00059               fflush(stdout);
00060               memset(map + i, 0xff, left);
00061        }
00062        putchar('\n');
00063 }
00064 
00065 int main(int ac, char **av)
00066 {
00067        char *map;
00068        struct bitmask *nodes, *gnodes;
00069        int policy, gpolicy;
00070        int ret = 0;
00071        int loose = 0;
00072        int i;
00073        int fd = -1;
00074        bool disable_hugepage = false;
00075 
00076        nodes = numa_allocate_nodemask();
00077        gnodes = numa_allocate_nodemask();
00078 
00079        while (av[1] && av[1][0] == '-') {
00080               switch (av[1][1]) {
00081               case 'f':
00082                      fd = open(av[1]+2, O_RDWR);
00083                      if (fd < 0)
00084                             perror(av[1]+2);
00085                      break; 
00086               case 'r':
00087                      repeat = atoi(av[1] + 2);
00088                      break;
00089               case 'H':
00090                      disable_hugepage = true;
00091                      break;
00092               default:      
00093                      usage();
00094               }
00095               av++;         
00096        }
00097        
00098        if (!av[1]) usage();
00099 
00100        length = memsize(av[1]);
00101        if (av[2] && numa_available() < 0) {
00102               printf("Kernel doesn't support NUMA policy\n");
00103               exit(1);
00104        } else
00105               loose = 1;
00106        policy = parse_policy(av[2], av[3]);
00107        if (policy != MPOL_DEFAULT)
00108               nodes = numa_parse_nodestring(av[3]);
00109         if (!nodes) {
00110               printf ("<%s> is invalid\n", av[3]);
00111               exit(1);
00112        }
00113        
00114        if (fd >= 0)
00115               map = mmap(NULL,length,PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
00116        else   
00117               map = mmap(NULL, length, PROT_READ|PROT_WRITE,
00118                                MAP_PRIVATE|MAP_ANONYMOUS,
00119                                0, 0);
00120        if (map == (char*)-1)
00121               err("mmap");
00122        
00123        if (mbind(map, length, policy, nodes->maskp, nodes->size, 0) < 0)
00124               terr("mbind");
00125 
00126        if (disable_hugepage)
00127               madvise(map, length, MADV_NOHUGEPAGE);
00128        
00129        gpolicy = -1;
00130        if (get_mempolicy(&gpolicy, gnodes->maskp, gnodes->size, map, MPOL_F_ADDR) < 0)
00131               terr("get_mempolicy");
00132        if (!loose && policy != gpolicy) {
00133               ret = 1;
00134               printf("policy %d gpolicy %d\n", policy, gpolicy);
00135        }
00136        if (!loose && !numa_bitmask_equal(gnodes, nodes)) {
00137               printf("nodes differ %lx, %lx!\n",
00138                      gnodes->maskp[0], nodes->maskp[0]);
00139               ret = 1;
00140        }
00141 
00142        for (i = 0; i < repeat; i++)
00143               hog(map);
00144        exit(ret);
00145 }