Changeset View
Changeset View
Standalone View
Standalone View
sys/sys/pcpu.h
Show First 20 Lines • Show All 166 Lines • ▼ Show 20 Lines | |||||
} while(0) | } while(0) | ||||
#endif /* _KERNEL */ | #endif /* _KERNEL */ | ||||
/* | /* | ||||
* This structure maps out the global data that needs to be kept on a | * This structure maps out the global data that needs to be kept on a | ||||
* per-cpu basis. The members are accessed via the PCPU_GET/SET/PTR | * per-cpu basis. The members are accessed via the PCPU_GET/SET/PTR | ||||
* macros defined in <machine/pcpu.h>. Machine dependent fields are | * macros defined in <machine/pcpu.h>. Machine dependent fields are | ||||
* defined in the PCPU_MD_FIELDS macro defined in <machine/pcpu.h>. | * defined in the PCPU_MD_FIELDS macro defined in <machine/pcpu.h>. | ||||
jhb: Maybe it would be simpler if we inverted these macros and had sys/pcpu.h define a… | |||||
Done Inline ActionsI suspect it would not, because due some definitions in sys/pcpu.h now would require placement after machine/pcpu.h defined complete struct pcpu. cpuhead is the first example. Also IMO it would cause much larger churn in source. kib: I suspect it would not, because due some definitions in sys/pcpu.h now would require placement… | |||||
*/ | */ | ||||
struct pcpu { | struct pcpu { | ||||
struct thread *pc_curthread; /* Current thread */ | struct thread *pc_curthread; /* Current thread */ | ||||
struct thread *pc_idlethread; /* Idle thread */ | struct thread *pc_idlethread; /* Idle thread */ | ||||
struct thread *pc_fpcurthread; /* Fp state owner */ | struct thread *pc_fpcurthread; /* Fp state owner */ | ||||
struct thread *pc_deadthread; /* Zombie thread or NULL */ | struct thread *pc_deadthread; /* Zombie thread or NULL */ | ||||
struct pcb *pc_curpcb; /* Current pcb */ | struct pcb *pc_curpcb; /* Current pcb */ | ||||
void *pc_sched; /* Scheduler state */ | void *pc_sched; /* Scheduler state */ | ||||
Show All 27 Lines | |||||
#ifdef _KERNEL | #ifdef _KERNEL | ||||
STAILQ_HEAD(cpuhead, pcpu); | STAILQ_HEAD(cpuhead, pcpu); | ||||
extern struct cpuhead cpuhead; | extern struct cpuhead cpuhead; | ||||
extern struct pcpu *cpuid_to_pcpu[]; | extern struct pcpu *cpuid_to_pcpu[]; | ||||
#define curcpu PCPU_GET(cpuid) | #define curcpu PCPU_GET(cpuid) | ||||
#define curproc (curthread->td_proc) | |||||
#ifndef curthread | |||||
#define curthread PCPU_GET(curthread) | |||||
#endif | |||||
#define curvidata PCPU_GET(vidata) | #define curvidata PCPU_GET(vidata) | ||||
#define UMA_PCPU_ALLOC_SIZE PAGE_SIZE | #define UMA_PCPU_ALLOC_SIZE PAGE_SIZE | ||||
#ifdef CTASSERT | #include <machine/pcpu_aux.h> | ||||
#if defined(__i386__) || defined(__amd64__) | |||||
/* Required for counters(9) to work on x86. */ | #ifndef curthread | ||||
CTASSERT(sizeof(struct pcpu) == UMA_PCPU_ALLOC_SIZE); | #define curthread PCPU_GET(curthread) | ||||
#else | #endif | ||||
/* | #define curproc (curthread->td_proc) | ||||
* To minimize memory waste in per-cpu UMA zones, size of struct pcpu | |||||
* should be denominator of PAGE_SIZE. | |||||
*/ | |||||
CTASSERT((PAGE_SIZE / sizeof(struct pcpu)) * sizeof(struct pcpu) == PAGE_SIZE); | |||||
#endif /* UMA_PCPU_ALLOC_SIZE && x86 */ | |||||
#endif /* CTASSERT */ | |||||
/* Accessor to elements allocated via UMA_ZONE_PCPU zone. */ | /* Accessor to elements allocated via UMA_ZONE_PCPU zone. */ | ||||
static inline void * | static inline void * | ||||
zpcpu_get(void *base) | zpcpu_get(void *base) | ||||
{ | { | ||||
return ((char *)(base) + UMA_PCPU_ALLOC_SIZE * curcpu); | return ((char *)(base) + UMA_PCPU_ALLOC_SIZE * curcpu); | ||||
} | } | ||||
Show All 28 Lines |
Maybe it would be simpler if we inverted these macros and had sys/pcpu.h define a PCPU_MI_FIELDS macro before #including <machine/pcpu.h> and then the MD header would define the actual 'struct pcpu' using 'PCPU_MI_FIELDS' as the first line? We could add a static assert that offsetof(struct pcpu, pc_curthread) == 0 in subr_pcpu.c. Would this let us keep a single header?