/* * Copyright (C) 2012 Red Hat, Inc. * * This work is licensed under the terms of the GNU GPL, version 2. See * the COPYING file in the top-level directory. */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #if 1 #define THREADS 24 #define SIZE (1UL*1024*1024*1024) #else #define THREADS 8 #define SIZE (500*1024*1024) #endif #define TOTALSIZE (4UL*1024*1024*1024*200) #define THREAD_SIZE (SIZE/THREADS) //#define HARD_BIND //#define INVERSE_BIND static void *thread(void * arg) { char *p = arg; int i; for (i = 0; i < TOTALSIZE/SIZE; i++) { bzero(p, THREAD_SIZE); asm volatile("" : : : "memory"); } return NULL; } #ifdef HARD_BIND static void bind(int node) { int i; unsigned long nodemask; cpu_set_t cpumask; CPU_ZERO(&cpumask); if (!node) { nodemask = 1; for (i = 0; i < 6; i++) CPU_SET(i, &cpumask); for (i = 12; i < 18; i++) CPU_SET(i, &cpumask); } else { nodemask = 2; for (i = 6; i < 12; i++) CPU_SET(i, &cpumask); for (i = 18; i < 24; i++) CPU_SET(i, &cpumask); } if (sched_setaffinity(0, sizeof(cpumask), &cpumask) < 0) perror("sched_setaffinity"), exit(1); if (set_mempolicy(MPOL_BIND, &nodemask, 3) < 0) perror("set_mempolicy"), printf("%lu\n", nodemask), exit(1); } #else static void bind(int node) {} #endif int main() { int i; pthread_t pthread[THREADS]; char *p; pid_t pid; int f; p = malloc(SIZE); if (!p) perror("malloc"), exit(1); bind(0); bzero(p, SIZE/2); bind(1); bzero(p+SIZE/2, SIZE/2); for (i = 0; i < THREADS; i++) { char *_p = p + THREAD_SIZE * i; #ifdef INVERSE_BIND bind(i < THREADS/2); #else bind(i >= THREADS/2); #endif if (pthread_create(&pthread[i], NULL, thread, _p) != 0) perror("pthread_create"), exit(1); } for (i = 0; i < THREADS; i++) if (pthread_join(pthread[i], NULL) != 0) perror("pthread_join"), exit(1); return 0; }