Changeset eb2e723


Ignore:
Timestamp:
Jan 19, 2017, 2:42:49 PM (7 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
35dd180f
Parents:
2175062
Message:

First prototype of kernel with proper startup and shutdown, not yet implemented for i386

Location:
src
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixGlobalInit.cc

    r2175062 reb2e723  
    8484                        // for library code are run before constructors and destructors for user code,
    8585                        // specify a priority when building the library. Priorities 0-100 are reserved by gcc.
    86                         ctorParameters.push_back( new ConstantExpr( Constant::from_int( 101 ) ) );
    87                         dtorParameters.push_back( new ConstantExpr( Constant::from_int( 101 ) ) );
     86                        ctorParameters.push_back( new ConstantExpr( Constant::from_int( 102 ) ) );
     87                        dtorParameters.push_back( new ConstantExpr( Constant::from_int( 102 ) ) );
    8888                }
    8989                initFunction = new FunctionDecl( "_init_" + fixedName, DeclarationNode::Static, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false );
  • src/examples/thread.c

    r2175062 reb2e723  
    1 #include <kernel>
     1// #include <kernel>
    22#include <stdlib>
    33#include <threads>
    44
    5 // Start coroutine routines
    6 extern "C" {
    7       forall(dtype T | is_coroutine(T))
    8       void CtxInvokeCoroutine(T * this);
     5// // Start coroutine routines
     6// extern "C" {
     7//       forall(dtype T | is_coroutine(T))
     8//       void CtxInvokeCoroutine(T * this);
    99
    10       forall(dtype T | is_coroutine(T))
    11       void CtxStart(T * this, void ( *invoke)(T *));
     10//       forall(dtype T | is_coroutine(T))
     11//       void CtxStart(T * this, void ( *invoke)(T *));
    1212
    13         forall(dtype T | is_coroutine(T))
    14       void CtxInvokeThread(T * this);
    15 }
     13//      forall(dtype T | is_coroutine(T))
     14//       void CtxInvokeThread(T * this);
     15// }
    1616
    17 struct MyThread {
    18         thread_h t;
    19         unsigned id;
    20         unsigned count;
    21 };
     17// struct MyThread {
     18//      thread_h t;
     19//      unsigned id;
     20//      unsigned count;
     21// };
    2222
    23 void ?{}( MyThread * this ) {
    24         this->id = 0;
    25         this->count = 10;
    26 }
     23// void ?{}( MyThread * this ) {
     24//      this->id = 0;
     25//      this->count = 10;
     26// }
    2727
    28 void ?{}( MyThread * this, unsigned id, unsigned count ) {
    29         this->id = id;
    30         this->count = count;
    31 }
     28// void ?{}( MyThread * this, unsigned id, unsigned count ) {
     29//      this->id = id;
     30//      this->count = count;
     31// }
    3232
    33 void ^?{}( MyThread * this ) {}
     33// void ^?{}( MyThread * this ) {}
    3434
    35 void main(MyThread* this) {
    36         printf("Main called with %p\n", this);
    37         printf("Thread %d : Suspending %d times\n", this->id, this->count);
     35// void main(MyThread* this) {
     36//      printf("Main called with %p\n", this);
     37//      printf("Thread %d : Suspending %d times\n", this->id, this->count);
    3838
    39         for(int i = 0; i < this->count; i++) {
    40                 printf("Thread %d : Suspend No. %d\n", this->id, i + 1);
    41                 printf("Back to %p\n", &this->t.c);
    42                 suspend();
    43         }
    44 }
     39//      for(int i = 0; i < this->count; i++) {
     40//              printf("Thread %d : Suspend No. %d\n", this->id, i + 1);
     41//              printf("Back to %p\n", &this->t.c);
     42//              suspend();
     43//      }
     44// }
    4545
    46 thread_h* get_thread(MyThread* this) {
    47         return &this->t;
    48 }
     46// thread_h* get_thread(MyThread* this) {
     47//      return &this->t;
     48// }
    4949
    50 coroutine* get_coroutine(MyThread* this) {
    51         return &this->t.c;
    52 }
     50// coroutine* get_coroutine(MyThread* this) {
     51//      return &this->t.c;
     52// }
    5353
    5454int main() {
     55        printf("Main is %p\n", this_coroutine());
    5556
    56         thread(MyThread) thread1;
    57         thread(MyThread) thread2;
     57        // thread(MyThread) thread1;
     58        // thread(MyThread) thread2;
    5859
    59         thread2.handle.id = 1;
     60        // thread2.handle.id = 1;
    6061
    61         printf("\n\nMain is %p\n", this_coroutine());
    6262
    63         kernel_run();
     63        // // kernel_run();
    6464
    65         printf("Kernel terminated correctly\n");
     65        // printf("Kernel terminated correctly\n");
    6666
    6767        return 0;
  • src/libcfa/concurrency/CtxSwitch-x86_64.S

    r2175062 reb2e723  
    8484        jmp *%r12
    8585
     86.text
     87        .align 2
     88.globl  CtxGet
     89CtxGet:
     90        movq %rsp,SP_OFFSET(%rdi)
     91        movq %rbp,FP_OFFSET(%rdi)
     92
     93        ret
     94
    8695// Local Variables: //
    8796// mode: c //
  • src/libcfa/concurrency/coroutines.c

    r2175062 reb2e723  
    3636static size_t pageSize = 0;                             // architecture pagesize HACK, should go in proper runtime singleton
    3737
    38 //Extra private desctructor for the main
    39 //FIXME the main should not actually allocate a stack
    40 //Since the main is never resumed the extra stack does not cause
    41 //any problem but it is wasted memory
    42 void ?{}(coStack_t* this, size_t size);
    43 void ?{}(coroutine* this, size_t size);
    44 
    45 //Main coroutine
    46 //FIXME do not construct a stack for the main
    47 coroutine main_coroutine = { 1000 };
    48 
    4938//Current coroutine
    5039//Will need to be in TLS when multi-threading is added
    51 coroutine* current_coroutine = &main_coroutine;
     40coroutine* current_coroutine;
    5241
    5342//-----------------------------------------------------------------------------
  • src/libcfa/concurrency/invoke.h

    r2175062 reb2e723  
    5252      // assembler routines that performs the context switch
    5353      extern void CtxInvokeStub( void );
    54       void CtxSwitch( void *from, void *to ) asm ("CtxSwitch");
     54      void CtxSwitch( void * from, void * to ) asm ("CtxSwitch");
     55      void CtxGet( void * this ) asm ("CtxGet");
    5556
    5657#endif //_INVOKE_PRIVATE_H_
  • src/libcfa/concurrency/kernel

    r2175062 reb2e723  
    2121
    2222struct processor {
    23         struct proc_coroutine * cor;
     23        struct processorCtx_t * ctx;
    2424        unsigned int thread_index;
    2525        unsigned int thread_count;
  • src/libcfa/concurrency/kernel.c

    r2175062 reb2e723  
    2020//C Includes
    2121#include <stddef.h>
     22extern "C" {
     23#include <sys/resource.h>
     24}
    2225
    2326//CFA Includes
     
    2932#include "invoke.h"
    3033
    31 processor systemProcessorStorage = {};
    32 processor * systemProcessor = &systemProcessorStorage;
     34processor * systemProcessor;
     35thread_h * mainThread;
     36
     37void kernel_startup(void)  __attribute__((constructor(101)));
     38void kernel_shutdown(void) __attribute__((destructor(101)));
    3339
    3440void ?{}(processor * this) {
    35         this->cor = NULL;
     41        this->ctx = NULL;
    3642        this->thread_index = 0;
    3743        this->thread_count = 10;
     
    5157//-----------------------------------------------------------------------------
    5258// Processor coroutine
    53 struct proc_coroutine {
     59struct processorCtx_t {
    5460        processor * proc;
    5561        coroutine c;
    5662};
    5763
    58 void ?{}(coroutine * this, processor * proc) {
    59         this{};
    60 }
    61 
    62 DECL_COROUTINE(proc_coroutine)
    63 
    64 void ?{}(proc_coroutine * this, processor * proc) {
    65         (&this->c){proc};
     64DECL_COROUTINE(processorCtx_t)
     65
     66void ?{}(processorCtx_t * this, processor * proc) {
     67        (&this->c){};
    6668        this->proc = proc;
    67         proc->cor = this;
    68 }
    69 
    70 void ^?{}(proc_coroutine * this) {
    71         ^(&this->c){};
    7269}
    7370
    7471void CtxInvokeProcessor(processor * proc) {
    75         proc_coroutine proc_cor_storage = {proc};
     72        processorCtx_t proc_cor_storage = {proc};
    7673        resume( &proc_cor_storage );
    7774}
     
    7976//-----------------------------------------------------------------------------
    8077// Processor running routines
    81 void main(proc_coroutine * cor);
     78void main(processorCtx_t * ctx);
    8279thread_h * nextThread(processor * this);
    8380void runThread(processor * this, thread_h * dst);
    8481void spin(processor * this, unsigned int * spin_count);
    8582
    86 void main(proc_coroutine * cor) {
    87         processor * this;
    88         this = cor->proc;
     83void main(processorCtx_t * ctx) {
     84        processor * this = ctx->proc;
     85        LIB_DEBUG_PRINTF("Kernel : core %p starting\n", this);
    8986
    9087        thread_h * readyThread = NULL;
     
    116113
    117114void runThread(processor * this, thread_h * dst) {
    118         coroutine * proc_ctx = get_coroutine(this->cor);
     115        coroutine * proc_ctx = get_coroutine(this->ctx);
    119116        coroutine * thrd_ctx = get_coroutine(dst);
    120117        thrd_ctx->last = proc_ctx;
     
    138135// Kernel runner (Temporary)
    139136
    140 void scheduler_add( struct thread_h * thrd ) {
     137void scheduler_add( thread_h * thrd ) {
    141138        LIB_DEBUG_PRINTF("Kernel : scheduling %p on core %p (%d spots)\n", thrd, systemProcessor, systemProcessor->thread_count);
    142139        for(int i = 0; i < systemProcessor->thread_count; i++) {
     
    149146}
    150147
    151 void scheduler_remove( struct thread_h * thrd ) {
     148void scheduler_remove( thread_h * thrd ) {
    152149        LIB_DEBUG_PRINTF("Kernel : unscheduling %p from core %p\n", thrd, systemProcessor);
    153150        for(int i = 0; i < systemProcessor->thread_count; i++) {
     
    162159                }
    163160        }
    164         LIB_DEBUG_PRINTF("Kernel : terminating core %p\n\n\n", systemProcessor);       
     161        LIB_DEBUG_PRINTF("Kernel : terminating core %p\n", systemProcessor);   
    165162        systemProcessor->terminated = true;
    166163}
    167164
    168 void kernel_run( void ) {
    169         CtxInvokeProcessor(systemProcessor);
     165//-----------------------------------------------------------------------------
     166// Kernel storage
     167#define KERNEL_STORAGE(T,X) static char X##_storage[sizeof(T)]
     168
     169KERNEL_STORAGE(processorCtx_t, systemProcessorCtx);
     170KERNEL_STORAGE(processor, systemProcessor);
     171KERNEL_STORAGE(thread_h, mainThread);
     172KERNEL_STORAGE(machine_context_t, mainThread_context);
     173
     174//-----------------------------------------------------------------------------
     175// Main thread construction
     176struct mainThread_info_t {
     177        machine_context_t ctx; 
     178        unsigned int size;              // size of stack
     179        void *base;                             // base of stack
     180        void *storage;                  // pointer to stack
     181        void *limit;                    // stack grows towards stack limit
     182        void *context;                  // address of cfa_context_t
     183        void *top;                              // address of top of storage
     184};
     185
     186void ?{}( mainThread_info_t * this ) {
     187        CtxGet( &this->ctx );
     188        this->base = this->ctx.FP;
     189        this->storage = this->ctx.SP;
     190
     191        rlimit r;
     192        int ret = getrlimit( RLIMIT_STACK, &r);
     193        this->size = r.rlim_cur;
     194
     195        this->limit = (void *)(((intptr_t)this->base) - this->size);
     196        this->context = &mainThread_context_storage;
     197        this->top = this->base;
     198}
     199
     200void ?{}( coStack_t * this, mainThread_info_t * info) {
     201        this->size = info->size;
     202        this->storage = info->storage;
     203        this->limit = info->limit;
     204        this->base = info->base;
     205        this->context = info->context;
     206        this->top = info->top;
     207        this->userStack = true;
     208}
     209
     210void ?{}( coroutine * this, mainThread_info_t * info) {
     211        (&this->stack){ info };
     212        this->name = "Main Thread";
     213        this->errno_ = 0;
     214        this->state = Inactive;
     215        this->notHalted = true;
     216}
     217
     218void ?{}( thread_h * this, mainThread_info_t * info) {
     219        (&this->c){ info };
     220}
     221
     222//-----------------------------------------------------------------------------
     223// Kernel boot procedures
     224void kernel_startup(void) {
     225
     226        // SKULLDUGGERY: the mainThread steals the process main thread
     227        // which will then be scheduled by the systemProcessor normally
     228        LIB_DEBUG_PRINTF("Kernel : Starting\n");       
     229
     230        mainThread_info_t ctx;
     231        LIB_DEBUG_PRINTF("Kernel :    base : %p\n", ctx.base );
     232        LIB_DEBUG_PRINTF("Kernel :     top : %p\n", ctx.top );
     233        LIB_DEBUG_PRINTF("Kernel :   limit : %p\n", ctx.limit );
     234        LIB_DEBUG_PRINTF("Kernel :    size : %x\n", ctx.size );
     235        LIB_DEBUG_PRINTF("Kernel : storage : %p\n", ctx.storage );
     236        LIB_DEBUG_PRINTF("Kernel : context : %p\n", ctx.context );
     237
     238        // Start by initializing the main thread
     239        mainThread = (thread_h *)&mainThread_storage;
     240        LIB_DEBUG_PRINTF("Kernel : Main thread : %p\n", mainThread );
     241        mainThread{ &ctx };
     242
     243        // // Initialize the system processor
     244        systemProcessor = (processor *)&systemProcessor_storage;
     245        systemProcessor{};
     246
     247        // Initialize the system processor ctx
     248        // (the coroutine that contains the processing control flow)
     249        systemProcessor->ctx = (processorCtx_t *)&systemProcessorCtx_storage;
     250        systemProcessor->ctx{ systemProcessor };
     251
     252        scheduler_add(mainThread);
     253
     254        current_coroutine = &mainThread->c;
     255
     256        LIB_DEBUG_PRINTF("Kernel : Starting system processor\n");       
     257        resume(systemProcessor->ctx);
     258
     259        LIB_DEBUG_PRINTF("Kernel : Started\n--------------------------------------------------\n\n");
     260}
     261void kernel_shutdown(void) {
     262        LIB_DEBUG_PRINTF("\n--------------------------------------------------\nKernel : Shutting down");
     263
     264        LIB_DEBUG_PRINTF("Unscheduling main thread\n");
     265        scheduler_remove(mainThread);
     266
     267        LIB_DEBUG_PRINTF("Suspending main\n");
     268        suspend();
     269
     270        LIB_DEBUG_PRINTF("Kernel : Control return to initial process thread\n");
     271
     272        ^(systemProcessor->ctx){};
     273        ^(systemProcessor){};
     274
     275        ^(mainThread){};
     276
     277        LIB_DEBUG_PRINTF("Kernel : Shutdown complete\n");       
    170278}
    171279
Note: See TracChangeset for help on using the changeset viewer.