1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
/*
* DEBUG: section 54 Interprocess Communication
*
*/
#include "squid.h"
#include "base/TextException.h"
#include "CpuAffinitySet.h"
#include "Debug.h"
#include "util.h"
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#if HAVE_STRING_H
#include <string.h>
#endif
CpuAffinitySet::CpuAffinitySet()
{
CPU_ZERO(&theCpuSet);
CPU_ZERO(&theOrigCpuSet);
}
void
CpuAffinitySet::apply()
{
Must(CPU_COUNT(&theCpuSet) > 0); // CPU affinity mask set
Must(!applied());
bool success = false;
if (sched_getaffinity(0, sizeof(theOrigCpuSet), &theOrigCpuSet)) {
debugs(54, DBG_IMPORTANT, "ERROR: failed to get CPU affinity for "
"process PID " << getpid() << ", ignoring CPU affinity for "
"this process: " << xstrerror());
} else {
cpu_set_t cpuSet;
memcpy(&cpuSet, &theCpuSet, sizeof(cpuSet));
(void) CPU_AND(&cpuSet, &cpuSet, &theOrigCpuSet);
if (CPU_COUNT(&cpuSet) <= 0) {
debugs(54, DBG_IMPORTANT, "ERROR: invalid CPU affinity for process "
"PID " << getpid() << ", may be caused by an invalid core in "
"'cpu_affinity_map' or by external affinity restrictions");
} else if (sched_setaffinity(0, sizeof(cpuSet), &cpuSet)) {
debugs(54, DBG_IMPORTANT, "ERROR: failed to set CPU affinity for "
"process PID " << getpid() << ": " << xstrerror());
} else
success = true;
}
if (!success)
CPU_ZERO(&theOrigCpuSet);
}
void
CpuAffinitySet::undo()
{
if (applied()) {
if (sched_setaffinity(0, sizeof(theOrigCpuSet), &theOrigCpuSet)) {
debugs(54, DBG_IMPORTANT, "ERROR: failed to restore original CPU "
"affinity for process PID " << getpid() << ": " <<
xstrerror());
}
CPU_ZERO(&theOrigCpuSet);
}
}
bool
CpuAffinitySet::applied()
{
// NOTE: cannot be const.
// According to CPU_SET(3) and, apparently, on some systems (e.g.,
// OpenSuSE 10.3) CPU_COUNT macro expects a non-const argument.
return (CPU_COUNT(&theOrigCpuSet) > 0);
}
void
CpuAffinitySet::set(const cpu_set_t &aCpuSet)
{
memcpy(&theCpuSet, &aCpuSet, sizeof(theCpuSet));
}
|