Ignore:
File:
1 edited

Legend:

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

    rdd4e2d7 r504a7dc  
    6060        // Cluster from which to get threads
    6161        struct cluster * cltr;
     62        unsigned int id;
    6263
    6364        // Name of the processor
     
    9293
    9394        // Link lists fields
    94         struct __dbg_node_proc {
    95                 struct processor * next;
    96                 struct processor * prev;
     95        struct __dbg_node_cltr {
     96                processor * next;
     97                processor * prev;
    9798        } node;
    9899
     
    116117struct __io_data;
    117118
    118 #define CFA_CLUSTER_IO_POLLER_USER_THREAD    1 << 0 // 0x1
    119 #define CFA_CLUSTER_IO_POLLER_THREAD_SUBMITS 1 << 1 // 0x2
    120 // #define CFA_CLUSTER_IO_POLLER_KERNEL_SIDE 1 << 2 // 0x4
    121 #define CFA_CLUSTER_IO_BUFFLEN_OFFSET        16
     119#define CFA_CLUSTER_IO_POLLER_USER_THREAD 1 << 0
     120// #define CFA_CLUSTER_IO_POLLER_KERNEL_SIDE 1 << 1
     121
     122
     123//-----------------------------------------------------------------------------
     124// Cluster Tools
     125
     126// Cells use by the reader writer lock
     127// while not generic it only relies on a opaque pointer
     128struct __processor_id;
     129
     130// Reader-Writer lock protecting the ready-queue
     131// while this lock is mostly generic some aspects
     132// have been hard-coded to for the ready-queue for
     133// simplicity and performance
     134struct __clusterRWLock_t {
     135        // total cachelines allocated
     136        unsigned int max;
     137
     138        // cachelines currently in use
     139        volatile unsigned int alloc;
     140
     141        // cachelines ready to itereate over
     142        // (!= to alloc when thread is in second half of doregister)
     143        volatile unsigned int ready;
     144
     145        // writer lock
     146        volatile bool lock;
     147
     148        // data pointer
     149        __processor_id * data;
     150};
     151
     152void  ?{}(__clusterRWLock_t & this);
     153void ^?{}(__clusterRWLock_t & this);
     154
     155// Intrusives lanes which are used by the relaxed ready queue
     156struct __attribute__((aligned(128))) __intrusive_lane_t {
     157        // spin lock protecting the queue
     158        volatile bool lock;
     159
     160        // anchor for the head and the tail of the queue
     161        struct __sentinel_t {
     162                // Link lists fields
     163                // instrusive link field for threads
     164                // must be exactly as in $thread
     165                __thread_desc_link link;
     166        } before, after;
     167
     168#if defined(__CFA_WITH_VERIFY__)
     169        // id of last processor to acquire the lock
     170        // needed only to check for mutual exclusion violations
     171        unsigned int last_id;
     172
     173        // number of items on this list
     174        // needed only to check for deadlocks
     175        unsigned int count;
     176#endif
     177
     178        // Optional statistic counters
     179        #if !defined(__CFA_NO_SCHED_STATS__)
     180                struct __attribute__((aligned(64))) {
     181                        // difference between number of push and pops
     182                        ssize_t diff;
     183
     184                        // total number of pushes and pops
     185                        size_t  push;
     186                        size_t  pop ;
     187                } stat;
     188        #endif
     189};
     190
     191void  ?{}(__intrusive_lane_t & this);
     192void ^?{}(__intrusive_lane_t & this);
     193
     194typedef unsigned long long __cfa_readyQ_mask_t;
     195
     196// enum {
     197//      __cfa_ready_queue_mask_size = (64 - sizeof(size_t)) / sizeof(size_t),
     198//      __cfa_max_ready_queues = __cfa_ready_queue_mask_size * 8 * sizeof(size_t)
     199// };
     200
     201#define __cfa_lane_mask_size ((64 - sizeof(size_t)) / sizeof(__cfa_readyQ_mask_t))
     202#define __cfa_max_lanes (__cfa_lane_mask_size * 8 * sizeof(__cfa_readyQ_mask_t))
     203
     204//TODO adjust cache size to ARCHITECTURE
     205// Structure holding the relaxed ready queue
     206struct __attribute__((aligned(128))) __ready_queue_t {
     207        // Data tracking how many/which lanes are used
     208        // Aligned to 128 for cache locality
     209        struct {
     210                // number of non-empty lanes
     211                volatile size_t count;
     212
     213                // bit mask, set bits indentify which lanes are non-empty
     214                volatile __cfa_readyQ_mask_t mask[ __cfa_lane_mask_size ];
     215        } used;
     216
     217        // Data tracking the actual lanes
     218        // On a seperate cacheline from the used struct since
     219        // used can change on each push/pop but this data
     220        // only changes on shrink/grow
     221        struct __attribute__((aligned(64))) {
     222                // Arary of lanes
     223                __intrusive_lane_t * volatile data;
     224
     225                // Number of lanes (empty or not)
     226                volatile size_t count;
     227        } lanes;
     228
     229        // Statistics
     230        #if !defined(__CFA_NO_STATISTICS__)
     231                __attribute__((aligned(64))) struct {
     232                        struct {
     233                                // Push statistic
     234                                struct {
     235                                        // number of attemps at pushing something
     236                                        volatile size_t attempt;
     237
     238                                        // number of successes at pushing
     239                                        volatile size_t success;
     240                                } push;
     241
     242                                // Pop statistic
     243                                struct {
     244                                        // number of reads of the mask
     245                                        // picking an empty __cfa_readyQ_mask_t counts here
     246                                        // but not as an attempt
     247                                        volatile size_t maskrds;
     248
     249                                        // number of attemps at poping something
     250                                        volatile size_t attempt;
     251
     252                                        // number of successes at poping
     253                                        volatile size_t success;
     254                                } pop;
     255                        } pick;
     256
     257                        // stats on the "used" struct of the queue
     258                        // tracks average number of queues that are not empty
     259                        // when pushing / poping
     260                        struct {
     261                                volatile size_t value;
     262                                volatile size_t count;
     263                        } used;
     264                } global_stats;
     265
     266        #endif
     267};
     268
     269void  ?{}(__ready_queue_t & this);
     270void ^?{}(__ready_queue_t & this);
    122271
    123272//-----------------------------------------------------------------------------
     
    125274struct cluster {
    126275        // Ready queue locks
    127         __spinlock_t ready_queue_lock;
     276        __clusterRWLock_t ready_lock;
    128277
    129278        // Ready queue for threads
    130         __queue_t($thread) ready_queue;
     279        __ready_queue_t ready_queue;
    131280
    132281        // Name of the cluster
     
    161310extern Duration default_preemption();
    162311
    163 void ?{} (cluster & this, const char name[], Duration preemption_rate, unsigned flags);
     312void ?{} (cluster & this, const char name[], Duration preemption_rate, int flags);
    164313void ^?{}(cluster & this);
    165314
    166 static inline void ?{} (cluster & this)                                           { this{"Anonymous Cluster", default_preemption(), 0}; }
    167 static inline void ?{} (cluster & this, Duration preemption_rate)                 { this{"Anonymous Cluster", preemption_rate, 0}; }
    168 static inline void ?{} (cluster & this, const char name[])                        { this{name, default_preemption(), 0}; }
    169 static inline void ?{} (cluster & this, unsigned flags)                           { this{"Anonymous Cluster", default_preemption(), flags}; }
    170 static inline void ?{} (cluster & this, Duration preemption_rate, unsigned flags) { this{"Anonymous Cluster", preemption_rate, flags}; }
    171 static inline void ?{} (cluster & this, const char name[], unsigned flags)        { this{name, default_preemption(), flags}; }
     315static inline void ?{} (cluster & this)                                      { this{"Anonymous Cluster", default_preemption(), 0}; }
     316static inline void ?{} (cluster & this, Duration preemption_rate)            { this{"Anonymous Cluster", preemption_rate, 0}; }
     317static inline void ?{} (cluster & this, const char name[])                   { this{name, default_preemption(), 0}; }
     318static inline void ?{} (cluster & this, int flags)                           { this{"Anonymous Cluster", default_preemption(), flags}; }
     319static inline void ?{} (cluster & this, Duration preemption_rate, int flags) { this{"Anonymous Cluster", preemption_rate, flags}; }
     320static inline void ?{} (cluster & this, const char name[], int flags)        { this{name, default_preemption(), flags}; }
    172321
    173322static inline [cluster *&, cluster *& ] __get( cluster & this ) __attribute__((const)) { return this.node.[next, prev]; }
Note: See TracChangeset for help on using the changeset viewer.