Index: pcpu.h =================================================================== --- pcpu.h (revision 261863) +++ pcpu.h (working copy) @@ -70,11 +70,82 @@ struct pcb; struct pcpu; -register struct pcb *curpcb __asm__(__XSTRING(PCB_REG)); -register struct pcpu *pcpup __asm__(__XSTRING(PCPU_REG)); +/* + * Evaluates to the byte offset of the per-cpu variable name. + */ +#define __pcpu_offset(name) \ + __offsetof(struct pcpu, name) -#define PCPU_GET(member) (pcpup->pc_ ## member) +/* + * Evaluates to the type of the per-cpu variable name. + */ +#define __pcpu_type(name) \ + __typeof(((struct pcpu *)0)->name) +#define __PCPU_GET(name) __extension__ ({ \ + __pcpu_type(name) __res; \ + \ + switch (sizeof(__res)) { \ + case 1: \ + __asm __volatile("ldub [%" __XSTRING(PCPU_REG) "+ %1], %0" \ + : "=r" (__res) : "i" (__pcpu_offset(name))); \ + break; \ + case 2: \ + __asm __volatile("lduh [%" __XSTRING(PCPU_REG) "+ %1], %0"\ + : "=r" (__res) : "i" (__pcpu_offset(name))); \ + break; \ + case 4: \ + __asm __volatile("ld [%" __XSTRING(PCPU_REG) "+ %1], %0"\ + : "=r" (__res) : "i" (__pcpu_offset(name))); \ + break; \ + case 8: \ + __asm __volatile("ldd [%" __XSTRING(PCPU_REG) "+ %1], %0"\ + : "=r" (__res) : "i" (__pcpu_offset(name))); \ + break; \ + default: \ + /* XXX - what to put here? */; \ + } \ + __res; \ + }) + +#define __PCPU_SET(name, val) __extension__ ({ \ + __pcpu_type(name) __val; \ + \ + __val = (val); \ + switch (sizeof(__val)) { \ + case 1: \ + __asm __volatile("stub %0, [%" __XSTRING(PCPU_REG) "+ %1]" \ + : : "r" (__val), "i" (__pcpu_offset(name))); \ + break; \ + case 2: \ + __asm __volatile("stuh %0, [%" __XSTRING(PCPU_REG) "+ %1]"\ + : : "r" (__val), "i" (__pcpu_offset(name))); \ + break; \ + case 4: \ + __asm __volatile("st %0, [%" __XSTRING(PCPU_REG) "+ %1]"\ + : : "r" (__val), "i" (__pcpu_offset(name))); \ + break; \ + case 8: \ + __asm __volatile("std %0, [%" __XSTRING(PCPU_REG) "+ %1]"\ + : : "r" (__val), "i" (__pcpu_offset(name))); \ + break; \ + default: \ + /* XXX - what to put here? */; \ + } \ + __val; \ + }) + +#define __PCPU_PTR(name) __extension__ ({ \ + __pcpu_type(name) *__p; \ + struct pcpu *__pcpu; \ + \ + __asm __volatile("mov %" __XSTRING(PCPU_REG) ", %0" \ + : "=r" (__pcpu)); \ + __p = &__pcpu->name; \ + \ + __p; \ +}) + static __inline __pure2 struct thread * __curthread(void) { @@ -89,10 +160,11 @@ * XXX The implementation of this operation should be made atomic * with respect to preemption. */ -#define PCPU_ADD(member, value) (pcpup->pc_ ## member += (value)) +#define PCPU_GET(member) __PCPU_GET(pc_ ## member) +#define PCPU_ADD(member, value) PCPU_SET(member, PCPU_GET(member) + (value)) #define PCPU_INC(member) PCPU_ADD(member, 1) -#define PCPU_PTR(member) (&pcpup->pc_ ## member) -#define PCPU_SET(member,value) (pcpup->pc_ ## member = (value)) +#define PCPU_PTR(member) __PCPU_PTR(pc_ ## member) +#define PCPU_SET(member,value) __PCPU_SET(pc_ ## member, (value)) #endif /* _KERNEL */