int migrate(uint64_t *ptr, int n1, int n2)
{ int ret, tmp; int status = 0; struct timespec ts1, ts2; int failures = 0;
if (clock_gettime(CLOCK_MONOTONIC, &ts1)) return -1;
while (1) { if (clock_gettime(CLOCK_MONOTONIC, &ts2)) return -1;
if (ts2.tv_sec - ts1.tv_sec >= RUNTIME) return0;
ret = move_pages(0, 1, (void **) &ptr, &n2, &status,
MPOL_MF_MOVE_ALL); if (ret) { if (ret > 0) { /* Migration is best effort; try again */ if (++failures < MAX_RETRIES) continue;
printf("Didn't migrate %d pages\n", ret);
} else
perror("Couldn't migrate pages"); return -2;
}
failures = 0;
tmp = n2;
n2 = n1;
n1 = tmp;
}
return0;
}
void *access_mem(void *ptr)
{ while (1) {
pthread_testcancel(); /* Force a read from the memory pointed to by ptr. This ensures *thememoryaccessactuallyhappensandpreventsthecompiler *fromoptimizingawaythisentireloop.
*/
FORCE_READ(*(uint64_t *)ptr);
}
memset(ptr, 0xde, TWOMEG); for (i = 0; i < self->nthreads - 1; i++) {
pid = fork(); if (!pid) {
prctl(PR_SET_PDEATHSIG, SIGHUP); /* Parent may have died before prctl so check now. */ if (getppid() == 1)
kill(getpid(), SIGHUP);
access_mem(ptr);
} else {
self->pids[i] = pid;
}
}
ASSERT_EQ(migrate(ptr, self->n1, self->n2), 0); for (i = 0; i < self->nthreads - 1; i++)
ASSERT_EQ(kill(self->pids[i], SIGTERM), 0);
}
memset(ptr, 0xde, TWOMEG); for (i = 0; i < self->nthreads - 1; i++) {
pid = fork(); if (!pid) {
prctl(PR_SET_PDEATHSIG, SIGHUP); /* Parent may have died before prctl so check now. */ if (getppid() == 1)
kill(getpid(), SIGHUP);
access_mem(ptr);
} else {
self->pids[i] = pid;
}
}
ASSERT_EQ(migrate(ptr, self->n1, self->n2), 0); for (i = 0; i < self->nthreads - 1; i++)
ASSERT_EQ(kill(self->pids[i], SIGTERM), 0);
}
memset(ptr, 0xde, TWOMEG); for (i = 0; i < self->nthreads - 1; i++) {
pid = fork(); if (!pid) {
prctl(PR_SET_PDEATHSIG, SIGHUP); /* Parent may have died before prctl so check now. */ if (getppid() == 1)
kill(getpid(), SIGHUP);
access_mem(ptr);
} else {
self->pids[i] = pid;
}
}
ASSERT_EQ(migrate(ptr, self->n1, self->n2), 0); for (i = 0; i < self->nthreads - 1; i++)
ASSERT_EQ(kill(self->pids[i], SIGTERM), 0);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.