File Coverage

lib/Sys/CpuAffinity.xs
Criterion Covered Total %
statement 37 47 78.7
branch 34 56 60.7
condition n/a
subroutine n/a
pod n/a
total 71 103 68.9


line stmt bran cond sub pod time code
1             #include
2             #include
3             #include
4             #include
5             #include
6              
7              
8              
9              
10             =pod
11            
12             linux-sched_getaffinity.xs: return CPU affinity with the Linux
13             sched_getaffinity(2) system call. See also:
14             linux-sched_setaffinity.xs .
15              
16              
17             /*
18             * This declaration isn't used and looks useless. But for some
19             * reason I don't understand at all, for some versions of perl
20             * with some build configurations running on some systems,
21             * this declaration is the difference between XS code that works
22             * (specifically, passing t/11-exercise-all.t) and code that
23             * segfaults. For the same reason, the cpu_set_t variables
24             * in xs_sched_getaffinity_get_affinity() below are declared
25             * static .
26             *
27             * Any insights into this issue would be profoundly appreciated.
28             */
29              
30             =cut
31            
32             char ___linux_sched_getaffinity_dummy[4096];
33              
34 0           void diag()
35             {
36 0           fprintf(stderr,"---\n");
37 0           fprintf(stderr,"diag CPU_SETSIZE=%d\n", CPU_SETSIZE);
38 0           fprintf(stderr,"diag sizeof(__cpu_mask)=%d\n", (int) sizeof(__cpu_mask));
39 0           fprintf(stderr,"diag __NCPUBITS=%d\n", (int) __NCPUBITS);
40 0           fprintf(stderr,"diag sizeof(cpu_set_t)=%d\n", (int) sizeof(cpu_set_t));
41 0           fprintf(stderr,"diag sizeof(pid_t)=%d\n", (int) sizeof(pid_t));
42 0           }
43              
44              
45              
46              
47             =pod
48              
49             linux-sched_setaffinity.xs: update CPU affinity with the Linux
50             sched_setaffinity(2) system call. See also:
51             linux-sched_getaffinity.xs .
52              
53             =cut
54              
55              
56              
57              
58             MODULE = Sys::CpuAffinity PACKAGE = Sys::CpuAffinity
59              
60             int
61             xs_fortytwo()
62             CODE:
63             /* The purpose of this trivial code snippet is to
64             see whether you can compile something, anything,
65             during this build process.
66              
67             If this doesn't compile, then you probably don't have
68             a compiler or it is badly misconfigured, and you
69             won't be able to generate any XS code with this
70             distribution. This would not necessarily mean that
71             this module wouldn't work -- it may still be possible
72             to manipulate CPU affinities on your system with Pure
73             Perl calls or with external utilities available on
74             your system.
75              
76             If this is the ONLY thing that compiles, then your
77             system-specific snippets might be incorrect, or your
78             system might be obscure enough that no system-specific
79             snippets have been developed for it yet. */
80             RETVAL = 42;
81             OUTPUT:
82             RETVAL
83              
84              
85              
86              
87              
88              
89              
90              
91             int
92             xs_sched_getaffinity_get_affinity(pid,maskarray,debug_flag)
93             int pid
94             AV *maskarray
95             int debug_flag
96             CODE:
97             int i, z;
98             int r = 0;
99             int ncpus = __NCPUBITS;
100             static cpu_set_t _set2, *_set1;
101              
102 50 50         if(debug_flag) diag();
103 50 50         if(debug_flag) fprintf(stderr,"getaffinity0\n");
104 50           _set1 = &_set2;
105 50 50         if(debug_flag) {
106 0           fprintf(stderr,"getaffinity1 pid=%d size=%d %d ncpu=%d cpuset=%p\n",
107             (int) pid, (int) CPU_SETSIZE, (int) sizeof(cpu_set_t),
108             ncpus, (void *) _set1);
109             }
110             /* RT 94560: CPU_SETSIZE might be less than sizeof(cpu_set_t) ? */
111 50           z = sched_getaffinity((pid_t) pid, sizeof(cpu_set_t), _set1);
112             #ifdef CPU_COUNT
113 50 50         if (debug_flag) fprintf(stderr,"getaffinity2a ncpus=%d\n", ncpus);
114 50           ncpus = CPU_COUNT(_set1);
115             /* CPU_COUNT is not the correct expression to use -- that is the number
116             of cpus that the process is currently bound to. */
117             #endif
118 50 50         if (debug_flag) fprintf(stderr,"getaffinity2b ncpus=%d\n", ncpus);
119 50           ncpus = sysconf(_SC_NPROCESSORS_ONLN);
120 50 50         if (debug_flag) fprintf(stderr,"getaffinity2c ncpus=%d\n", ncpus);
121 50           ncpus = sysconf(_SC_NPROCESSORS_CONF);
122 50 50         if(debug_flag) fprintf(stderr,"getaffinity2d ncpus=%d\n", ncpus);
123              
124 50 100         if (z) {
125 6 50         if(debug_flag) fprintf(stderr,"getaffinity3 z=%d err=%d\n", z, errno);
126             r = 0;
127             } else {
128 44           av_clear(maskarray);
129 44 50         if(debug_flag) fprintf(stderr,"getaffinity4\n");
130             /* tests.reproducible-builds.org/debian/rb-pkg/unstable/i386/
131             libsys-cpuaffinity-perl.html:
132             __NCPUBITS=32 but taskset,/proc/cpuinfo say there are 34 cpus */
133 748 100         for (i = 0, r = 0; i < ncpus; i++) {
134 704 50         if(debug_flag) fprintf(stderr,"getaffinity5 i=%d r=%d\n", i, r);
135 704 50         if (CPU_ISSET(i, &_set2)) {
    100          
    100          
136             r |= 1;
137 440           av_push(maskarray, newSViv(i));
138 440 50         if(debug_flag) fprintf(stderr,"getaffinity6 add %d to mask\n", i);
139 264 50         } else if(debug_flag) {
140 0           fprintf(stderr,"getaffinity6 don't add %d to mask\n",i);
141             }
142             }
143 44 50         if(debug_flag) fprintf(stderr,"getaffinity7 r=%d\n",r);
144             }
145             RETVAL = r;
146             OUTPUT:
147             RETVAL
148              
149              
150              
151              
152             int
153             xs_sched_setaffinity_set_affinity(pid,mask,debug_flag)
154             int pid
155             AV *mask
156             int debug_flag
157             CODE:
158             static cpu_set_t cpumask;
159             int i,r;
160            
161 16           CPU_ZERO(&cpumask);
162 164 100         for (i=0; i <= av_len(mask); i++) {
163 148 50         int c = SvIV(*av_fetch(mask,i,0));
164 148 50         if (debug_flag) fprintf(stderr,"sched_setaffinity%d = %d\n", i, c);
165 148 50         CPU_SET(c, &cpumask);
166             }
167 16           r = sched_setaffinity(pid, sizeof(cpu_set_t), &cpumask);
168 16 50         if (debug_flag) fprintf(stderr,"sched_setaffinity(%d,%ld,...) = %d\n", pid, (long unsigned int) sizeof(cpu_set_t), r);
169 16 100         if (r != 0) {
170 4 50         fprintf(stderr,"result: %d %d %s\n", r, errno,
171 4           errno==EFAULT ? "EFAULT" /* a supplied memory address was invalid */
172             : errno==EINVAL ? "EINVAL" /* the affinity bitmask contains no
173             processors that are physically on the
174             system, or _cpusetsize_ is smaller than
175             the size of the affinity mask used by
176             the kernel */
177 4 50         : errno==EPERM ? "EPERM" /* the calling process does not have
178             appropriate privilieges. The process
179             calling *sched_setaffinity()* needs an
180             effective user ID equal to the user ID
181             or effective user ID of the process
182             identified by _pid_, or it must possess
183             the _CAP_SYS_NICE_ capability. */
184 4 50         : errno==ESRCH ? "ESRCH" /* the process whose ID is _pid_ could not
185             be found */
186 4 50         :"E_WTF");
187             }
188 16           RETVAL = !r;
189             OUTPUT:
190             RETVAL
191              
192              
193              
194              
195              
196              
197