Changeset 33608cb for libcfa/src/device
- Timestamp:
- Dec 10, 2021, 2:41:52 PM (3 years ago)
- Branches:
- ADT, ast-experimental, enum, forall-pointer-decay, master, pthread-emulation, qualifiedEnum
- Children:
- 7a6ae53
- Parents:
- a499702
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified libcfa/src/device/cpu.cfa ¶
ra499702 r33608cb 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 … … 144 146 145 147 // Count number of cpus in the system 146 static intcount_cpus(void) {148 static [int, const char *] count_cpus(void) { 147 149 const char * fpath = "/sys/devices/system/cpu/online"; 148 150 int fd = open(fpath, 0, O_RDONLY); … … 160 162 161 163 const char * _; 162 return read_width(buff, r - 1, &_);;164 return [read_width(buff, r - 1, &_), strndup(buff, r - 1)]; 163 165 } 164 166 … … 236 238 // Returns a 2D array of instances of size [cpu count][cache levels] 237 239 // where cache level doesn't include instruction caches 238 raw_cache_instance ** build_raw_cache_table(unsigned cpus , unsigned idxs, unsigned cache_levels)240 raw_cache_instance ** build_raw_cache_table(unsigned cpus_c, idx_range_t cpus, unsigned idxs, unsigned cache_levels) 239 241 { 240 raw_cache_instance ** raw = alloc(cpus); 241 242 // TODO: this loop is broken, it only works if the present cpu start at 0 and are contiguous which is not guaranteed. 243 for(i; cpus) { 244 if (cache_levels > 0) { 245 raw[i] = alloc(cache_levels); 246 void addcache(unsigned fidx, unsigned char level, idx_range_t range, size_t len) { 247 /* paranoid */ verifyf(level <= cache_levels, "Unexpected cache level %d on cpu %u index %u", (int)level, i, fidx); 248 249 unsigned idx = cache_levels - level; 250 raw_cache_instance & r = raw[i][idx]; 251 r.range = strndup(range, len); 252 r.level = level; 253 const char * end; 254 r.width = read_width(range, len, &end); 255 } 256 foreach_cacheidx(i, idxs, addcache); 257 } 258 else { 259 char buf[128]; 260 snprintf(buf, 128, "0-%u", cpus); 261 raw[i] = alloc(); 262 raw[i]->range = strndup(buf, 128); 263 raw[i]->level = 0; 264 raw[i]->width = cpus; 265 } 242 raw_cache_instance ** raw = alloc(cpus_c, '\0'`fill); 243 244 RangeIter rc = { cpus }; 245 while(moveNext(rc)) { 246 unsigned i = rc.com; 247 raw[i] = alloc(cache_levels); 248 void addcache(unsigned fidx, unsigned char level, idx_range_t range, size_t len) { 249 /* paranoid */ verifyf(level <= cache_levels, "Unexpected cache level %d on cpu %u index %u", (int)level, i, fidx); 250 251 unsigned idx = cache_levels - level; 252 raw_cache_instance & r = raw[i][idx]; 253 r.range = strndup(range, len); 254 r.level = level; 255 const char * end; 256 r.width = read_width(range, len, &end); 257 } 258 foreach_cacheidx(i, idxs, addcache); 266 259 } 267 260 … … 276 269 277 270 // returns an allocate list of all the different distinct last level caches 278 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) { 279 272 // Allocate at least one element 280 273 llc_map_t* ranges = alloc(); 281 274 size_t range_cnt = 1; 282 275 276 RangeIter rc = { cpus }; 277 __attribute__((unused)) bool ret = 278 moveNext(rc); 279 /* paranoid */ verify( ret ); 280 /* paranoid */ verify( rc.com >= 0 ); 281 283 282 // Initialize with element 0 284 ranges->raw = &raw[ 0][llc_idx];283 ranges->raw = &raw[rc.com][llc_idx]; 285 284 ranges->count = 0; 286 285 ranges->start = -1u; 287 286 288 287 // Go over all other cpus 289 CPU_LOOP: for(i; 1~cpus) { 288 CPU_LOOP: while(moveNext(rc)) { 289 unsigned i = rc.com; 290 290 // Check if the range is already there 291 291 raw_cache_instance * candidate = &raw[i][llc_idx]; … … 317 317 } 318 318 319 static [[]cpu_pairing_t] get_cpu_pairings(unsigned cpus, raw_cache_instance ** raw, llc_map_t * maps, size_t map_cnt) { 320 cpu_pairing_t * pairings = alloc(cpus); 321 322 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; 323 325 pairings[i].cpu = i; 324 326 idx_range_t want = raw[i][0].range; … … 340 342 extern "C" { 341 343 void __cfaabi_device_startup( void ) { 342 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 343 358 int idxs = count_cache_indexes(); 344 359 … … 358 373 359 374 // Read in raw data 360 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); 361 376 362 377 // Find number of distinct cache instances … … 375 390 width2 += maps[i].raw->width; 376 391 } 377 verify(width1 == cpus );378 verify(width2 == cpus );392 verify(width1 == cpus_c); 393 verify(width2 == cpus_c); 379 394 } 380 395 #endif 381 396 382 397 // Get mappings from cpu to cache instance 383 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); 384 399 385 400 // Sort by cache instance 386 qsort(pairings, cpus );401 qsort(pairings, cpus_c); 387 402 388 403 { 389 404 unsigned it = 0; 390 for(i; cpus) { 405 RangeIter rc = { cpus }; 406 while(moveNext(rc)) { 407 unsigned i = rc.com; 391 408 unsigned llc_id = pairings[i].id; 392 409 if(maps[llc_id].start == -1u) { … … 397 414 } 398 415 } 399 /* paranoid */ verify(it == cpus );416 /* paranoid */ verify(it == cpus_c); 400 417 } 401 418 402 419 // From the mappings build the actual cpu map we want 403 struct cpu_map_entry_t * entries = alloc(cpus); 404 for(i; cpus) { entries[i].count = 0; } 405 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; 406 426 /* paranoid */ verify(pairings[i].id < map_cnt); 407 427 unsigned c = pairings[i].cpu; … … 419 439 free(pairings); 420 440 421 for(i; cpus ) {422 for(j; cache_levels) {441 for(i; cpus_c) { 442 if( raw[i] ) for(j; cache_levels) { 423 443 ^(raw[i][j]){}; 424 444 } … … 428 448 429 449 cpu_info.llc_map = entries; 430 cpu_info.hthrd_count = cpus ;450 cpu_info.hthrd_count = cpus_c; 431 451 cpu_info.llc_count = map_cnt; 432 452 }
Note: See TracChangeset
for help on using the changeset viewer.