Logo Search packages:      
Sourcecode: numactl version File versions  Download package

randmap.c

/* Randomly change policy */ 
#include <stdio.h>
#include "numaif.h"
#include <sys/mman.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#define SIZE (100*1024*1024) 
#define PAGES (SIZE/pagesize)

#define perror(x) printf("%s: %s\n", x, strerror(errno))
#define err(x) perror(x),exit(1)

struct page { 
      unsigned long mask; 
      int policy;
};

struct page *pages;
char *map;
int pagesize;

void setpol(unsigned long offset, unsigned long length, int policy, unsigned long nodes)
{
      long i, end;

      printf("off:%lx length:%lx policy:%d nodes:%lx\n",
             offset, length, policy, nodes);
      
      if (mbind(map + offset*pagesize, length*pagesize, policy,
              &nodes, 8, 0) < 0) {
            printf("mbind: %s offset %lx length %lx policy %d nodes %lx\n", 
                   strerror(errno),
                   offset*pagesize, length*pagesize,
                   policy, nodes);
            return;
      }

      for (i = offset; i < offset+length; i++) { 
            pages[i].mask = nodes;
            pages[i].policy = policy;
      }

      i = offset - 20;
      if (i < 0) 
            i = 0; 
      end = offset+length+20; 
      if (end > PAGES)
            end = PAGES;
      for (; i < end; i++) { 
            int pol2;
            unsigned long nodes2;
            if (get_mempolicy(&pol2, &nodes2, sizeof(long)*8, map+i*pagesize, 
                          MPOL_F_ADDR) < 0)
                  err("get_mempolicy");
            if (pol2 != pages[i].policy) { 
                  printf("%lx: got policy %d expected %d, nodes got %lx expected %lx\n",
                         i,
                         pol2, pages[i].policy, nodes2, pages[i].mask);
            }
            if (policy != MPOL_DEFAULT && nodes2 != pages[i].mask) { 
                  printf("%lx: nodes %lx, expected %lx, policy %d\n",
                         i, nodes2, pages[i].mask, policy);
            }
      } 
}

static unsigned char pop4[16] = {
  0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
}; 

int popcnt(unsigned long val)
{ 
      int count = 0;
      while (val) { 
            count += pop4[val & 0xf];
            val >>= 4; 
      }
      return count;
} 

void testmap(void) 
{ 

      pages = calloc(1, PAGES * sizeof(struct page)); 
      if (!pages)
            exit(100);

      printf("simple tests\n");
#define MB ((1024*1024)/pagesize)
      setpol(0, PAGES, MPOL_INTERLEAVE, 3); 
      setpol(0, MB, MPOL_BIND, 1); 
      setpol(MB, MB, MPOL_BIND, 1); 
      setpol(MB, MB, MPOL_DEFAULT, 0); 
      setpol(MB, MB, MPOL_PREFERRED, 2); 
      setpol(MB/2, MB, MPOL_DEFAULT, 0); 
      setpol(MB+MB/2, MB, MPOL_BIND, 2); 
      setpol(MB/2+100, 100, MPOL_PREFERRED, 1); 
      setpol(100, 200, MPOL_PREFERRED, 1);
      printf("done\n");

      for (;;) {  
            unsigned long offset = random() % PAGES; 
            int policy = random() % (MPOL_MAX+1);
            unsigned long nodes = random() % 4;
            long length = random() % (PAGES - offset);

            /* validate */ 
            switch (policy) { 
            case MPOL_DEFAULT: 
                  nodes = 0;
                  break;
            case MPOL_INTERLEAVE:
            case MPOL_BIND:
                  if (nodes == 0) 
                        continue;
                  break;
            case MPOL_PREFERRED:
                  if (popcnt(nodes) != 1) 
                        continue;
                  break;
            } 


            setpol(offset, length, policy, nodes);

      } 
} 

int main(int ac, char **av)
{
      unsigned long seed;

      pagesize = getpagesize();
      
#if 0
      map = mmap(NULL, SIZE, PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, 0, 0);
      if (map == (char*)-1)
            err("mmap");
#else 
      int shmid = shmget(IPC_PRIVATE, SIZE, IPC_CREAT|0666); 
      if (shmid < 0) err("shmget");
      map = shmat(shmid, NULL, SHM_RDONLY);
      shmctl(shmid, IPC_RMID, NULL);
      if (map == (char *)-1) err("shmat");            
      printf("map %p\n", map);
#endif

      if (av[1]) { 
            char *end;
            unsigned long timeout = strtoul(av[1], &end, 0);
            switch (*end) { 
            case 'h': timeout *= 3600; break;
            case 'm': timeout *= 60; break;
            }
            printf("running for %lu seconds\n", timeout);
            alarm(timeout);
      } else
            printf("running forever\n");

      if (av[1] && av[2])
            seed = strtoul(av[2], 0, 0);
      else
            seed = time(0);

      printf("random seed %lu\n", seed); 
      srandom(seed);

      testmap();
      /* test shm etc. */
      return 0;
} 

Generated by  Doxygen 1.6.0   Back to index