1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-10 05:03:06 +03:00

hurd: Add THREAD_GET/SETMEM/_NC

Store them in the TCB, and use them for accessing _hurd_sigstate.
This commit is contained in:
Samuel Thibault
2020-02-15 05:04:02 -08:00
parent fe66db99f4
commit b65a82e4e7
2 changed files with 114 additions and 5 deletions

View File

@@ -164,9 +164,9 @@ extern void _hurd_sigstate_delete (thread_t thread);
_HURD_SIGNAL_H_EXTERN_INLINE struct hurd_sigstate * _HURD_SIGNAL_H_EXTERN_INLINE struct hurd_sigstate *
_hurd_self_sigstate (void) _hurd_self_sigstate (void)
{ {
if (THREAD_SELF->_hurd_sigstate == NULL) if (THREAD_GETMEM (THREAD_SELF, _hurd_sigstate) == NULL)
THREAD_SELF->_hurd_sigstate = _hurd_thread_sigstate (__mach_thread_self ()); THREAD_SETMEM (THREAD_SELF, _hurd_sigstate, _hurd_thread_sigstate (__mach_thread_self ()));
return THREAD_SELF->_hurd_sigstate; return THREAD_GETMEM (THREAD_SELF, _hurd_sigstate);
} }
# endif # endif
#endif #endif
@@ -210,14 +210,15 @@ _hurd_critical_section_lock (void)
return NULL; return NULL;
#endif #endif
ss = THREAD_SELF->_hurd_sigstate; ss = THREAD_GETMEM (THREAD_SELF, _hurd_sigstate);
if (ss == NULL) if (ss == NULL)
{ {
/* The thread variable is unset; this must be the first time we've /* The thread variable is unset; this must be the first time we've
asked for it. In this case, the critical section flag cannot asked for it. In this case, the critical section flag cannot
possible already be set. Look up our sigstate structure the slow possible already be set. Look up our sigstate structure the slow
way. */ way. */
ss = THREAD_SELF->_hurd_sigstate = _hurd_thread_sigstate (__mach_thread_self ()); ss = _hurd_thread_sigstate (__mach_thread_self ());
THREAD_SETMEM(THREAD_SELF, _hurd_sigstate, ss);
} }
if (! __spin_try_lock (&ss->critical_section_lock)) if (! __spin_try_lock (&ss->critical_section_lock))

View File

@@ -163,6 +163,114 @@ out:
: "i" (offsetof (tcbhead_t, tcb))); \ : "i" (offsetof (tcbhead_t, tcb))); \
__tcb;}) __tcb;})
/* Read member of the thread descriptor directly. */
# define THREAD_GETMEM(descr, member) \
({ __typeof (descr->member) __value; \
if (sizeof (__value) == 1) \
asm volatile ("movb %%gs:%P2,%b0" \
: "=q" (__value) \
: "0" (0), "i" (offsetof (tcbhead_t, member))); \
else if (sizeof (__value) == 4) \
asm volatile ("movl %%gs:%P1,%0" \
: "=r" (__value) \
: "i" (offsetof (tcbhead_t, member))); \
else \
{ \
if (sizeof (__value) != 8) \
/* There should not be any value with a size other than 1, \
4 or 8. */ \
abort (); \
\
asm volatile ("movl %%gs:%P1,%%eax\n\t" \
"movl %%gs:%P2,%%edx" \
: "=A" (__value) \
: "i" (offsetof (tcbhead_t, member)), \
"i" (offsetof (tcbhead_t, member) + 4)); \
} \
__value; })
/* Same as THREAD_GETMEM, but the member offset can be non-constant. */
# define THREAD_GETMEM_NC(descr, member, idx) \
({ __typeof (descr->member[0]) __value; \
if (sizeof (__value) == 1) \
asm volatile ("movb %%gs:%P2(%3),%b0" \
: "=q" (__value) \
: "0" (0), "i" (offsetof (tcbhead_t, member[0])), \
"r" (idx)); \
else if (sizeof (__value) == 4) \
asm volatile ("movl %%gs:%P1(,%2,4),%0" \
: "=r" (__value) \
: "i" (offsetof (tcbhead_t, member[0])), \
"r" (idx)); \
else \
{ \
if (sizeof (__value) != 8) \
/* There should not be any value with a size other than 1, \
4 or 8. */ \
abort (); \
\
asm volatile ("movl %%gs:%P1(,%2,8),%%eax\n\t" \
"movl %%gs:4+%P1(,%2,8),%%edx" \
: "=&A" (__value) \
: "i" (offsetof (tcbhead_t, member[0])), \
"r" (idx)); \
} \
__value; })
/* Set member of the thread descriptor directly. */
# define THREAD_SETMEM(descr, member, value) \
({ if (sizeof (descr->member) == 1) \
asm volatile ("movb %b0,%%gs:%P1" : \
: "iq" (value), \
"i" (offsetof (tcbhead_t, member))); \
else if (sizeof (descr->member) == 4) \
asm volatile ("movl %0,%%gs:%P1" : \
: "ir" (value), \
"i" (offsetof (tcbhead_t, member))); \
else \
{ \
if (sizeof (descr->member) != 8) \
/* There should not be any value with a size other than 1, \
4 or 8. */ \
abort (); \
\
asm volatile ("movl %%eax,%%gs:%P1\n\t" \
"movl %%edx,%%gs:%P2" : \
: "A" ((uint64_t) cast_to_integer (value)), \
"i" (offsetof (tcbhead_t, member)), \
"i" (offsetof (tcbhead_t, member) + 4)); \
}})
/* Same as THREAD_SETMEM, but the member offset can be non-constant. */
# define THREAD_SETMEM_NC(descr, member, idx, value) \
({ if (sizeof (descr->member[0]) == 1) \
asm volatile ("movb %b0,%%gs:%P1(%2)" : \
: "iq" (value), \
"i" (offsetof (tcbhead_t, member)), \
"r" (idx)); \
else if (sizeof (descr->member[0]) == 4) \
asm volatile ("movl %0,%%gs:%P1(,%2,4)" : \
: "ir" (value), \
"i" (offsetof (tcbhead_t, member)), \
"r" (idx)); \
else \
{ \
if (sizeof (descr->member[0]) != 8) \
/* There should not be any value with a size other than 1, \
4 or 8. */ \
abort (); \
\
asm volatile ("movl %%eax,%%gs:%P1(,%2,8)\n\t" \
"movl %%edx,%%gs:4+%P1(,%2,8)" : \
: "A" ((uint64_t) cast_to_integer (value)), \
"i" (offsetof (tcbhead_t, member)), \
"r" (idx)); \
}})
/* Return the TCB address of a thread given its state. /* Return the TCB address of a thread given its state.
Note: this is expensive. */ Note: this is expensive. */
# define THREAD_TCB(thread, thread_state) \ # define THREAD_TCB(thread, thread_state) \