X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Fppc-arch.c;h=281de3c48bb3ebdc2484ba97f837e5de3989ab72;hb=cd1b14acf6f548b28b8a14e554d779f0473122ec;hp=bdd1a402359885b9c6b9421dfd9df94801bda907;hpb=716153dd41af2df6ad91939fb3dcf0ba99cd72cf;p=sbcl.git diff --git a/src/runtime/ppc-arch.c b/src/runtime/ppc-arch.c index bdd1a40..281de3c 100644 --- a/src/runtime/ppc-arch.c +++ b/src/runtime/ppc-arch.c @@ -28,6 +28,10 @@ #include "gencgc-alloc-region.h" #endif +#ifdef LISP_FEATURE_SB_THREAD +#include "pseudo-atomic.h" +#endif + /* The header files may not define PT_DAR/PT_DSISR. This definition is correct for all versions of ppc linux >= 2.0.30 @@ -89,6 +93,13 @@ arch_internal_error_arguments(os_context_t *context) boolean arch_pseudo_atomic_atomic(os_context_t *context) { +#ifdef LISP_FEATURE_SB_THREAD + struct thread *thread = arch_os_get_current_thread(); + + if (foreign_function_call_active_p(thread)) { + return get_pseudo_atomic_atomic(thread); + } else return +#else /* FIXME: this foreign_function_call_active test is dubious at * best. If a foreign call is made in a pseudo atomic section * (?) or more likely a pseudo atomic section is in a foreign @@ -99,20 +110,37 @@ arch_pseudo_atomic_atomic(os_context_t *context) * The foreign_function_call_active used to live at each call-site * to arch_pseudo_atomic_atomic, but this seems clearer. * --NS 2007-05-15 */ - return (!foreign_function_call_active_p(arch_os_get_current_thread())) - && ((*os_context_register_addr(context,reg_ALLOC)) & 4); + return (!foreign_function_call_active_p(arch_os_get_current_thread())) && +#endif + ((*os_context_register_addr(context,reg_ALLOC)) & flag_PseudoAtomic); } void arch_set_pseudo_atomic_interrupted(os_context_t *context) { - *os_context_register_addr(context,reg_ALLOC) |= 1; +#ifdef LISP_FEATURE_SB_THREAD + struct thread *thread = arch_os_get_current_thread(); + + if (foreign_function_call_active_p(thread)) { + set_pseudo_atomic_interrupted(thread); + } else +#endif + *os_context_register_addr(context,reg_ALLOC) + |= flag_PseudoAtomicInterrupted; } void arch_clear_pseudo_atomic_interrupted(os_context_t *context) { - *os_context_register_addr(context,reg_ALLOC) &= ~1; +#ifdef LISP_FEATURE_SB_THREAD + struct thread *thread = arch_os_get_current_thread(); + + if (foreign_function_call_active_p(thread)) { + clear_pseudo_atomic_interrupted(thread); + } else +#endif + *os_context_register_addr(context,reg_ALLOC) + &= ~flag_PseudoAtomicInterrupted; } unsigned int @@ -272,15 +300,15 @@ allocation_trap_p(os_context_t * context) && (4 == ((inst >> 1) & 0x3ff))) { /* * We got the instruction. Now, look back to make sure it was - * proceeded by what we expected. 2 instructions back should be - * an ADD or ADDI instruction. + * proceeded by what we expected. The previous instruction + * should be an ADD or ADDI instruction. */ unsigned int add_inst; - add_inst = pc[-3]; + add_inst = pc[-1]; #if 0 fprintf(stderr, " add inst at %p: inst = 0x%08x\n", - pc - 3, add_inst); + pc - 1, add_inst); #endif opcode = add_inst >> 26; if ((opcode == 31) && (266 == ((add_inst >> 1) & 0x1ff))) { @@ -361,7 +389,7 @@ handle_allocation_trap(os_context_t * context) * is the size of the allocation. Get it and call alloc to allocate * new space. */ - inst = pc[-3]; + inst = pc[-1]; opcode = inst >> 26; #if 0 fprintf(stderr, " add inst = 0x%08x, opcode = %d\n", inst, opcode); @@ -450,15 +478,28 @@ handle_allocation_trap(os_context_t * context) #endif *os_context_register_addr(context, target) = (unsigned long) memory; +#ifndef LISP_FEATURE_SB_THREAD + /* This is handled by the fake_foreign_function_call machinery on + * threaded targets. */ *os_context_register_addr(context, reg_ALLOC) = (unsigned long) dynamic_space_free_pointer | (*os_context_register_addr(context, reg_ALLOC) & LOWTAG_MASK); +#endif if (were_in_lisp) { undo_fake_foreign_function_call(context); } + /* Skip the allocation trap and the write of the updated free + * pointer back to the allocation region. This is two + * instructions when threading is enabled and four instructions + * otherwise. */ +#ifdef LISP_FEATURE_SB_THREAD + (*os_context_pc_addr(context)) = pc + 2; +#else + (*os_context_pc_addr(context)) = pc + 4; +#endif } #endif @@ -518,7 +559,6 @@ sigtrap_handler(int signal, siginfo_t *siginfo, os_context_t *context) /* Is this an allocation trap? */ if (allocation_trap_p(context)) { handle_allocation_trap(context); - arch_skip_instruction(context); return; } #endif