- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/kernel.hfa
r454f478 r431cd4f 28 28 } 29 29 30 //-----------------------------------------------------------------------------31 // Underlying Locks32 30 #ifdef __CFA_WITH_VERIFY__ 33 31 extern bool __cfaabi_dbg_in_kernel(); 34 32 #endif 35 33 36 extern "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 41 struct __bin_sem_t { 42 pthread_mutex_t lock; 43 pthread_cond_t cond; 44 int val; 45 }; 46 47 static 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 58 static inline void ^?{}(__bin_sem_t & this) with( this ) { 59 CHECKED( pthread_mutex_destroy(&lock) ); 60 CHECKED( pthread_cond_destroy (&cond) ); 61 } 62 63 static 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 73 static 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 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); 89 45 90 46 //----------------------------------------------------------------------------- … … 95 51 struct __processor_id_t { 96 52 unsigned id:24; 97 bool full_proc:1;98 53 99 54 #if !defined(__CFA_NO_STATISTICS__) … … 114 69 struct cluster * cltr; 115 70 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 116 80 // Set to true to notify the processor should terminate 117 81 volatile bool do_terminate; … … 125 89 // Handle to pthreads 126 90 pthread_t kernel_thread; 91 92 struct { 93 $io_context * ctx; 94 bool pending; 95 bool dirty; 96 } io; 127 97 128 98 // Preemption data … … 134 104 135 105 // Idle lock (kernel semaphore) 136 __bin_sem_t idle;106 int idle; 137 107 138 108 // Termination synchronisation (user semaphore) … … 144 114 // Link lists fields 145 115 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; 146 124 147 125 #if !defined(__CFA_NO_STATISTICS__) … … 159 137 void ^?{}(processor & this); 160 138 161 static inline void ?{}(processor & this) { this{ "Anonymous Processor", *mainCluster}; }162 static inline void ?{}(processor & this, struct cluster & cltr) 163 static inline void ?{}(processor & this, const char name[]) { this{name, *mainCluster}; }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}; } 164 142 165 143 DLISTED_MGD_IMPL_OUT(processor) 166 144 167 145 //----------------------------------------------------------------------------- 168 // I/O169 struct __io_data;170 171 // IO poller user-thread172 // Not using the "thread" keyword because we want to control173 // more carefully when to start/stop it174 struct $io_ctx_thread {175 struct __io_data * ring;176 single_sem sem;177 volatile bool done;178 $thread self;179 };180 181 182 struct io_context {183 $io_ctx_thread thrd;184 };185 186 struct 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 196 void ?{}(io_context_params & this);197 198 void ?{}(io_context & this, struct cluster & cl);199 void ?{}(io_context & this, struct cluster & cl, const io_context_params & params);200 void ^?{}(io_context & this);201 202 struct io_cancellation {203 __u64 target;204 };205 206 static inline void ?{}(io_cancellation & this) { this.target = -1u; }207 static inline void ^?{}(io_cancellation &) {}208 bool cancel(io_cancellation & this);209 210 //-----------------------------------------------------------------------------211 146 // Cluster Tools 212 147 213 // Intrusives lanes which are used by the re laxed ready queue148 // Intrusives lanes which are used by the ready queue 214 149 struct __attribute__((aligned(128))) __intrusive_lane_t; 215 150 void ?{}(__intrusive_lane_t & this); 216 151 void ^?{}(__intrusive_lane_t & this); 217 152 218 // Counter used for wether or not the lanes are all empty 219 struct __attribute__((aligned(128))) __snzi_node_t; 220 struct __snzi_t { 221 unsigned mask; 222 int root; 223 __snzi_node_t * nodes; 224 }; 225 226 void ?{}( __snzi_t & this, unsigned depth ); 227 void ^?{}( __snzi_t & this ); 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); 228 157 229 158 //TODO adjust cache size to ARCHITECTURE 230 159 // Structure holding the relaxed ready queue 231 160 struct __ready_queue_t { 232 // Data tracking how many/which lanes are used233 // Aligned to 128 for cache locality234 __snzi_t snzi;235 236 161 // Data tracking the actual lanes 237 162 // On a seperate cacheline from the used struct since … … 242 167 __intrusive_lane_t * volatile data; 243 168 169 // Array of times 170 __timestamp_t * volatile tscs; 171 244 172 // Number of lanes (empty or not) 245 173 volatile size_t count; … … 251 179 252 180 // Idle Sleep 253 struct __cluster_ idles{181 struct __cluster_proc_list { 254 182 // Spin lock protecting the queue 255 183 volatile uint64_t lock; … … 262 190 263 191 // List of idle processors 264 dlist(processor, processor) list; 192 dlist(processor, processor) idles; 193 194 // List of active processors 195 dlist(processor, processor) actives; 265 196 }; 266 197 … … 278 209 279 210 // List of idle processors 280 __cluster_ idles idles;211 __cluster_proc_list procs; 281 212 282 213 // List of threads … … 292 223 293 224 struct { 294 io_context * ctxs;295 unsigned cnt;225 $io_arbiter * arbiter; 226 io_context_params params; 296 227 } io; 297 228
Note:
See TracChangeset
for help on using the changeset viewer.