Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Changeset 1314

Show
Ignore:
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
  • trunk/patches/Thread.d

    r1283 r1314  
    12631263            if( t.prev ) 
    12641264                t.prev.next = t.next; 
     1265 
    12651266            if( t.next ) 
    12661267                t.next.prev = t.prev; 
     1268 
    12671269            if( sm_tbeg == t ) 
    12681270                sm_tbeg = t.next; 
     
    20052007    } 
    20062008} 
     2009else version ( PPC ) 
     2010{ 
     2011    version( GNU ) 
     2012    { 
     2013        version( darwin ) 
     2014            version = AsmPPC_Posix_GDC; 
     2015    } 
     2016} 
    20072017 
    20082018 
     
    20142024    version( AsmX86_Linux ) {} else 
    20152025    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 
    20162035    version( X86_64 ) {} else 
    20172036    version( X86 ) 
     
    21362155class Fiber 
    21372156{ 
    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; 
    21392161 
    21402162 
     
    23782400        } 
    23792401    } 
    2380  
    23812402 
    23822403private: 
     
    25082529        else version( Posix ) 
    25092530        { 
     2531            // Mik: mmap does not work on OS X. 
    25102532        version( darwin ) 
    25112533        { 
    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               } 
    25132544        } 
    25142545        else 
     
    25202551                               0, 
    25212552                               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               } 
    25282559            } 
    25292560 
     
    25652596    else version( darwin ) 
    25662597    { 
    2567        free( m_pmem ); 
     2598            free( m_pmem ); 
    25682599    } 
    25692600        else version( Posix ) 
     
    25872618        void* pstack = m_ctxt.tstack; 
    25882619        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        } 
    25892627 
    25902628        void push( size_t val ) 
     
    26362674            push( 0x00000000 );                                     // EDI 
    26372675        } 
    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
    26392677        else version( AsmX86_Posix_GDC ) 
    26402678        { 
    26412679            push( cast(size_t) &fiber_entryPoint );             // EIP 
    26422680            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); 
    26432713        } 
    26442714        else version( JmpX86_Posix ) 
     
    27352805        tobj.pushContext( &m_ctxt ); 
    27362806 
    2737         doSwitch( *oldp, newp ); 
     2807        doSwitch( oldp, newp ); 
    27382808 
    27392809        // NOTE: As above, these operations must be performed in a strict order 
     
    27682838        volatile tobj.m_lock = true; 
    27692839 
    2770         doSwitch( *oldp, newp ); 
     2840        doSwitch( oldp, newp ); 
    27712841 
    27722842        // NOTE: As above, these operations must be performed in a strict order 
     
    27822852    // data will also be saved. 
    27832853    // 
    2784     final void doSwitch( inout void* oldp, void* newp ) 
     2854    final void doSwitch( void** oldp, void* newp ) 
    27852855    { 
    27862856        // NOTE: The data pushed and popped in this routine must match the 
     
    28682938                push EBP; 
    28692939                mov  EBP, ESP; 
     2940        push ESI; 
     2941        push EDI; 
     2942        push EBX; 
     2943        push EAX; 
    28702944                 
    28712945                // Swap stack pointers 
     
    28752949 
    28762950                // Load old frame pointer 
     2951        pop EAX; 
     2952        pop EBX; 
     2953        pop EDI; 
     2954        pop ESI; 
    28772955                pop EBP; 
    28782956 
     
    28812959            } 
    28822960        } 
     2961        else version( AsmPPC_Posix_GDC) 
     2962        { 
     2963            doSwitchASM(oldp, newp); 
     2964        } 
    28832965        else version( JmpX86_Posix ) 
    28842966        { 
    28852967            sigjmp_buf buf = void; 
    2886             oldp    = &buf; 
     2968            *oldp    = &buf; 
    28872969            // Basically, oldp will be the address of the current sigjmp_buf 
    28882970            // and newp will be the address of the new sigjmp_buf. This means 
    28892971            // that tstack will effectively point to a sigjmp_buf if the 
    28902972            // 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 ) ) 
    28922974                siglongjmp( *(cast(sigjmp_buf*) newp), 1 ); 
    28932975        } 
    28942976    } 
    28952977} 
     2978 
     2979