Changeset 6c53a93 for libcfa/src/device/cpu.cfa
- Timestamp:
- Jan 5, 2022, 10:39:39 AM (4 years ago)
- Branches:
- ADT, ast-experimental, enum, forall-pointer-decay, master, pthread-emulation, qualifiedEnum
- Children:
- 0ac728b
- Parents:
- e2853eb (diff), 6111f1f (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - File:
-
- 1 edited
-
libcfa/src/device/cpu.cfa (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/device/cpu.cfa
re2853eb r6c53a93 30 30 #include <fcntl.h> 31 31 } 32 33 #include "algorithms/range_iterator.hfa" 32 34 33 35 // search a string for character 'character' but looking atmost at len … … 135 137 count++; 136 138 } 137 iterate_dir(path, lambda); 139 int ret = iterate_dir(path, lambda); 140 if(ret == ENOTDIR) return 0; 138 141 139 142 /* paranoid */ verifyf(count == max + 1, "Inconsistent %s count, counted %d, but max %s was %d", prefix, count, prefix, (int)max); … … 143 146 144 147 // Count number of cpus in the system 145 static intcount_cpus(void) {148 static [int, const char *] count_cpus(void) { 146 149 const char * fpath = "/sys/devices/system/cpu/online"; 147 150 int fd = open(fpath, 0, O_RDONLY); … … 159 162 160 163 const char * _; 161 int cnt = read_width(buff, r - 1, &_); 162 /* paranoid */ verify(cnt == count_prefix_dirs("/sys/devices/system/cpu", "cpu")); 163 return cnt; 164 return [read_width(buff, r - 1, &_), strndup(buff, r - 1)]; 164 165 } 165 166 … … 226 227 227 228 struct raw_cache_instance { 228 idx_range_t range; 229 unsigned width; 230 unsigned char level; 229 idx_range_t range; // A text description of the cpus covered 230 unsigned width; // The number of cpus covered 231 unsigned char level; // the cache level 231 232 // FIXME add at least size and type 232 233 }; … … 235 236 static void ^?{}(raw_cache_instance & this) { free(this.range);} 236 237 237 raw_cache_instance ** build_raw_cache_table(unsigned cpus, unsigned idxs, unsigned cache_levels) 238 // Returns a 2D array of instances of size [cpu count][cache levels] 239 // where cache level doesn't include instruction caches 240 raw_cache_instance ** build_raw_cache_table(unsigned cpus_c, idx_range_t cpus, unsigned idxs, unsigned cache_levels) 238 241 { 239 raw_cache_instance ** raw = alloc(cpus); 240 for(i; cpus) { 242 raw_cache_instance ** raw = alloc(cpus_c, '\0'`fill); 243 244 RangeIter rc = { cpus }; 245 while(moveNext(rc)) { 246 unsigned i = rc.com; 241 247 raw[i] = alloc(cache_levels); 242 248 void addcache(unsigned fidx, unsigned char level, idx_range_t range, size_t len) { … … 263 269 264 270 // returns an allocate list of all the different distinct last level caches 265 static [*llc_map_t, size_t cnt] distinct_llcs( unsignedcpus, unsigned llc_idx, raw_cache_instance ** raw) {271 static [*llc_map_t, size_t cnt] distinct_llcs(idx_range_t cpus, unsigned llc_idx, raw_cache_instance ** raw) { 266 272 // Allocate at least one element 267 273 llc_map_t* ranges = alloc(); 268 274 size_t range_cnt = 1; 269 275 276 RangeIter rc = { cpus }; 277 __attribute__((unused)) bool ret = 278 moveNext(rc); 279 /* paranoid */ verify( ret ); 280 /* paranoid */ verify( rc.com >= 0 ); 281 270 282 // Initialize with element 0 271 ranges->raw = &raw[ 0][llc_idx];283 ranges->raw = &raw[rc.com][llc_idx]; 272 284 ranges->count = 0; 273 285 ranges->start = -1u; 274 286 275 287 // Go over all other cpus 276 CPU_LOOP: for(i; 1~cpus) { 288 CPU_LOOP: while(moveNext(rc)) { 289 unsigned i = rc.com; 277 290 // Check if the range is already there 278 291 raw_cache_instance * candidate = &raw[i][llc_idx]; … … 304 317 } 305 318 306 static [[]cpu_pairing_t] get_cpu_pairings(unsigned cpus, raw_cache_instance ** raw, llc_map_t * maps, size_t map_cnt) { 307 cpu_pairing_t * pairings = alloc(cpus); 308 309 CPU_LOOP: for(i; cpus) { 319 static [[]cpu_pairing_t] get_cpu_pairings(unsigned cpus_c, idx_range_t cpus, raw_cache_instance ** raw, llc_map_t * maps, size_t map_cnt) { 320 cpu_pairing_t * pairings = alloc(cpus_c); 321 322 RangeIter rc = { cpus }; 323 CPU_LOOP: while(moveNext(rc)) { 324 unsigned i = rc.com; 310 325 pairings[i].cpu = i; 311 326 idx_range_t want = raw[i][0].range; … … 327 342 extern "C" { 328 343 void __cfaabi_device_startup( void ) { 329 int cpus = count_cpus(); 344 int cpus_c; 345 const char * cpus; 346 [cpus_c, cpus] = count_cpus(); 347 #if defined(__CFA_WITH_VERIFY__) 348 // Verify that the mapping is self consistant. 349 { 350 RangeIter rc = { cpus }; 351 while(moveNext(rc)) { 352 unsigned i = rc.com; 353 verify(cpus_c > i); 354 } 355 } 356 #endif 357 330 358 int idxs = count_cache_indexes(); 331 359 … … 333 361 unsigned cache_levels = 0; 334 362 unsigned llc = 0; 335 {363 if (idxs != 0) { 336 364 unsigned char prev = -1u; 337 365 void first(unsigned idx, unsigned char level, const char * map, size_t len) { … … 345 373 346 374 // Read in raw data 347 raw_cache_instance ** raw = build_raw_cache_table(cpus , idxs, cache_levels);375 raw_cache_instance ** raw = build_raw_cache_table(cpus_c, cpus, idxs, cache_levels); 348 376 349 377 // Find number of distinct cache instances … … 362 390 width2 += maps[i].raw->width; 363 391 } 364 verify(width1 == cpus );365 verify(width2 == cpus );392 verify(width1 == cpus_c); 393 verify(width2 == cpus_c); 366 394 } 367 395 #endif 368 396 369 397 // Get mappings from cpu to cache instance 370 cpu_pairing_t * pairings = get_cpu_pairings(cpus , raw, maps, map_cnt);398 cpu_pairing_t * pairings = get_cpu_pairings(cpus_c, cpus, raw, maps, map_cnt); 371 399 372 400 // Sort by cache instance 373 qsort(pairings, cpus );401 qsort(pairings, cpus_c); 374 402 375 403 { 376 404 unsigned it = 0; 377 for(i; cpus) { 405 RangeIter rc = { cpus }; 406 while(moveNext(rc)) { 407 unsigned i = rc.com; 378 408 unsigned llc_id = pairings[i].id; 379 409 if(maps[llc_id].start == -1u) { … … 384 414 } 385 415 } 386 /* paranoid */ verify(it == cpus );416 /* paranoid */ verify(it == cpus_c); 387 417 } 388 418 389 419 // From the mappings build the actual cpu map we want 390 struct cpu_map_entry_t * entries = alloc(cpus); 391 for(i; cpus) { entries[i].count = 0; } 392 for(i; cpus) { 420 struct cpu_map_entry_t * entries = alloc(cpus_c); 421 for(i; cpus_c) { entries[i].count = 0; } 422 423 RangeIter rc = { cpus }; 424 while(moveNext(rc)) { 425 unsigned i = rc.com; 393 426 /* paranoid */ verify(pairings[i].id < map_cnt); 394 427 unsigned c = pairings[i].cpu; … … 406 439 free(pairings); 407 440 408 for(i; cpus ) {409 for(j; cache_levels) {441 for(i; cpus_c) { 442 if( raw[i] ) for(j; cache_levels) { 410 443 ^(raw[i][j]){}; 411 444 } … … 415 448 416 449 cpu_info.llc_map = entries; 417 cpu_info.hthrd_count = cpus; 450 cpu_info.hthrd_count = cpus_c; 451 cpu_info.llc_count = map_cnt; 418 452 } 419 453
Note:
See TracChangeset
for help on using the changeset viewer.