#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
/* ---- Minimal helpers to make this runnable ---- */
#define BIT_SET(x, bit) (((x) >> (bit)) & 1)
typedef struct CPUSet {
size_t allocated; /* number of CPUs */
uint8_t *set; /* bitset */
} CPUSet;
static void cpu_set_done(CPUSet *c) {
if (!c)
return;
free(c->set);
c->set = NULL;
c->allocated = 0;
}
#define _cleanup_(f) __attribute__((cleanup(f)))
static int cpu_set_realloc(CPUSet *c, size_t n_cpus) {
size_t n_bytes = (n_cpus + 7) / 8;
uint8_t *n = calloc(1, n_bytes);
if (!n)
return -1;
free(c->set);
c->set = n;
c->allocated = n_cpus;
return 0;
}
#define CPU_SET_S(cpu, ncpus, set) \
do { \
if ((size_t)(cpu) < (ncpus)) \
(set)[(cpu) / 8] |= (1U << ((cpu) % 8)); \
} while (0)
#define TAKE_STRUCT(s) (__extension__ ({ \
typeof(s) _tmp = (s); \
memset(&(s), 0, sizeof(s)); \
_tmp; \
}))
/* ---- Your function, unchanged ---- */
int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *ret) {
_cleanup_(cpu_set_done) CPUSet c = {};
int r;
assert(bits || size == 0);
assert(ret);
r = cpu_set_realloc(&c, size * 8);
if (r < 0)
return r;
for (size_t i = 0; i < size * 8; i++)
if (BIT_SET(bits[i / 8], i % 8))
CPU_SET_S(i, c.allocated, c.set);
*ret = TAKE_STRUCT(c);
return 0;
}
/* ---- Main test harness ---- */
int main(void) {
uint8_t bits[] = { 0x03, 0x00, 0x00, 0x00, 0x0f };
CPUSet set = {};
int r;
r = cpu_set_from_dbus(bits, sizeof(bits), &set);
if (r < 0) {
fprintf(stderr, "cpu_set_from_dbus failed\n");
return 1;
}
printf("CPUs set: ");
for (size_t i = 0; i < set.allocated; i++) {
if (BIT_SET(set.set[i / 8], i % 8))
printf("%zu ", i);
}
printf("\n");
cpu_set_done(&set);
return 0;
}