 |
Changeset 1314
- Timestamp:
- 01/15/07 15:40:30
(2 years ago)
- Author:
- mclysenk
- Message:
Added fiber support for the following targets via assembler:
Intel x86 OS X
PowerPC 32-bit OS X
Intel x86 Linux
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r1283 |
r1314 |
|
| 1263 | 1263 | if( t.prev ) |
|---|
| 1264 | 1264 | t.prev.next = t.next; |
|---|
| | 1265 | |
|---|
| 1265 | 1266 | if( t.next ) |
|---|
| 1266 | 1267 | t.next.prev = t.prev; |
|---|
| | 1268 | |
|---|
| 1267 | 1269 | if( sm_tbeg == t ) |
|---|
| 1268 | 1270 | sm_tbeg = t.next; |
|---|
| … | … | |
| 2005 | 2007 | } |
|---|
| 2006 | 2008 | } |
|---|
| | 2009 | else version ( PPC ) |
|---|
| | 2010 | { |
|---|
| | 2011 | version( GNU ) |
|---|
| | 2012 | { |
|---|
| | 2013 | version( darwin ) |
|---|
| | 2014 | version = AsmPPC_Posix_GDC; |
|---|
| | 2015 | } |
|---|
| | 2016 | } |
|---|
| 2007 | 2017 | |
|---|
| 2008 | 2018 | |
|---|
| … | … | |
| 2014 | 2024 | version( AsmX86_Linux ) {} else |
|---|
| 2015 | 2025 | version( AsmX86_Posix_GDC ) {} else |
|---|
| | 2026 | version( AsmPPC_Posix_GDC ) |
|---|
| | 2027 | { |
|---|
| | 2028 | // Mik: mmap does not work on OSX, so we use malloc instead |
|---|
| | 2029 | extern (C) size_t malloc_good_size(size_t); |
|---|
| | 2030 | extern (C) void* valloc(size_t size); |
|---|
| | 2031 | |
|---|
| | 2032 | // Mik: No inline assember, so we need external code |
|---|
| | 2033 | extern (C) void doSwitchASM(void**, void*); |
|---|
| | 2034 | } else |
|---|
| 2016 | 2035 | version( X86_64 ) {} else |
|---|
| 2017 | 2036 | version( X86 ) |
|---|
| … | … | |
| 2136 | 2155 | class Fiber |
|---|
| 2137 | 2156 | { |
|---|
| 2138 | | const size_t DEFAULT_STACKSIZE = 4096; |
|---|
| | 2157 | version ( PPC ) |
|---|
| | 2158 | const size_t DEFAULT_STACKSIZE = 8192; |
|---|
| | 2159 | else |
|---|
| | 2160 | const size_t DEFAULT_STACKSIZE = 4096; |
|---|
| 2139 | 2161 | |
|---|
| 2140 | 2162 | |
|---|
| … | … | |
| 2378 | 2400 | } |
|---|
| 2379 | 2401 | } |
|---|
| 2380 | | |
|---|
| 2381 | 2402 | |
|---|
| 2382 | 2403 | private: |
|---|
| … | … | |
| 2508 | 2529 | else version( Posix ) |
|---|
| 2509 | 2530 | { |
|---|
| | 2531 | // Mik: mmap does not work on OS X. |
|---|
| 2510 | 2532 | version( darwin ) |
|---|
| 2511 | 2533 | { |
|---|
| 2512 | | m_pmem = malloc(sz); |
|---|
| | 2534 | //Adjust size |
|---|
| | 2535 | sz = malloc_good_size(sz); |
|---|
| | 2536 | |
|---|
| | 2537 | //Perform allocation. |
|---|
| | 2538 | m_pmem = valloc(sz); |
|---|
| | 2539 | |
|---|
| | 2540 | if(m_pmem == null) |
|---|
| | 2541 | { |
|---|
| | 2542 | throw new FiberException( "Unable to allocate memory for stack" ); |
|---|
| | 2543 | } |
|---|
| 2513 | 2544 | } |
|---|
| 2514 | 2545 | else |
|---|
| … | … | |
| 2520 | 2551 | 0, |
|---|
| 2521 | 2552 | 0 ); |
|---|
| 2522 | | } |
|---|
| 2523 | | |
|---|
| 2524 | | if( m_pmem == MAP_FAILED ) |
|---|
| 2525 | | { |
|---|
| 2526 | | m_pmem = null; |
|---|
| 2527 | | throw new FiberException( "Unable to allocate memory for stack" ); |
|---|
| | 2553 | |
|---|
| | 2554 | if( m_pmem == MAP_FAILED ) |
|---|
| | 2555 | { |
|---|
| | 2556 | m_pmem = null; |
|---|
| | 2557 | throw new FiberException( "Unable to allocate memory for stack" ); |
|---|
| | 2558 | } |
|---|
| 2528 | 2559 | } |
|---|
| 2529 | 2560 | |
|---|
| … | … | |
| 2565 | 2596 | else version( darwin ) |
|---|
| 2566 | 2597 | { |
|---|
| 2567 | | free( m_pmem ); |
|---|
| | 2598 | free( m_pmem ); |
|---|
| 2568 | 2599 | } |
|---|
| 2569 | 2600 | else version( Posix ) |
|---|
| … | … | |
| 2587 | 2618 | void* pstack = m_ctxt.tstack; |
|---|
| 2588 | 2619 | scope( exit ) m_ctxt.tstack = pstack; |
|---|
| | 2620 | |
|---|
| | 2621 | // Mik: On OS X the stack must be 16-byte aligned according to the |
|---|
| | 2622 | // IA-32 call spec. |
|---|
| | 2623 | version( darwin ) |
|---|
| | 2624 | { |
|---|
| | 2625 | pstack = cast(void*)(cast(uint)(pstack) - (cast(uint)(pstack) & 0x0F)); |
|---|
| | 2626 | } |
|---|
| 2589 | 2627 | |
|---|
| 2590 | 2628 | void push( size_t val ) |
|---|
| … | … | |
| 2636 | 2674 | push( 0x00000000 ); // EDI |
|---|
| 2637 | 2675 | } |
|---|
| 2638 | | // Mik: Context does not have to store as much, since GDC uses the // simpler C calling convention. |
|---|
| | 2676 | // Mik: The same asm should work on all GDC-posix x86 targets. |
|---|
| 2639 | 2677 | else version( AsmX86_Posix_GDC ) |
|---|
| 2640 | 2678 | { |
|---|
| 2641 | 2679 | push( cast(size_t) &fiber_entryPoint ); // EIP |
|---|
| 2642 | 2680 | push( 0x00000000 ); // EBP |
|---|
| | 2681 | push( 0x00000000 ); // ESI |
|---|
| | 2682 | push( 0x00000000 ); // EDI |
|---|
| | 2683 | push( 0x00000000 ); // EBX |
|---|
| | 2684 | push( 0x00000000 ); // EAX |
|---|
| | 2685 | } |
|---|
| | 2686 | // Mik: Posix support for PowerPC architecture |
|---|
| | 2687 | else version( AsmPPC_Posix_GDC ) |
|---|
| | 2688 | { |
|---|
| | 2689 | version( StackGrowsDown ) |
|---|
| | 2690 | { |
|---|
| | 2691 | pstack -= int.sizeof * 5; |
|---|
| | 2692 | } |
|---|
| | 2693 | else |
|---|
| | 2694 | { |
|---|
| | 2695 | pstack += int.sizeof * 5; |
|---|
| | 2696 | } |
|---|
| | 2697 | |
|---|
| | 2698 | push( cast(size_t) &fiber_entryPoint ); // Link register |
|---|
| | 2699 | push( 0x00000000 ); // Control register |
|---|
| | 2700 | push( 0x00000000 ); // Old stack pointer |
|---|
| | 2701 | |
|---|
| | 2702 | //GPR values |
|---|
| | 2703 | version( StackGrowsDown ) |
|---|
| | 2704 | { |
|---|
| | 2705 | pstack -= int.sizeof * 20; |
|---|
| | 2706 | } |
|---|
| | 2707 | else |
|---|
| | 2708 | { |
|---|
| | 2709 | pstack += int.sizeof * 20; |
|---|
| | 2710 | } |
|---|
| | 2711 | |
|---|
| | 2712 | assert(cast(uint)pstack & 0x0f == 0); |
|---|
| 2643 | 2713 | } |
|---|
| 2644 | 2714 | else version( JmpX86_Posix ) |
|---|
| … | … | |
| 2735 | 2805 | tobj.pushContext( &m_ctxt ); |
|---|
| 2736 | 2806 | |
|---|
| 2737 | | doSwitch( *oldp, newp ); |
|---|
| | 2807 | doSwitch( oldp, newp ); |
|---|
| 2738 | 2808 | |
|---|
| 2739 | 2809 | // NOTE: As above, these operations must be performed in a strict order |
|---|
| … | … | |
| 2768 | 2838 | volatile tobj.m_lock = true; |
|---|
| 2769 | 2839 | |
|---|
| 2770 | | doSwitch( *oldp, newp ); |
|---|
| | 2840 | doSwitch( oldp, newp ); |
|---|
| 2771 | 2841 | |
|---|
| 2772 | 2842 | // NOTE: As above, these operations must be performed in a strict order |
|---|
| … | … | |
| 2782 | 2852 | // data will also be saved. |
|---|
| 2783 | 2853 | // |
|---|
| 2784 | | final void doSwitch( inout void* oldp, void* newp ) |
|---|
| | 2854 | final void doSwitch( void** oldp, void* newp ) |
|---|
| 2785 | 2855 | { |
|---|
| 2786 | 2856 | // NOTE: The data pushed and popped in this routine must match the |
|---|
| … | … | |
| 2868 | 2938 | push EBP; |
|---|
| 2869 | 2939 | mov EBP, ESP; |
|---|
| | 2940 | push ESI; |
|---|
| | 2941 | push EDI; |
|---|
| | 2942 | push EBX; |
|---|
| | 2943 | push EAX; |
|---|
| 2870 | 2944 | |
|---|
| 2871 | 2945 | // Swap stack pointers |
|---|
| … | … | |
| 2875 | 2949 | |
|---|
| 2876 | 2950 | // Load old frame pointer |
|---|
| | 2951 | pop EAX; |
|---|
| | 2952 | pop EBX; |
|---|
| | 2953 | pop EDI; |
|---|
| | 2954 | pop ESI; |
|---|
| 2877 | 2955 | pop EBP; |
|---|
| 2878 | 2956 | |
|---|
| … | … | |
| 2881 | 2959 | } |
|---|
| 2882 | 2960 | } |
|---|
| | 2961 | else version( AsmPPC_Posix_GDC) |
|---|
| | 2962 | { |
|---|
| | 2963 | doSwitchASM(oldp, newp); |
|---|
| | 2964 | } |
|---|
| 2883 | 2965 | else version( JmpX86_Posix ) |
|---|
| 2884 | 2966 | { |
|---|
| 2885 | 2967 | sigjmp_buf buf = void; |
|---|
| 2886 | | oldp = &buf; |
|---|
| | 2968 | *oldp = &buf; |
|---|
| 2887 | 2969 | // Basically, oldp will be the address of the current sigjmp_buf |
|---|
| 2888 | 2970 | // and newp will be the address of the new sigjmp_buf. This means |
|---|
| 2889 | 2971 | // that tstack will effectively point to a sigjmp_buf if the |
|---|
| 2890 | 2972 | // context has been swapped out via this Fiber code. |
|---|
| 2891 | | if( !sigsetjmp( *(cast(sigjmp_buf*) oldp), 0 ) ) |
|---|
| | 2973 | if( !sigsetjmp( *(cast(sigjmp_buf*) *oldp), 0 ) ) |
|---|
| 2892 | 2974 | siglongjmp( *(cast(sigjmp_buf*) newp), 1 ); |
|---|
| 2893 | 2975 | } |
|---|
| 2894 | 2976 | } |
|---|
| 2895 | 2977 | } |
|---|
| | 2978 | |
|---|
| | 2979 | |
|---|
Download in other formats:
|
 |
 |
|
 |
Copyright © 2006-2008 Tango. All Rights Reserved. | Page Width:
Static or
Dynamic