diff --git a/UnixBench/src/context1.c b/UnixBench/src/context1.c index 4263ad1..1387f85 100644 --- a/UnixBench/src/context1.c +++ b/UnixBench/src/context1.c @@ -24,6 +24,9 @@ char SCCSid[] = "@(#) @(#)context1.c:3.3 -- 5/15/91 19:30:18"; * */ +#define _GNU_SOURCE +#include +#include #include #include #include @@ -37,6 +40,10 @@ void report() exit(0); } +static int get_cpu_num(void){ + return sysconf(_SC_NPROCESSORS_ONLN); +} + int main(argc, argv) int argc; char *argv[]; @@ -45,6 +52,7 @@ char *argv[]; unsigned long check; int p1[2], p2[2]; ssize_t ret; + int need_affinity; if (argc != 2) { fprintf(stderr, "Usage: context duration\n"); @@ -53,6 +61,11 @@ char *argv[]; duration = atoi(argv[1]); + /* if os has more than one cpu, will bind parent process to cpu 0 and child process to other cpus + * In this way, we can ensure context switch always happen + * */ + need_affinity = get_cpu_num() >> 1; + /* set up alarm call */ iter = 0; wake_me(duration, report); @@ -64,6 +77,19 @@ char *argv[]; } if (fork()) { /* parent process */ + if (need_affinity) { + cpu_set_t pmask; + int i; + CPU_ZERO(&pmask); + for (i = 0; i < need_affinity; i++) + CPU_SET(i, &pmask); + + if (sched_setaffinity(0, sizeof(cpu_set_t), &pmask) == -1) + { + perror("parent sched_setaffinity failed"); + } + } + /* master, write p1 & read p2 */ close(p1[0]); close(p2[1]); while (1) { @@ -94,6 +120,18 @@ char *argv[]; } } else { /* child process */ + if (need_affinity) { + cpu_set_t pmask; + int i; + CPU_ZERO(&pmask); + for (i = need_affinity; i < (need_affinity << 1); i++) + CPU_SET(i, &pmask); + + if (sched_setaffinity(0, sizeof(cpu_set_t), &pmask) == -1) + { + perror("child sched_setaffinity failed"); + } + } /* slave, read p1 & write p2 */ close(p1[1]); close(p2[0]); while (1) {