Main index | Section 9 | Options |
#include <sys/pcpu.h>
DPCPU_DEFINE(int, foo_int);
Values may also be initialized statically with the definition, causing each per-CPU instance to be initialized with the value:
DPCPU_DEFINE(int, foo_int) = 1;
Values that can be defined as static must use DPCPU_DEFINE_STATIC():
DPCPU_DEFINE_STATIC(int, foo_int);
DPCPU_DECLARE() produces a declaration of the per-CPU variable suitable for use in header files.
The current CPU's variable instance can be accessed via DPCPU_PTR (which returns a pointer to the per-CPU instance), DPCPU_GET (which retrieves the value of the per-CPU instance), and DPCPU_SET (which sets the value of the per-CPU instance).
Instances of variables associated with specific CPUs can be accessed via the DPCPU_ID_PTR, DPCPU_ID_GET, and DPGPU_ID_SET accessor functions, which accept an additional CPU ID argument, cpu.
For example, it may be desirable to protect access using critical_section(9) to prevent both preemption and migration during use. Alternatively, it may be desirable to cache the CPU ID at the start of a sequence of accesses, using suitable synchronization to make non-atomic sequences safe in the presence of migration.
DPCPU_DEFINE_STATIC(int, foo_int); DPCPU_DEFINE_STATIC(struct mutex, foo_lock);void foo_int_increment(void) { int cpu, value;
/* Safe as atomic access. */ atomic_add_int(DPCPU_PTR(foo_int), 1);
/* * Protect with a critical section, which prevents preemption * and migration. However, access to instances from remote CPUs * is not safe, as critical sections prevent concurrent access * only from the current CPU. */ critical_enter(); value = DPCPU_GET(foo_int); value++; DPCPU_SET(foo_int, value); critical_exit();
/* * Protect with a per-CPU mutex, tolerating migration, but * potentially accessing the variable from multiple CPUs if * migration occurs after reading curcpu. Remote access to a * per-CPU variable is safe as long as the correct mutex is * acquired. */ cpu = curcpu; mtx_lock(DPCPU_ID_PTR(cpu, foo_lock)); value = DPCPU_ID_GET(cpu, foo_int); value++; DPCPU_ID_SET(cpu, foo_int); mtx_unlock(DPCPU_ID_PTR(cpu, foo_lock)); }
DPCPU (9) | July 5, 2018 |
Main index | Section 9 | Options |
Please direct any comments about this manual page service to Ben Bullock. Privacy policy.
“ | UNIX has been evolving feverishly for close to 30 years, sort of like bacteria in a cesspool — only not as attractive | ” |
— John Levine, "Unix for Dummies" |