| #include <sys/shm.h> |
| #include <sys/ipc.h> |
| #include <sys/fcntl.h> |
| #include <stdio.h> |
| #include <numaif.h> |
| |
| #define err(x) perror(x),exit(1) |
| |
| enum { |
| MEMSZ = 10*1024*1024, |
| }; |
| |
| struct req { |
| enum cmd { |
| SET = 1, |
| CHECK, |
| REPLY, |
| EXIT, |
| } cmd; |
| long offset; |
| long len; |
| int policy; |
| nodemask_t nodes; |
| }; |
| |
| void worker(void) |
| { |
| struct req req; |
| while (read(0, &req, sizeof(struct req) > 0)) { |
| switch (req.cmd) { |
| case SET: |
| if (mbind(map + req.offset, req.len, req.policy, &req.nodes, |
| NUMA_MAX_NODES+1, 0) < 0) |
| err("mbind"); |
| break; |
| case TEST: |
| req.cmd = REPLY; |
| if (get_mempolicy(&req.policy, &req.nodes, NUMA_MAX_NODES+1, |
| map + req.offset, MPOL_F_ADDR) < 0) |
| err("get_mempolicy"); |
| write(1, &req, sizeof(struct req)); |
| break; |
| case EXIT: |
| return; |
| default: |
| abort(); |
| } |
| } |
| } |
| |
| void sendreq(int fd, enum cmd cmd, int policy, long offset, long len, nodemask_t nodes) |
| { |
| struct req req = { |
| .cmd = cmd, |
| .offset = offset, |
| .len = len, |
| .policy = policy, |
| .nodes = nodes |
| }; |
| if (write(fd, &req, sizeof(struct req)) != sizeof(struct req)) |
| panic("bad req write"); |
| } |
| |
| void readreq(int fd, int *policy, nodemask_t *nodes, long offset, long len) |
| { |
| struct req req; |
| if (read(fd, &req, sizeof(struct req)) != sizeof(struct req)) |
| panic("bad req read"); |
| if (req.cmd != REPLY) |
| abort(); |
| *policy = req.policy; |
| *nodes = req.nodes; |
| } |
| |
| int main(void) |
| { |
| int fd = open("tshm", O_CREAT, 0600); |
| close(fd); |
| key_t key = ftok("tshm", 1); |
| int shm = shmget(key, MEMSZ, IPC_CREAT|0600); |
| if (shm < 0) err("shmget"); |
| char *map = shmat(shm, NULL, 0); |
| printf("map = %p\n", map); |
| |
| unsigned long nmask = 0x3; |
| if (mbind(map, MEMSZ, MPOL_INTERLEAVE, &nmask, 4, 0) < 0) err("mbind1"); |
| |
| int fd[2]; |
| if (pipe(fd) < 0) err("pipe"); |
| if (fork() == 0) { |
| close(0); |
| close(1); |
| dup2(fd[0], 0); |
| dup2(fd[1], 1); |
| worker(); |
| _exit(0); |
| } |
| |
| int pagesz = getpagesize(); |
| int i; |
| |
| srand(1); |
| for (;;) { |
| |
| /* chose random offset */ |
| |
| /* either in child or here */ |
| |
| /* change policy */ |
| |
| /* ask other guy to check */ |
| |
| } |
| |
| shmdt(map); |
| shmctl(shm, IPC_RMID, 0); |
| } |