Back to index

numactl  2.0.8~rc4
randmap.c
Go to the documentation of this file.
00001 /* Randomly change policy */ 
00002 #include <stdio.h>
00003 #include "numa.h"
00004 #include "numaif.h"
00005 #include <sys/mman.h>
00006 #include <sys/shm.h>
00007 #include <sys/ipc.h>
00008 #include <stdlib.h>
00009 #include <time.h>
00010 #include <unistd.h>
00011 #include <string.h>
00012 #include <errno.h>
00013 
00014 #define SIZE (100*1024*1024) 
00015 #define PAGES (SIZE/pagesize)
00016 
00017 #define perror(x) printf("%s: %s\n", x, strerror(errno))
00018 #define err(x) perror(x),exit(1)
00019 
00020 struct page { 
00021        unsigned long mask; 
00022        int policy;
00023 };
00024 
00025 struct page *pages;
00026 char *map;
00027 int pagesize;
00028 
00029 void setpol(unsigned long offset, unsigned long length, int policy, unsigned long nodes)
00030 {
00031        long i, end;
00032 
00033        printf("off:%lx length:%lx policy:%d nodes:%lx\n",
00034               offset, length, policy, nodes);
00035 
00036        if (mbind(map + offset*pagesize, length*pagesize, policy,
00037                 &nodes, 8, 0) < 0) {
00038               printf("mbind: %s offset %lx length %lx policy %d nodes %lx\n", 
00039                      strerror(errno),
00040                      offset*pagesize, length*pagesize,
00041                      policy, nodes);
00042               return;
00043        }
00044 
00045        for (i = offset; i < offset+length; i++) { 
00046               pages[i].mask = nodes;
00047               pages[i].policy = policy;
00048        }
00049 
00050        i = offset - 20;
00051        if (i < 0) 
00052               i = 0; 
00053        end = offset+length+20; 
00054        if (end > PAGES)
00055               end = PAGES;
00056        for (; i < end; i++) { 
00057               int pol2;
00058               unsigned long nodes2;
00059               if (get_mempolicy(&pol2, &nodes2, sizeof(long)*8, map+i*pagesize, 
00060                                                  MPOL_F_ADDR) < 0)
00061                      err("get_mempolicy");
00062               if (pol2 != pages[i].policy) { 
00063                      printf("%lx: got policy %d expected %d, nodes got %lx expected %lx\n",
00064                             i, pol2, pages[i].policy, nodes2, pages[i].mask);
00065               }
00066               if (policy != MPOL_DEFAULT && nodes2 != pages[i].mask) {
00067                      printf("%lx: nodes %lx, expected %lx, policy %d\n",
00068                             i, nodes2, pages[i].mask, policy);
00069               }
00070        } 
00071 }
00072 
00073 static unsigned char pop4[16] = {
00074   0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
00075 }; 
00076 
00077 int popcnt(unsigned long val)
00078 { 
00079        int count = 0;
00080        while (val) { 
00081               count += pop4[val & 0xf];
00082               val >>= 4; 
00083        }
00084        return count;
00085 } 
00086 
00087 void testmap(void) 
00088 { 
00089 
00090        pages = calloc(1, PAGES * sizeof(struct page)); 
00091        if (!pages)
00092               exit(100);
00093 
00094        printf("simple tests\n");
00095 #define MB ((1024*1024)/pagesize)
00096        setpol(0, PAGES, MPOL_INTERLEAVE, 3); 
00097        setpol(0, MB, MPOL_BIND, 1); 
00098        setpol(MB, MB, MPOL_BIND, 1); 
00099        setpol(MB, MB, MPOL_DEFAULT, 0); 
00100        setpol(MB, MB, MPOL_PREFERRED, 2); 
00101        setpol(MB/2, MB, MPOL_DEFAULT, 0); 
00102        setpol(MB+MB/2, MB, MPOL_BIND, 2); 
00103        setpol(MB/2+100, 100, MPOL_PREFERRED, 1); 
00104        setpol(100, 200, MPOL_PREFERRED, 1);
00105        printf("done\n");
00106 
00107        for (;;) {    
00108               unsigned long offset = random() % PAGES; 
00109               int policy = random() % (MPOL_MAX+1);
00110               unsigned long nodes = random() % 4;
00111               long length = random() % (PAGES - offset);
00112 
00113               /* validate */ 
00114               switch (policy) { 
00115               case MPOL_DEFAULT: 
00116                      nodes = 0;
00117                      break;
00118               case MPOL_INTERLEAVE:
00119               case MPOL_BIND:
00120                      if (nodes == 0) 
00121                             continue;
00122                      break;
00123               case MPOL_PREFERRED:
00124                      if (popcnt(nodes) != 1) 
00125                             continue;
00126                      break;
00127               } 
00128 
00129 
00130               setpol(offset, length, policy, nodes);
00131 
00132        } 
00133 } 
00134 
00135 int main(int ac, char **av)
00136 {
00137        unsigned long seed;
00138 
00139        pagesize = getpagesize();
00140        
00141 #if 0
00142        map = mmap(NULL, SIZE, PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, 0, 0);
00143        if (map == (char*)-1)
00144               err("mmap");
00145 #else  
00146        int shmid = shmget(IPC_PRIVATE, SIZE, IPC_CREAT|0666); 
00147        if (shmid < 0) err("shmget");
00148        map = shmat(shmid, NULL, SHM_RDONLY);
00149        shmctl(shmid, IPC_RMID, NULL);
00150        if (map == (char *)-1) err("shmat");             
00151        printf("map %p\n", map);
00152 #endif
00153 
00154        if (av[1]) { 
00155               char *end;
00156               unsigned long timeout = strtoul(av[1], &end, 0);
00157               switch (*end) { 
00158               case 'h': timeout *= 3600; break;
00159               case 'm': timeout *= 60; break;
00160               }
00161               printf("running for %lu seconds\n", timeout);
00162               alarm(timeout);
00163        } else
00164               printf("running forever\n");
00165 
00166        if (av[1] && av[2])
00167               seed = strtoul(av[2], 0, 0);
00168        else
00169               seed = time(0);
00170 
00171        printf("random seed %lu\n", seed); 
00172        srandom(seed);
00173 
00174        testmap();
00175        /* test shm etc. */
00176        return 0;
00177 }