3
* Copyright (c) 2004-2006 The Trustees of Indiana University.
5
* Copyright (c) 2004-2005 The Regents of the University of California.
7
* Copyright (c) 2007-2008 Cisco Systems, Inc. All rights reserved.
10
* Additional copyrights may follow
15
#include "plpa_config.h"
17
#include "plpa_internal.h"
20
#include <sys/syscall.h>
24
* Call the kernel's setaffinity, massaging the user's input
25
* parameters as necessary
27
int PLPA_NAME(sched_setaffinity)(pid_t pid, size_t cpusetsize,
28
const PLPA_NAME(cpu_set_t) *cpuset)
32
PLPA_NAME(cpu_set_t) tmp;
33
PLPA_NAME(api_type_t) api;
35
/* Check to see that we're initialized */
36
if (!PLPA_NAME(initialized)) {
37
if (0 != (ret = PLPA_NAME(init)())) {
42
/* Check for bozo arguments */
47
/* Probe the API type */
48
if (0 != (ret = PLPA_NAME(api_probe)(&api))) {
52
case PLPA_NAME_CAPS(PROBE_OK):
53
/* This shouldn't happen, but check anyway */
54
if (cpusetsize > sizeof(*cpuset)) {
58
/* If the user-supplied bitmask is smaller than what the
59
kernel wants, zero out a temporary buffer of the size that
60
the kernel wants and copy the user-supplied bitmask to the
61
lower part of the temporary buffer. This could be done
62
more efficiently, but we're looking for clarity/simplicity
63
of code here -- this is not intended to be
64
performance-critical. */
65
if (cpusetsize < PLPA_NAME(len)) {
66
memset(&tmp, 0, sizeof(tmp));
67
for (i = 0; i < cpusetsize * 8; ++i) {
68
if (PLPA_CPU_ISSET(i, cpuset)) {
69
PLPA_CPU_SET(i, &tmp);
74
/* If the user-supplied bitmask is larger than what the kernel
75
will accept, scan it and see if there are any set bits in
76
the part larger than what the kernel will accept. If so,
77
return EINVAL. Otherwise, copy the part that the kernel
78
will accept into a temporary and use that. Again,
79
efficinency is not the issue of this code -- clarity is. */
80
else if (cpusetsize > PLPA_NAME(len)) {
81
for (i = PLPA_NAME(len) * 8; i < cpusetsize * 8; ++i) {
82
if (PLPA_CPU_ISSET(i, cpuset)) {
86
/* No upper-level bits are set, so now copy over the bits
87
that the kernel will look at */
88
memset(&tmp, 0, sizeof(tmp));
89
for (i = 0; i < PLPA_NAME(len) * 8; ++i) {
90
if (PLPA_CPU_ISSET(i, cpuset)) {
91
PLPA_CPU_SET(i, &tmp);
96
/* Otherwise, the user supplied a buffer that is exactly the
97
right size. Just for clarity of code, copy the user's
98
buffer into the temporary and use that. */
100
memcpy(&tmp, cpuset, cpusetsize);
103
/* Now do the syscall */
104
ret = syscall(__NR_sched_setaffinity, pid, PLPA_NAME(len), &tmp);
106
/* Return 0 upon success. According to
107
http://www.open-mpi.org/community/lists/plpa-users/2006/02/0016.php,
108
all the kernel implementations return >= 0 upon success. */
116
case PLPA_NAME_CAPS(PROBE_NOT_SUPPORTED):
117
/* Process affinity not supported here */
122
/* Something went wrong */
123
/* JMS: would be good to have something other than EINVAL here
132
* Call the kernel's getaffinity, massaging the user's input
133
* parameters as necessary
135
int PLPA_NAME(sched_getaffinity)(pid_t pid, size_t cpusetsize,
136
PLPA_NAME(cpu_set_t) *cpuset)
139
PLPA_NAME(api_type_t) api;
141
/* Check to see that we're initialized */
142
if (!PLPA_NAME(initialized)) {
143
if (0 != (ret = PLPA_NAME(init)())) {
148
/* Check for bozo arguments */
149
if (NULL == cpuset) {
152
/* Probe the API type */
153
if (0 != (ret = PLPA_NAME(api_probe)(&api))) {
157
case PLPA_NAME_CAPS(PROBE_OK):
158
/* This shouldn't happen, but check anyway */
159
if (PLPA_NAME(len) > sizeof(*cpuset)) {
163
/* If the user supplied a buffer that is too small, then don't
165
if (cpusetsize < PLPA_NAME(len)) {
169
/* Now we know that the user's buffer is >= the size required
170
by the kernel. If it's >, then zero it out so that the
171
bits at the top are cleared (since they won't be set by the
173
if (cpusetsize > PLPA_NAME(len)) {
174
memset(cpuset, 0, cpusetsize);
177
/* Now do the syscall */
178
ret = syscall(__NR_sched_getaffinity, pid, PLPA_NAME(len), cpuset);
180
/* Return 0 upon success. According to
181
http://www.open-mpi.org/community/lists/plpa-users/2006/02/0016.php,
182
all the kernel implementations return >= 0 upon success. */
190
case PLPA_NAME_CAPS(PROBE_NOT_SUPPORTED):
191
/* Process affinity not supported here */
196
/* Something went wrong */