Date: Sat, 20 Nov 2004 09:17:43 GMT From: David Xu <davidxu@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 65542 for review Message-ID: <200411200917.iAK9HhB9028768@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=65542 Change 65542 by davidxu@davidxu_alona on 2004/11/20 09:17:36 ia64 port. Affected files ... .. //depot/projects/davidxu_thread/src/lib/libthread/arch/ia64/ia64/pthread_md.c#2 edit .. //depot/projects/davidxu_thread/src/lib/libthread/arch/ia64/include/pthread_md.h#2 edit Differences ... ==== //depot/projects/davidxu_thread/src/lib/libthread/arch/ia64/ia64/pthread_md.c#2 (text+ko) ==== @@ -1,5 +1,6 @@ /* * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org> + * Copyright (c) 2005 David Xu <davidxu@freebsd.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,7 +28,8 @@ */ #include <stdlib.h> -#include <strings.h> +#include <sys/types.h> +#include "rtld_tls.h" #include "pthread_md.h" /* @@ -37,39 +39,33 @@ _tcb_ctor(struct pthread *thread, int initial) { struct tcb *tcb; + void *oldtls; - if ((tcb = malloc(sizeof(struct tcb))) != NULL) { - bzero(tcb, sizeof(struct tcb)); - tcb->tcb_thread = thread; - /* Allocate TDV */ + if (initial) + oldtls = _tp; + else + oldtls = NULL; + +#if 1 + if ((tcb = malloc(sizeof(struct tcb))) != NULL) { + tcb->tcb_tdv = 0; + tcb->tcb_thread = thread; + } +#else + tcb = _rtld_allocate_tls(oldtls, sizeof(struct tcb), 16); + if (tcb) { + tcb->tcb_thread = thread; } +#endif return (tcb); } void _tcb_dtor(struct tcb *tcb) { - /* Free TDV */ +#if 1 free(tcb); -} - -struct kcb * -_kcb_ctor(struct kse *kse) -{ - struct kcb *kcb; - - if ((kcb = malloc(sizeof(struct kcb))) != NULL) { - bzero(kcb, sizeof(struct kcb)); - kcb->kcb_faketcb.tcb_isfake = 1; - kcb->kcb_faketcb.tcb_tmbx.tm_flags = TMF_NOUPCALL; - kcb->kcb_curtcb = &kcb->kcb_faketcb; - kcb->kcb_kse = kse; - } - return (kcb); -} - -void -_kcb_dtor(struct kcb *kcb) -{ - free(kcb); +#else + _rtld_free_tls(tcb, sizeof(tcb), 16); +#endif } ==== //depot/projects/davidxu_thread/src/lib/libthread/arch/ia64/include/pthread_md.h#2 (text+ko) ==== @@ -29,224 +29,50 @@ #ifndef _PTHREAD_MD_H_ #define _PTHREAD_MD_H_ -#include <sys/kse.h> #include <stddef.h> -#include <ucontext.h> -#define KSE_STACKSIZE 16384 #define DTV_OFFSET offsetof(struct tcb, tcb_tp.tp_tdv) -#define THR_GETCONTEXT(ucp) _ia64_save_context(&(ucp)->uc_mcontext) -#define THR_SETCONTEXT(ucp) PANIC("THR_SETCONTEXT() now in use!\n") - -#define PER_THREAD - -struct kcb; -struct kse; struct pthread; struct tcb; struct tdv; /* We don't know what this is yet? */ -/* - * tp points to one of these. We define the static TLS as an array - * of long double to enforce 16-byte alignment of the TLS memory, - * struct ia64_tp, struct tcb and also struct kcb. Both static and - * dynamic allocation of any of these structures will result in a - * valid, well-aligned thread pointer. - */ -struct ia64_tp { - struct tdv *tp_tdv; /* dynamic TLS */ - uint64_t _reserved_; - long double tp_tls[0]; /* static TLS */ -}; - struct tcb { - struct kse_thr_mailbox tcb_tmbx; + struct tdv *tcb_tdv; /* dynamic TLS */ struct pthread *tcb_thread; - struct kcb *tcb_curkcb; - long tcb_isfake; - struct ia64_tp tcb_tp; }; -struct kcb { - struct kse_mailbox kcb_kmbx; - struct tcb kcb_faketcb; - struct tcb *kcb_curtcb; - struct kse *kcb_kse; -}; +register struct tcb *_tp __asm("%r13"); -register struct ia64_tp *_tp __asm("%r13"); +#define _tcb _tp -#define _tcb ((struct tcb*)((char*)(_tp) - offsetof(struct tcb, tcb_tp))) - /* - * The kcb and tcb constructors. + * The tcb constructors. */ struct tcb *_tcb_ctor(struct pthread *, int); void _tcb_dtor(struct tcb *); -struct kcb *_kcb_ctor(struct kse *kse); -void _kcb_dtor(struct kcb *); /* Called from the KSE to set its private data. */ static __inline void -_kcb_set(struct kcb *kcb) +_tcb_set(struct tcb *tcb) { - /* There is no thread yet; use the fake tcb. */ - _tp = &kcb->kcb_faketcb.tcb_tp; -} - -/* - * Get the current kcb. - * - * This can only be called while in a critical region; don't - * worry about having the kcb changed out from under us. - */ -static __inline struct kcb * -_kcb_get(void) -{ - return (_tcb->tcb_curkcb); -} - -/* - * Enter a critical region. - * - * Read and clear km_curthread in the kse mailbox. - */ -static __inline struct kse_thr_mailbox * -_kcb_critical_enter(void) -{ - struct kse_thr_mailbox *crit; - uint32_t flags; - - 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; - } - return (crit); -} - -static __inline void -_kcb_critical_leave(struct kse_thr_mailbox *crit) -{ - /* No need to do anything if this is a fake tcb. */ - if (_tcb->tcb_isfake == 0) - _tcb->tcb_curkcb->kcb_kmbx.km_curthread = crit; -} - -static __inline int -_kcb_in_critical(void) -{ - uint32_t flags; - int ret; - - 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; - } - return (ret); + _tp = tcb; } -static __inline void -_tcb_set(struct kcb *kcb, struct tcb *tcb) -{ - 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 (_tcb); } +extern int _thread_inited; + static __inline struct pthread * _get_curthread(void) { - return (_tcb->tcb_thread); -} - -/* - * Get the current kse. - * - * Like _kcb_get(), this can only be called while in a critical region. - */ -static __inline struct kse * -_get_curkse(void) -{ - return (_tcb->tcb_curkcb->kcb_kse); -} - -void _ia64_break_setcontext(mcontext_t *mc); -void _ia64_enter_uts(kse_func_t uts, struct kse_mailbox *km, void *stack, - size_t stacksz); -int _ia64_restore_context(mcontext_t *mc, intptr_t val, intptr_t *loc); -int _ia64_save_context(mcontext_t *mc); - -static __inline int -_thread_enter_uts(struct tcb *tcb, struct kcb *kcb) -{ - if (_ia64_save_context(&tcb->tcb_tmbx.tm_context.uc_mcontext) == 0) { - /* Make the fake tcb the current thread. */ - kcb->kcb_curtcb = &kcb->kcb_faketcb; - _tp = &kcb->kcb_faketcb.tcb_tp; - _ia64_enter_uts(kcb->kcb_kmbx.km_func, &kcb->kcb_kmbx, - kcb->kcb_kmbx.km_stack.ss_sp, - kcb->kcb_kmbx.km_stack.ss_size); - /* We should not reach here. */ - return (-1); - } - return (0); -} - -static __inline int -_thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox) -{ - mcontext_t *mc; - - _tcb_set(kcb, tcb); - mc = &tcb->tcb_tmbx.tm_context.uc_mcontext; - if (mc->mc_flags & _MC_FLAGS_ASYNC_CONTEXT) { - if (setmbox) { - mc->mc_flags |= _MC_FLAGS_KSE_SET_MBOX; - mc->mc_special.ifa = - (intptr_t)&kcb->kcb_kmbx.km_curthread; - mc->mc_special.isr = (intptr_t)&tcb->tcb_tmbx; - } - _ia64_break_setcontext(mc); - } else if (mc->mc_flags & _MC_FLAGS_SYSCALL_CONTEXT) { - if (setmbox) - kse_switchin(&tcb->tcb_tmbx, KSE_SWITCHIN_SETTMBX); - else - kse_switchin(&tcb->tcb_tmbx, 0); - } else { - if (setmbox) - _ia64_restore_context(mc, (intptr_t)&tcb->tcb_tmbx, - (intptr_t *)&kcb->kcb_kmbx.km_curthread); - else - _ia64_restore_context(mc, 0, NULL); - } - /* We should not reach here. */ - return (-1); + if (_thread_inited) + return (_tcb->tcb_thread); + return (NULL); } #endif /* _PTHREAD_MD_H_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200411200917.iAK9HhB9028768>