Ignore:
File:
1 edited

Legend:

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

    r504a7dc rdd4e2d7  
    6060        // Cluster from which to get threads
    6161        struct cluster * cltr;
    62         unsigned int id;
    6362
    6463        // Name of the processor
     
    9392
    9493        // Link lists fields
    95         struct __dbg_node_cltr {
    96                 processor * next;
    97                 processor * prev;
     94        struct __dbg_node_proc {
     95                struct processor * next;
     96                struct processor * prev;
    9897        } node;
    9998
     
    117116struct __io_data;
    118117
    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
    128 struct __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
    134 struct __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 
    152 void  ?{}(__clusterRWLock_t & this);
    153 void ^?{}(__clusterRWLock_t & this);
    154 
    155 // Intrusives lanes which are used by the relaxed ready queue
    156 struct __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 
    191 void  ?{}(__intrusive_lane_t & this);
    192 void ^?{}(__intrusive_lane_t & this);
    193 
    194 typedef 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
    206 struct __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 
    269 void  ?{}(__ready_queue_t & this);
    270 void ^?{}(__ready_queue_t & this);
     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
    271122
    272123//-----------------------------------------------------------------------------
     
    274125struct cluster {
    275126        // Ready queue locks
    276         __clusterRWLock_t ready_lock;
     127        __spinlock_t ready_queue_lock;
    277128
    278129        // Ready queue for threads
    279         __ready_queue_t ready_queue;
     130        __queue_t($thread) ready_queue;
    280131
    281132        // Name of the cluster
     
    310161extern Duration default_preemption();
    311162
    312 void ?{} (cluster & this, const char name[], Duration preemption_rate, int flags);
     163void ?{} (cluster & this, const char name[], Duration preemption_rate, unsigned flags);
    313164void ^?{}(cluster & this);
    314165
    315 static inline void ?{} (cluster & this)                                      { this{"Anonymous Cluster", default_preemption(), 0}; }
    316 static inline void ?{} (cluster & this, Duration preemption_rate)            { this{"Anonymous Cluster", preemption_rate, 0}; }
    317 static inline void ?{} (cluster & this, const char name[])                   { this{name, default_preemption(), 0}; }
    318 static inline void ?{} (cluster & this, int flags)                           { this{"Anonymous Cluster", default_preemption(), flags}; }
    319 static inline void ?{} (cluster & this, Duration preemption_rate, int flags) { this{"Anonymous Cluster", preemption_rate, flags}; }
    320 static inline void ?{} (cluster & this, const char name[], int flags)        { this{name, default_preemption(), flags}; }
     166static inline void ?{} (cluster & this)                                           { this{"Anonymous Cluster", default_preemption(), 0}; }
     167static inline void ?{} (cluster & this, Duration preemption_rate)                 { this{"Anonymous Cluster", preemption_rate, 0}; }
     168static inline void ?{} (cluster & this, const char name[])                        { this{name, default_preemption(), 0}; }
     169static inline void ?{} (cluster & this, unsigned flags)                           { this{"Anonymous Cluster", default_preemption(), flags}; }
     170static inline void ?{} (cluster & this, Duration preemption_rate, unsigned flags) { this{"Anonymous Cluster", preemption_rate, flags}; }
     171static inline void ?{} (cluster & this, const char name[], unsigned flags)        { this{name, default_preemption(), flags}; }
    321172
    322173static inline [cluster *&, cluster *& ] __get( cluster & this ) __attribute__((const)) { return this.node.[next, prev]; }
Note: See TracChangeset for help on using the changeset viewer.