From 37f3261fb03018506ca05c7138ca29512279f6dd Mon Sep 17 00:00:00 2001 From: marcel Date: Wed, 6 Aug 2003 04:17:42 +0000 Subject: Avoid a level of indirection to get from the thread pointer to the TCB. We know that the thread pointer points to &tcb->tcb_tp, so all we have to do is subtract offsetof(struct tcb, tcb_tp) from the thread pointer to get to the TCB. Any reasonably smart compiler will translate accesses to fields in the TCB as negative offsets from TP. In _tcb_set() make sure the fake TCB gets a pointer to the current KCB, just like any other TCB. This fixes a NULL-pointer dereference in _thr_ref_add() when it tried to get the current KSE. --- lib/libkse/arch/ia64/ia64/pthread_md.c | 2 - lib/libkse/arch/ia64/include/pthread_md.h | 64 +++++++++++++------------------ 2 files changed, 27 insertions(+), 39 deletions(-) (limited to 'lib/libkse/arch/ia64') diff --git a/lib/libkse/arch/ia64/ia64/pthread_md.c b/lib/libkse/arch/ia64/ia64/pthread_md.c index e8fd64e..c761185 100644 --- a/lib/libkse/arch/ia64/ia64/pthread_md.c +++ b/lib/libkse/arch/ia64/ia64/pthread_md.c @@ -41,7 +41,6 @@ _tcb_ctor(struct pthread *thread) if ((tcb = malloc(sizeof(struct tcb))) != NULL) { bzero(tcb, sizeof(struct tcb)); tcb->tcb_thread = thread; - tcb->tcb_tp.tp_self = tcb; /* Allocate TDV */ } return (tcb); @@ -63,7 +62,6 @@ _kcb_ctor(struct kse *kse) bzero(kcb, sizeof(struct kcb)); kcb->kcb_faketcb.tcb_isfake = 1; kcb->kcb_faketcb.tcb_tmbx.tm_flags = TMF_NOUPCALL; - kcb->kcb_faketcb.tcb_tp.tp_self = &kcb->kcb_faketcb; kcb->kcb_curtcb = &kcb->kcb_faketcb; kcb->kcb_kse = kse; } diff --git a/lib/libkse/arch/ia64/include/pthread_md.h b/lib/libkse/arch/ia64/include/pthread_md.h index 7b5c221..045cafa 100644 --- a/lib/libkse/arch/ia64/include/pthread_md.h +++ b/lib/libkse/arch/ia64/include/pthread_md.h @@ -30,6 +30,7 @@ #define _PTHREAD_MD_H_ #include +#include #include #define THR_GETCONTEXT(ucp) _ia64_save_context(&(ucp)->uc_mcontext) @@ -53,7 +54,7 @@ struct tdv; /* We don't know what this is yet? */ */ struct ia64_tp { struct tdv *tp_tdv; /* dynamic TLS */ - struct tcb *tp_self; + uint64_t _reserved_; long double tp_tls[0]; /* static TLS */ }; @@ -74,6 +75,8 @@ struct kcb { register struct ia64_tp *_tp __asm("%r13"); +#define _tcb ((struct tcb*)((char*)(_tp) - offsetof(struct tcb, tcb_tp))) + /* * The kcb and tcb constructors. */ @@ -99,7 +102,7 @@ _kcb_set(struct kcb *kcb) static __inline struct kcb * _kcb_get(void) { - return (_tp->tp_self->tcb_curkcb); + return (_tcb->tcb_curkcb); } /* @@ -111,22 +114,20 @@ static __inline struct kse_thr_mailbox * _kcb_critical_enter(void) { struct kse_thr_mailbox *crit; - struct tcb *tcb; uint32_t flags; - tcb = _tp->tp_self; - if (tcb->tcb_isfake != 0) { + if (_tcb->tcb_isfake != 0) { /* * We already are in a critical region since * there is no current thread. */ crit = NULL; } else { - flags = tcb->tcb_tmbx.tm_flags; - tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL; - crit = tcb->tcb_curkcb->kcb_kmbx.km_curthread; - tcb->tcb_curkcb->kcb_kmbx.km_curthread = NULL; - tcb->tcb_tmbx.tm_flags = flags; + flags = _tcb->tcb_tmbx.tm_flags; + _tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL; + crit = _tcb->tcb_curkcb->kcb_kmbx.km_curthread; + _tcb->tcb_curkcb->kcb_kmbx.km_curthread = NULL; + _tcb->tcb_tmbx.tm_flags = flags; } return (crit); } @@ -134,33 +135,28 @@ _kcb_critical_enter(void) static __inline void _kcb_critical_leave(struct kse_thr_mailbox *crit) { - struct tcb *tcb; - - tcb = _tp->tp_self; /* No need to do anything if this is a fake tcb. */ - if (tcb->tcb_isfake == 0) - tcb->tcb_curkcb->kcb_kmbx.km_curthread = crit; + if (_tcb->tcb_isfake == 0) + _tcb->tcb_curkcb->kcb_kmbx.km_curthread = crit; } static __inline int _kcb_in_critical(void) { - struct tcb *tcb; uint32_t flags; int ret; - tcb = _tp->tp_self; - if (tcb->tcb_isfake != 0) { + if (_tcb->tcb_isfake != 0) { /* * We are in a critical region since there is no * current thread. */ ret = 1; } else { - flags = tcb->tcb_tmbx.tm_flags; - tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL; - ret = (tcb->tcb_curkcb->kcb_kmbx.km_curthread == NULL); - tcb->tcb_tmbx.tm_flags = flags; + flags = _tcb->tcb_tmbx.tm_flags; + _tcb->tcb_tmbx.tm_flags |= TMF_NOUPCALL; + ret = (_tcb->tcb_curkcb->kcb_kmbx.km_curthread == NULL); + _tcb->tcb_tmbx.tm_flags = flags; } return (ret); } @@ -168,27 +164,23 @@ _kcb_in_critical(void) static __inline void _tcb_set(struct kcb *kcb, struct tcb *tcb) { - if (tcb == NULL) { - kcb->kcb_curtcb = &kcb->kcb_faketcb; - _tp = &kcb->kcb_faketcb.tcb_tp; - } - else { - kcb->kcb_curtcb = tcb; - tcb->tcb_curkcb = kcb; - _tp = &tcb->tcb_tp; - } + if (tcb == NULL) + tcb = &kcb->kcb_faketcb; + kcb->kcb_curtcb = tcb; + tcb->tcb_curkcb = kcb; + _tp = &tcb->tcb_tp; } static __inline struct tcb * _tcb_get(void) { - return (_tp->tp_self); + return (_tcb); } static __inline struct pthread * _get_curthread(void) { - return (_tp->tp_self->tcb_thread); + return (_tcb->tcb_thread); } /* @@ -199,7 +191,7 @@ _get_curthread(void) static __inline struct kse * _get_curkse(void) { - return (_tp->tp_self->tcb_curkcb->kcb_kse); + return (_tcb->tcb_curkcb->kcb_kse); } void _ia64_enter_uts(kse_func_t uts, struct kse_mailbox *km, void *stack, @@ -226,9 +218,7 @@ _thread_enter_uts(struct tcb *tcb, struct kcb *kcb) static __inline int _thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox) { - kcb->kcb_curtcb = tcb; - tcb->tcb_curkcb = kcb; - _tp = &tcb->tcb_tp; + _tcb_set(kcb, tcb); if (setmbox != 0) _ia64_restore_context(&tcb->tcb_tmbx.tm_context.uc_mcontext, (intptr_t)&tcb->tcb_tmbx, -- cgit v1.1