Ignore:
Timestamp:
Dec 10, 2021, 2:41:52 PM (2 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, enum, forall-pointer-decay, master, pthread-emulation, qualifiedEnum
Children:
7a6ae53
Parents:
a499702
Message:

Changed defice/cpu to hopefully work with sparse cpus.
UNTESTED

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/device/cpu.cfa

    ra499702 r33608cb  
    3030        #include <fcntl.h>
    3131}
     32
     33#include "algorithms/range_iterator.hfa"
    3234
    3335// search a string for character 'character' but looking atmost at len
     
    144146
    145147// Count number of cpus in the system
    146 static int count_cpus(void) {
     148static [int, const char *] count_cpus(void) {
    147149        const char * fpath = "/sys/devices/system/cpu/online";
    148150        int fd = open(fpath, 0, O_RDONLY);
     
    160162
    161163        const char * _;
    162         return read_width(buff, r - 1, &_);;
     164        return [read_width(buff, r - 1, &_), strndup(buff, r - 1)];
    163165}
    164166
     
    236238// Returns a 2D array of instances of size [cpu count][cache levels]
    237239// where cache level doesn't include instruction caches
    238 raw_cache_instance ** build_raw_cache_table(unsigned cpus, unsigned idxs, unsigned cache_levels)
     240raw_cache_instance ** build_raw_cache_table(unsigned cpus_c, idx_range_t cpus, unsigned idxs, unsigned cache_levels)
    239241{
    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);
    266259        }
    267260
     
    276269
    277270// returns an allocate list of all the different distinct last level caches
    278 static [*llc_map_t, size_t cnt] distinct_llcs(unsigned cpus, unsigned llc_idx, raw_cache_instance ** raw) {
     271static [*llc_map_t, size_t cnt] distinct_llcs(idx_range_t cpus, unsigned llc_idx, raw_cache_instance ** raw) {
    279272        // Allocate at least one element
    280273        llc_map_t* ranges = alloc();
    281274        size_t range_cnt = 1;
    282275
     276        RangeIter rc = { cpus };
     277        __attribute__((unused)) bool ret =
     278        moveNext(rc);
     279        /* paranoid */ verify( ret );
     280        /* paranoid */ verify( rc.com >= 0 );
     281
    283282        // Initialize with element 0
    284         ranges->raw = &raw[0][llc_idx];
     283        ranges->raw = &raw[rc.com][llc_idx];
    285284        ranges->count = 0;
    286285        ranges->start = -1u;
    287286
    288287        // Go over all other cpus
    289         CPU_LOOP: for(i; 1~cpus) {
     288        CPU_LOOP: while(moveNext(rc)) {
     289                unsigned i = rc.com;
    290290                // Check if the range is already there
    291291                raw_cache_instance * candidate = &raw[i][llc_idx];
     
    317317}
    318318
    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) {
     319static [[]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;
    323325                pairings[i].cpu = i;
    324326                idx_range_t want = raw[i][0].range;
     
    340342extern "C" {
    341343        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
    343358                int idxs = count_cache_indexes();
    344359
     
    358373
    359374                // 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);
    361376
    362377                // Find number of distinct cache instances
     
    375390                                width2 += maps[i].raw->width;
    376391                        }
    377                         verify(width1 == cpus);
    378                         verify(width2 == cpus);
     392                        verify(width1 == cpus_c);
     393                        verify(width2 == cpus_c);
    379394                }
    380395                #endif
    381396
    382397                // 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);
    384399
    385400                // Sort by cache instance
    386                 qsort(pairings, cpus);
     401                qsort(pairings, cpus_c);
    387402
    388403                {
    389404                        unsigned it = 0;
    390                         for(i; cpus) {
     405                        RangeIter rc = { cpus };
     406                        while(moveNext(rc)) {
     407                                unsigned i = rc.com;
    391408                                unsigned llc_id = pairings[i].id;
    392409                                if(maps[llc_id].start == -1u) {
     
    397414                                }
    398415                        }
    399                         /* paranoid */ verify(it == cpus);
     416                        /* paranoid */ verify(it == cpus_c);
    400417                }
    401418
    402419                // 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;
    406426                        /* paranoid */ verify(pairings[i].id < map_cnt);
    407427                        unsigned c = pairings[i].cpu;
     
    419439                free(pairings);
    420440
    421                 for(i; cpus) {
    422                         for(j; cache_levels) {
     441                for(i; cpus_c) {
     442                        if( raw[i] ) for(j; cache_levels) {
    423443                                ^(raw[i][j]){};
    424444                        }
     
    428448
    429449                cpu_info.llc_map = entries;
    430                 cpu_info.hthrd_count = cpus;
     450                cpu_info.hthrd_count = cpus_c;
    431451                cpu_info.llc_count = map_cnt;
    432452        }
Note: See TracChangeset for help on using the changeset viewer.