Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/kernel.hfa

    r431cd4f r454f478  
    2828}
    2929
     30//-----------------------------------------------------------------------------
     31// Underlying Locks
    3032#ifdef __CFA_WITH_VERIFY__
    3133        extern bool __cfaabi_dbg_in_kernel();
    3234#endif
    3335
    34 //-----------------------------------------------------------------------------
    35 // I/O
    36 struct cluster;
    37 struct $io_context;
    38 struct $io_arbiter;
    39 
    40 struct io_context_params {
    41         int num_entries;
    42 };
    43 
    44 void  ?{}(io_context_params & this);
     36extern "C" {
     37        char * strerror(int);
     38}
     39#define CHECKED(x) { int err = x; if( err != 0 ) abort("KERNEL ERROR: Operation \"" #x "\" return error %d - %s\n", err, strerror(err)); }
     40
     41struct __bin_sem_t {
     42        pthread_mutex_t         lock;
     43        pthread_cond_t          cond;
     44        int                     val;
     45};
     46
     47static inline void ?{}(__bin_sem_t & this) with( this ) {
     48        // Create the mutex with error checking
     49        pthread_mutexattr_t mattr;
     50        pthread_mutexattr_init( &mattr );
     51        pthread_mutexattr_settype( &mattr, PTHREAD_MUTEX_ERRORCHECK_NP);
     52        pthread_mutex_init(&lock, &mattr);
     53
     54        pthread_cond_init (&cond, (const pthread_condattr_t *)0p);  // workaround trac#208: cast should not be required
     55        val = 0;
     56}
     57
     58static inline void ^?{}(__bin_sem_t & this) with( this ) {
     59        CHECKED( pthread_mutex_destroy(&lock) );
     60        CHECKED( pthread_cond_destroy (&cond) );
     61}
     62
     63static inline void wait(__bin_sem_t & this) with( this ) {
     64        verify(__cfaabi_dbg_in_kernel());
     65        CHECKED( pthread_mutex_lock(&lock) );
     66                while(val < 1) {
     67                        pthread_cond_wait(&cond, &lock);
     68                }
     69                val -= 1;
     70        CHECKED( pthread_mutex_unlock(&lock) );
     71}
     72
     73static inline bool post(__bin_sem_t & this) with( this ) {
     74        bool needs_signal = false;
     75
     76        CHECKED( pthread_mutex_lock(&lock) );
     77                if(val < 1) {
     78                        val += 1;
     79                        pthread_cond_signal(&cond);
     80                        needs_signal = true;
     81                }
     82        CHECKED( pthread_mutex_unlock(&lock) );
     83
     84        return needs_signal;
     85}
     86
     87#undef CHECKED
     88
    4589
    4690//-----------------------------------------------------------------------------
     
    5195struct __processor_id_t {
    5296        unsigned id:24;
     97        bool full_proc:1;
    5398
    5499        #if !defined(__CFA_NO_STATISTICS__)
     
    69114        struct cluster * cltr;
    70115
    71         // Ready Queue state per processor
    72         struct {
    73                 unsigned short its;
    74                 unsigned short itr;
    75                 unsigned id;
    76                 unsigned target;
    77                 unsigned long long int cutoff;
    78         } rdq;
    79 
    80116        // Set to true to notify the processor should terminate
    81117        volatile bool do_terminate;
     
    89125        // Handle to pthreads
    90126        pthread_t kernel_thread;
    91 
    92         struct {
    93                 $io_context * ctx;
    94                 bool pending;
    95                 bool dirty;
    96         } io;
    97127
    98128        // Preemption data
     
    104134
    105135        // Idle lock (kernel semaphore)
    106         int idle;
     136        __bin_sem_t idle;
    107137
    108138        // Termination synchronisation (user semaphore)
     
    114144        // Link lists fields
    115145        DLISTED_MGD_IMPL_IN(processor)
    116 
    117         // special init fields
    118         // This is needed for memcached integration
    119         // once memcached experiments are done this should probably be removed
    120         // it is not a particularly safe scheme as it can make processors less homogeneous
    121         struct {
    122                 $thread * thrd;
    123         } init;
    124146
    125147        #if !defined(__CFA_NO_STATISTICS__)
     
    137159void ^?{}(processor & this);
    138160
    139 static inline void  ?{}(processor & this)                        { this{ "Anonymous Processor", *mainCluster}; }
    140 static inline void  ?{}(processor & this, struct cluster & cltr) { this{ "Anonymous Processor", cltr}; }
    141 static inline void  ?{}(processor & this, const char name[])     { this{name, *mainCluster}; }
     161static inline void  ?{}(processor & this)                    { this{ "Anonymous Processor", *mainCluster}; }
     162static inline void  ?{}(processor & this, struct cluster & cltr)    { this{ "Anonymous Processor", cltr}; }
     163static inline void  ?{}(processor & this, const char name[]) { this{name, *mainCluster }; }
    142164
    143165DLISTED_MGD_IMPL_OUT(processor)
    144166
    145167//-----------------------------------------------------------------------------
     168// I/O
     169struct __io_data;
     170
     171// IO poller user-thread
     172// Not using the "thread" keyword because we want to control
     173// more carefully when to start/stop it
     174struct $io_ctx_thread {
     175        struct __io_data * ring;
     176        single_sem sem;
     177        volatile bool done;
     178        $thread self;
     179};
     180
     181
     182struct io_context {
     183        $io_ctx_thread thrd;
     184};
     185
     186struct io_context_params {
     187        int num_entries;
     188        int num_ready;
     189        int submit_aff;
     190        bool eager_submits:1;
     191        bool poller_submits:1;
     192        bool poll_submit:1;
     193        bool poll_complete:1;
     194};
     195
     196void  ?{}(io_context_params & this);
     197
     198void  ?{}(io_context & this, struct cluster & cl);
     199void  ?{}(io_context & this, struct cluster & cl, const io_context_params & params);
     200void ^?{}(io_context & this);
     201
     202struct io_cancellation {
     203        __u64 target;
     204};
     205
     206static inline void  ?{}(io_cancellation & this) { this.target = -1u; }
     207static inline void ^?{}(io_cancellation &) {}
     208bool cancel(io_cancellation & this);
     209
     210//-----------------------------------------------------------------------------
    146211// Cluster Tools
    147212
    148 // Intrusives lanes which are used by the ready queue
     213// Intrusives lanes which are used by the relaxed ready queue
    149214struct __attribute__((aligned(128))) __intrusive_lane_t;
    150215void  ?{}(__intrusive_lane_t & this);
    151216void ^?{}(__intrusive_lane_t & this);
    152217
    153 // Aligned timestamps which are used by the relaxed ready queue
    154 struct __attribute__((aligned(128))) __timestamp_t;
    155 void  ?{}(__timestamp_t & this);
    156 void ^?{}(__timestamp_t & this);
     218// Counter used for wether or not the lanes are all empty
     219struct __attribute__((aligned(128))) __snzi_node_t;
     220struct __snzi_t {
     221        unsigned mask;
     222        int root;
     223        __snzi_node_t * nodes;
     224};
     225
     226void  ?{}( __snzi_t & this, unsigned depth );
     227void ^?{}( __snzi_t & this );
    157228
    158229//TODO adjust cache size to ARCHITECTURE
    159230// Structure holding the relaxed ready queue
    160231struct __ready_queue_t {
     232        // Data tracking how many/which lanes are used
     233        // Aligned to 128 for cache locality
     234        __snzi_t snzi;
     235
    161236        // Data tracking the actual lanes
    162237        // On a seperate cacheline from the used struct since
     
    167242                __intrusive_lane_t * volatile data;
    168243
    169                 // Array of times
    170                 __timestamp_t * volatile tscs;
    171 
    172244                // Number of lanes (empty or not)
    173245                volatile size_t count;
     
    179251
    180252// Idle Sleep
    181 struct __cluster_proc_list {
     253struct __cluster_idles {
    182254        // Spin lock protecting the queue
    183255        volatile uint64_t lock;
     
    190262
    191263        // List of idle processors
    192         dlist(processor, processor) idles;
    193 
    194         // List of active processors
    195         dlist(processor, processor) actives;
     264        dlist(processor, processor) list;
    196265};
    197266
     
    209278
    210279        // List of idle processors
    211         __cluster_proc_list procs;
     280        __cluster_idles idles;
    212281
    213282        // List of threads
     
    223292
    224293        struct {
    225                 $io_arbiter * arbiter;
    226                 io_context_params params;
     294                io_context * ctxs;
     295                unsigned cnt;
    227296        } io;
    228297
Note: See TracChangeset for help on using the changeset viewer.