]>
git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/lib/util/cpuset.c
4 * Copyright(c) Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "spdk/cpuset.h"
38 char str
[SPDK_CPUSET_SIZE
/ 4 + 1];
39 uint8_t cpus
[SPDK_CPUSET_SIZE
/ 8];
43 spdk_cpuset_alloc(void)
45 return (struct spdk_cpuset
*)calloc(sizeof(struct spdk_cpuset
), 1);
49 spdk_cpuset_free(struct spdk_cpuset
*set
)
55 spdk_cpuset_equal(const struct spdk_cpuset
*set1
, const struct spdk_cpuset
*set2
)
59 return memcmp(set1
->cpus
, set2
->cpus
, sizeof(set2
->cpus
)) == 0;
63 spdk_cpuset_copy(struct spdk_cpuset
*dst
, const struct spdk_cpuset
*src
)
67 memcpy(&dst
->cpus
, &src
->cpus
, sizeof(src
->cpus
));
71 spdk_cpuset_negate(struct spdk_cpuset
*set
)
75 for (i
= 0; i
< sizeof(set
->cpus
); i
++) {
76 set
->cpus
[i
] = ~set
->cpus
[i
];
81 spdk_cpuset_and(struct spdk_cpuset
*dst
, const struct spdk_cpuset
*src
)
86 for (i
= 0; i
< sizeof(src
->cpus
); i
++) {
87 dst
->cpus
[i
] &= src
->cpus
[i
];
92 spdk_cpuset_or(struct spdk_cpuset
*dst
, const struct spdk_cpuset
*src
)
97 for (i
= 0; i
< sizeof(src
->cpus
); i
++) {
98 dst
->cpus
[i
] |= src
->cpus
[i
];
103 spdk_cpuset_xor(struct spdk_cpuset
*dst
, const struct spdk_cpuset
*src
)
108 for (i
= 0; i
< sizeof(src
->cpus
); i
++) {
109 dst
->cpus
[i
] ^= src
->cpus
[i
];
114 spdk_cpuset_zero(struct spdk_cpuset
*set
)
117 memset(set
->cpus
, 0, sizeof(set
->cpus
));
121 spdk_cpuset_set_cpu(struct spdk_cpuset
*set
, uint32_t cpu
, bool state
)
124 assert(cpu
< sizeof(set
->cpus
) * 8);
126 set
->cpus
[cpu
/ 8] |= (1U << (cpu
% 8));
128 set
->cpus
[cpu
/ 8] &= ~(1U << (cpu
% 8));
133 spdk_cpuset_get_cpu(const struct spdk_cpuset
*set
, uint32_t cpu
)
136 assert(cpu
< sizeof(set
->cpus
) * 8);
137 return (set
->cpus
[cpu
/ 8] >> (cpu
% 8)) & 1U;
141 spdk_cpuset_count(const struct spdk_cpuset
*set
)
146 for (i
= 0; i
< sizeof(set
->cpus
); i
++) {
157 spdk_cpuset_fmt(struct spdk_cpuset
*set
)
159 uint32_t lcore
, lcore_max
= 0;
162 static const char *hex
= "0123456789abcdef";
166 for (lcore
= 0; lcore
< sizeof(set
->cpus
) * 8; lcore
++) {
167 if (spdk_cpuset_get_cpu(set
, lcore
)) {
176 /* Store first number only if it is not leading zero */
177 if ((val
& 0xf0) != 0) {
178 *(ptr
++) = hex
[(val
& 0xf0) >> 4];
180 *(ptr
++) = hex
[val
& 0x0f];
182 for (i
= n
- 1; i
>= 0; i
--) {
184 *(ptr
++) = hex
[(val
& 0xf0) >> 4];
185 *(ptr
++) = hex
[val
& 0x0f];
195 #define V(x, y) [x] = y + 1
196 static const int8_t val
[256] = {
197 V('0', 0), V('1', 1), V('2', 2), V('3', 3), V('4', 4),
198 V('5', 5), V('6', 6), V('7', 7), V('8', 8), V('9', 9),
199 V('A', 0xA), V('B', 0xB), V('C', 0xC), V('D', 0xD), V('E', 0xE), V('F', 0xF),
200 V('a', 0xA), V('b', 0xB), V('c', 0xC), V('d', 0xD), V('e', 0xE), V('f', 0xF),
208 parse_list(const char *mask
, struct spdk_cpuset
*set
)
211 const char *ptr
= mask
;
213 uint32_t lcore_min
, lcore_max
;
215 spdk_cpuset_zero(set
);
216 lcore_min
= UINT32_MAX
;
221 while (isblank(*ptr
)) {
224 if (*ptr
== '\0' || *ptr
== ']' || *ptr
== '-' || *ptr
== ',') {
225 goto invalid_character
;
229 lcore
= strtoul(ptr
, &end
, 10);
231 SPDK_ERRLOG("Conversion of core mask in '%s' failed\n", mask
);
235 if (lcore
>= sizeof(set
->cpus
) * 8) {
236 SPDK_ERRLOG("Core number %" PRIu32
" is out of range in '%s'\n", lcore
, mask
);
240 while (isblank(*end
)) {
246 } else if (*end
== ',' || *end
== ']') {
248 if (lcore_min
== UINT32_MAX
) {
251 if (lcore_min
> lcore_max
) {
252 SPDK_ERRLOG("Invalid range of CPUs (%" PRIu32
" > %" PRIu32
")\n",
253 lcore_min
, lcore_max
);
256 for (lcore
= lcore_min
; lcore
<= lcore_max
; lcore
++) {
257 spdk_cpuset_set_cpu(set
, lcore
, true);
259 lcore_min
= UINT32_MAX
;
261 goto invalid_character
;
266 } while (*end
!= ']');
272 SPDK_ERRLOG("Unexpected end of core list '%s'\n", mask
);
274 SPDK_ERRLOG("Parsing of core list '%s' failed on character '%c'\n", mask
, *end
);
280 parse_mask(const char *mask
, struct spdk_cpuset
*set
, size_t len
)
287 if (mask
[0] == '0' && (mask
[1] == 'x' || mask
[1] == 'X')) {
292 spdk_cpuset_zero(set
);
293 for (i
= len
- 1; i
>= 0; i
--) {
297 /* Invalid character */
298 SPDK_ERRLOG("Invalid character in core mask '%s' (%c)\n", mask
, c
);
301 for (j
= 0; j
< 4 && lcore
< sizeof(set
->cpus
); j
++, lcore
++) {
302 if ((1 << j
) & val
) {
303 spdk_cpuset_set_cpu(set
, lcore
, true);
312 spdk_cpuset_parse(struct spdk_cpuset
*set
, const char *mask
)
317 if (mask
== NULL
|| set
== NULL
) {
321 while (isblank(*mask
)) {
326 while (len
> 0 && isblank(mask
[len
- 1])) {
334 if (mask
[0] == '[') {
335 ret
= parse_list(mask
, set
);
337 ret
= parse_mask(mask
, set
, len
);