Changeset f019069


Ignore:
Timestamp:
May 6, 2019, 10:09:02 AM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
63364d8
Parents:
b9696a8
Message:

Some more work on suspend_then

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/CtxSwitch-x86_64.S

    rb9696a8 rf019069  
    100100        movq %rbp,FP_OFFSET(%rdi)
    101101
     102        mfence
     103
    102104        // Don't load a new context, directly jump to the desired function
    103 
    104         jmp *%rsi
     105#if defined(PIC)
     106        call __suspend_callback@plt
     107#else
     108        call __suspend_callback
     109#endif
    105110        .size  CtxStore, .-CtxStore
    106111
  • libcfa/src/concurrency/coroutine.cfa

    rb9696a8 rf019069  
    4040                abort();
    4141        }
     42
     43        extern void CtxRet( struct __stack_context_t * to ) asm ("CtxRet") __attribute__ ((__noreturn__));
    4244}
    4345
     
    203205                CoroutineCtxSwitch( src, starter );
    204206        }
     207
     208        __attribute__((noreturn)) void __suspend_callback( struct __stack_context_t *, fptr_t call ) {
     209                call();
     210
     211                coroutine_desc * src = TL_GET( this_thread )->curr_cor;
     212                // set state of current coroutine to inactive
     213                src->state = src->state == Halted ? Halted : Inactive;
     214
     215                TL_GET( this_thread )->curr_cor = src->last;
     216
     217                // context switch to specified coroutine
     218                assert( src->last->context.SP );
     219                CtxRet( &src->last->context );
     220
     221                abort();
     222        }
    205223}
    206224
  • libcfa/src/concurrency/coroutine.hfa

    rb9696a8 rf019069  
    6868
    6969        extern void CtxSwitch( struct __stack_context_t * from, struct __stack_context_t * to ) asm ("CtxSwitch");
    70         extern void CtxStore ( struct __stack_context_t * from, __attribute__((noreturn)) void (*__callback)(void) ) asm ("CtxStore");
    71         extern void CtxRet   ( struct __stack_context_t * to ) asm ("CtxRet") __attribute__ ((__noreturn__));
     70        extern void CtxStore ( struct __stack_context_t * from, fptr_t callback ) asm ("CtxStore");
    7271}
    7372
     
    172171}
    173172
     173__attribute__((noreturn)) void __suspend_callback(void *, fptr_t call);
     174
    174175static inline void suspend_then(fptr_t call) {
    175176        // optimization : read TLS once and reuse it
     
    194195      assert( src->context.SP );
    195196
    196         __attribute__((noreturn)) void __suspend_callback(void) {
    197                 call();
    198 
    199                 // set state of current coroutine to inactive
    200                 src->state = src->state == Halted ? Halted : Inactive;
    201 
    202                 TL_GET( this_thread )->curr_cor = src->last;
    203 
    204                 // context switch to specified coroutine
    205                 assert( src->last->context.SP );
    206                 CtxRet( &src->last->context );
    207 
    208                 abort();
    209         }
    210       CtxStore( &src->context, __suspend_callback );
     197      CtxStore( &src->context, call );
    211198        // when CtxStore returns we are back in the src coroutine
    212199
     
    220207        return;
    221208}
    222 
    223 // static inline void suspend_return(void) {
    224 //      // optimization : read TLS once and reuse it
    225 //      // Safety note: this is preemption safe since if
    226 //      // preemption occurs after this line, the pointer
    227 //      // will also migrate which means this value will
    228 //      // stay in syn with the TLS
    229 //      coroutine_desc * src = TL_GET( this_thread )->curr_cor;
    230 
    231 //      assertf( src->last != 0,
    232 //              "Attempt to suspend coroutine \"%.256s\" (%p) that has never been resumed.\n"
    233 //              "Possible cause is a suspend executed in a member called by a coroutine user rather than by the coroutine main.",
    234 //              src->name, src );
    235 //      assertf( src->last->state != Halted,
    236 //              "Attempt by coroutine \"%.256s\" (%p) to suspend back to terminated coroutine \"%.256s\" (%p).\n"
    237 //              "Possible cause is terminated coroutine's main routine has already returned.",
    238 //              src->name, src, src->last->name, src->last );
    239 
    240 //      // Safety note : Preemption must be disabled here since kernelTLS.this_coroutine must always be up to date
    241 //       verify( TL_GET( preemption_state.enabled ) || TL_GET( this_processor )->do_terminate );
    242 //       disable_interrupts();
    243 
    244 //       // set state of current coroutine to inactive
    245 //       src->state = src->state == Halted ? Halted : Inactive;
    246 
    247 //       // set new coroutine that task is executing
    248 //       kernelTLS.this_coroutine = dst;
    249 
    250 //       // context switch to specified coroutine
    251 //       assert( src->stack.context );
    252 //      CtxRet( src->stack.context );
    253 
    254 //      abort();
    255 // }
    256209
    257210// Local Variables: //
  • tests/concurrent/coroutineThen.cfa

    rb9696a8 rf019069  
    11#include <fstream.hfa>
    22#include <kernel.hfa>
     3#include <monitor.hfa>
     4#include <thread.hfa>
     5#include <time.hfa>
    36#include <stdlib.hfa>
    4 #include <thread.hfa>
    5 #include <monitor.hfa>
    6 #include <time.hfa>
     7#include <string.h>
    78
    89#define __kick_rate 150000ul
     
    2324#endif
    2425
    25 monitor Printer {};
    2626#if !defined(TEST_FOREVER)
    27         static inline void print(Printer & mutex this, const char * const text ) {
    28                 sout | text;
    29         }
    30 
    31         static inline void print(Printer & mutex this, const char * const text, int i ) {
    32                 sout | text | i;
     27        static inline void print(const char * const text ) {
     28                write( STDERR_FILENO, text, strlen(text) );
    3329        }
    3430#else
    3531        static inline void print(Printer & this, const char * const text ) {}
    36         static inline void print(Printer & this, const char * const text, int i ) {}
    3732#endif
    38 Printer printer;
    3933
    4034coroutine Coroutine {};
     
    5852        for(int i = 0; TEST(i < N); i++) {
    5953
    60                 print(printer, "Coroutine 1", i);
     54                print("C - Suspending");
    6155                void publish() {
     56                        print("C - Publishing");
    6257                        assert(!the_cor);
    6358                        store( this );
     
    6560                suspend_then(publish);
    6661                assert(!the_cor);
    67                 print(printer, "Coroutine 2");
     62                print("Coroutine 2");
    6863                KICK_WATCHDOG;
    6964                yield();
     
    8277                if(!mine) continue;
    8378
    84                 print(printer, "Thread 1");
     79                print("T - took");
    8580                resume(*mine);
    86                 print(printer, "Thread 2");
     81                print("T - back");
    8782        }
    8883}
Note: See TracChangeset for help on using the changeset viewer.