#ifndef I386_CPU_DATA
#define I386_CPU_DATA
#include <cpus.h>
#include <mach_assert.h>
#if defined(__GNUC__)
#include <kern/assert.h>
#include <kern/kern_types.h>
#include <pexpert/pexpert.h>
typedef struct
{
thread_act_t *active_thread;
int preemption_level;
int simple_lock_count;
int interrupt_level;
int cpu_number;
int cpu_phys_number;
cpu_id_t cpu_id;
int cpu_status;
int cpu_signals;
int mcount_off;
} cpu_data_t;
extern cpu_data_t cpu_data[NCPUS];
#define offsetof(TYPE,MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define CPU_DATA_GET(field,type) \
type ret; \
__asm__ volatile ("movl %%gs:%P1,%0" \
: "=r" (ret) \
: "i" (offsetof(cpu_data_t,field))); \
return ret;
extern thread_act_t __inline__ get_active_thread(void)
{
CPU_DATA_GET(active_thread,thread_act_t)
}
#define current_act_fast() get_active_thread()
#define current_act() current_act_fast()
#define current_thread() current_act_fast()->thread
extern int __inline__ get_preemption_level(void)
{
CPU_DATA_GET(preemption_level,int)
}
extern int __inline__ get_simple_lock_count(void)
{
CPU_DATA_GET(simple_lock_count,int)
}
extern int __inline__ get_interrupt_level(void)
{
CPU_DATA_GET(interrupt_level,int)
}
extern int __inline__ get_cpu_number(void)
{
CPU_DATA_GET(cpu_number,int)
}
extern int __inline__ get_cpu_phys_number(void)
{
CPU_DATA_GET(cpu_phys_number,int)
}
extern void __inline__ disable_preemption(void)
{
register int idx = (int)&((cpu_data_t *)0)->preemption_level;
__asm__ volatile (" incl %%gs:(%0)" : : "r" (idx));
}
extern void __inline__ enable_preemption(void)
{
extern void kernel_preempt_check (void);
register int idx = (int)&((cpu_data_t *)0)->preemption_level;
register void (*kpc)(void)= kernel_preempt_check;
assert(get_preemption_level() > 0);
__asm__ volatile ("decl %%gs:(%0); jne 1f; \
call %1; 1:"
:
: "r" (idx), "r" (kpc)
: "%eax", "%ecx", "%edx", "cc", "memory");
}
extern void __inline__ enable_preemption_no_check(void)
{
register int idx = (int)&((cpu_data_t *)0)->preemption_level;
assert(get_preemption_level() > 0);
__asm__ volatile ("decl %%gs:(%0)"
:
: "r" (idx)
: "cc", "memory");
}
extern void __inline__ mp_disable_preemption(void)
{
#if NCPUS > 1
disable_preemption();
#endif
}
extern void __inline__ mp_enable_preemption(void)
{
#if NCPUS > 1
enable_preemption();
#endif
}
extern void __inline__ mp_enable_preemption_no_check(void)
{
#if NCPUS > 1
enable_preemption_no_check();
#endif
}
#if 0
#ifndef __OPTIMIZE__
#undef extern
#endif
#endif
#else
#endif
#endif