Index: libcfa/src/algorithms/range_iterator.hfa
===================================================================
--- libcfa/src/algorithms/range_iterator.hfa	(revision 8e6582413cf8b4afa976cac5c741ea047e2fbe90)
+++ libcfa/src/algorithms/range_iterator.hfa	(revision 33608cb54b8ea1ec847090d2cae1dd35145c0f9b)
@@ -21,5 +21,5 @@
 };
 
-void ?{}(RangeIter & this, const char * text) {
+static inline void ?{}(RangeIter & this, const char * text) {
 	this.text = text;
 }
Index: libcfa/src/device/cpu.cfa
===================================================================
--- libcfa/src/device/cpu.cfa	(revision 8e6582413cf8b4afa976cac5c741ea047e2fbe90)
+++ libcfa/src/device/cpu.cfa	(revision 33608cb54b8ea1ec847090d2cae1dd35145c0f9b)
@@ -30,4 +30,6 @@
 	#include <fcntl.h>
 }
+
+#include "algorithms/range_iterator.hfa"
 
 // search a string for character 'character' but looking atmost at len
@@ -144,5 +146,5 @@
 
 // Count number of cpus in the system
-static int count_cpus(void) {
+static [int, const char *] count_cpus(void) {
 	const char * fpath = "/sys/devices/system/cpu/online";
 	int fd = open(fpath, 0, O_RDONLY);
@@ -160,5 +162,5 @@
 
 	const char * _;
-	return read_width(buff, r - 1, &_);;
+	return [read_width(buff, r - 1, &_), strndup(buff, r - 1)];
 }
 
@@ -236,32 +238,23 @@
 // Returns a 2D array of instances of size [cpu count][cache levels]
 // where cache level doesn't include instruction caches
-raw_cache_instance ** build_raw_cache_table(unsigned cpus, unsigned idxs, unsigned cache_levels)
+raw_cache_instance ** build_raw_cache_table(unsigned cpus_c, idx_range_t cpus, unsigned idxs, unsigned cache_levels)
 {
-	raw_cache_instance ** raw = alloc(cpus);
-
-	// TODO: this loop is broken, it only works if the present cpu start at 0 and are contiguous which is not guaranteed.
-	for(i; cpus) {
-		if (cache_levels > 0) {
-			raw[i] = alloc(cache_levels);
-			void addcache(unsigned fidx, unsigned char level, idx_range_t range, size_t len) {
-				/* paranoid */ verifyf(level <= cache_levels, "Unexpected cache level %d on cpu %u index %u", (int)level, i, fidx);
-
-				unsigned idx = cache_levels - level;
-				raw_cache_instance & r = raw[i][idx];
-				r.range = strndup(range, len);
-				r.level = level;
-				const char * end;
-				r.width = read_width(range, len, &end);
-			}
-			foreach_cacheidx(i, idxs, addcache);
-		}
-		else {
-			char buf[128];
-			snprintf(buf, 128, "0-%u", cpus);
-			raw[i] = alloc();
-			raw[i]->range = strndup(buf, 128);
-			raw[i]->level = 0;
-			raw[i]->width = cpus;
-		}
+	raw_cache_instance ** raw = alloc(cpus_c, '\0'`fill);
+
+	RangeIter rc = { cpus };
+	while(moveNext(rc)) {
+		unsigned i = rc.com;
+		raw[i] = alloc(cache_levels);
+		void addcache(unsigned fidx, unsigned char level, idx_range_t range, size_t len) {
+			/* paranoid */ verifyf(level <= cache_levels, "Unexpected cache level %d on cpu %u index %u", (int)level, i, fidx);
+
+			unsigned idx = cache_levels - level;
+			raw_cache_instance & r = raw[i][idx];
+			r.range = strndup(range, len);
+			r.level = level;
+			const char * end;
+			r.width = read_width(range, len, &end);
+		}
+		foreach_cacheidx(i, idxs, addcache);
 	}
 
@@ -276,16 +269,23 @@
 
 // returns an allocate list of all the different distinct last level caches
-static [*llc_map_t, size_t cnt] distinct_llcs(unsigned cpus, unsigned llc_idx, raw_cache_instance ** raw) {
+static [*llc_map_t, size_t cnt] distinct_llcs(idx_range_t cpus, unsigned llc_idx, raw_cache_instance ** raw) {
 	// Allocate at least one element
 	llc_map_t* ranges = alloc();
 	size_t range_cnt = 1;
 
+	RangeIter rc = { cpus };
+	__attribute__((unused)) bool ret =
+	moveNext(rc);
+	/* paranoid */ verify( ret );
+	/* paranoid */ verify( rc.com >= 0 );
+
 	// Initialize with element 0
-	ranges->raw = &raw[0][llc_idx];
+	ranges->raw = &raw[rc.com][llc_idx];
 	ranges->count = 0;
 	ranges->start = -1u;
 
 	// Go over all other cpus
-	CPU_LOOP: for(i; 1~cpus) {
+	CPU_LOOP: while(moveNext(rc)) {
+		unsigned i = rc.com;
 		// Check if the range is already there
 		raw_cache_instance * candidate = &raw[i][llc_idx];
@@ -317,8 +317,10 @@
 }
 
-static [[]cpu_pairing_t] get_cpu_pairings(unsigned cpus, raw_cache_instance ** raw, llc_map_t * maps, size_t map_cnt) {
-	cpu_pairing_t * pairings = alloc(cpus);
-
-	CPU_LOOP: for(i; cpus) {
+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) {
+	cpu_pairing_t * pairings = alloc(cpus_c);
+
+	RangeIter rc = { cpus };
+	CPU_LOOP: while(moveNext(rc)) {
+		unsigned i = rc.com;
 		pairings[i].cpu = i;
 		idx_range_t want = raw[i][0].range;
@@ -340,5 +342,18 @@
 extern "C" {
 	void __cfaabi_device_startup( void ) {
-		int cpus = count_cpus();
+		int cpus_c;
+		const char * cpus;
+		[cpus_c, cpus] = count_cpus();
+		#if defined(__CFA_WITH_VERIFY__)
+		// Verify that the mapping is self consistant.
+		{
+			RangeIter rc = { cpus };
+			while(moveNext(rc)) {
+				unsigned i = rc.com;
+				verify(cpus_c > i);
+			}
+		}
+		#endif
+
 		int idxs = count_cache_indexes();
 
@@ -358,5 +373,5 @@
 
 		// Read in raw data
-		raw_cache_instance ** raw = build_raw_cache_table(cpus, idxs, cache_levels);
+		raw_cache_instance ** raw = build_raw_cache_table(cpus_c, cpus, idxs, cache_levels);
 
 		// Find number of distinct cache instances
@@ -375,18 +390,20 @@
 				width2 += maps[i].raw->width;
 			}
-			verify(width1 == cpus);
-			verify(width2 == cpus);
+			verify(width1 == cpus_c);
+			verify(width2 == cpus_c);
 		}
 		#endif
 
 		// Get mappings from cpu to cache instance
-		cpu_pairing_t * pairings = get_cpu_pairings(cpus, raw, maps, map_cnt);
+		cpu_pairing_t * pairings = get_cpu_pairings(cpus_c, cpus, raw, maps, map_cnt);
 
 		// Sort by cache instance
-		qsort(pairings, cpus);
+		qsort(pairings, cpus_c);
 
 		{
 			unsigned it = 0;
-			for(i; cpus) {
+			RangeIter rc = { cpus };
+			while(moveNext(rc)) {
+				unsigned i = rc.com;
 				unsigned llc_id = pairings[i].id;
 				if(maps[llc_id].start == -1u) {
@@ -397,11 +414,14 @@
 				}
 			}
-			/* paranoid */ verify(it == cpus);
+			/* paranoid */ verify(it == cpus_c);
 		}
 
 		// From the mappings build the actual cpu map we want
-		struct cpu_map_entry_t * entries = alloc(cpus);
-		for(i; cpus) { entries[i].count = 0; }
-		for(i; cpus) {
+		struct cpu_map_entry_t * entries = alloc(cpus_c);
+		for(i; cpus_c) { entries[i].count = 0; }
+
+		RangeIter rc = { cpus };
+		while(moveNext(rc)) {
+			unsigned i = rc.com;
 			/* paranoid */ verify(pairings[i].id < map_cnt);
 			unsigned c = pairings[i].cpu;
@@ -419,6 +439,6 @@
 		free(pairings);
 
-		for(i; cpus) {
-			for(j; cache_levels) {
+		for(i; cpus_c) {
+			if( raw[i] ) for(j; cache_levels) {
 				^(raw[i][j]){};
 			}
@@ -428,5 +448,5 @@
 
 		cpu_info.llc_map = entries;
-		cpu_info.hthrd_count = cpus;
+		cpu_info.hthrd_count = cpus_c;
 		cpu_info.llc_count = map_cnt;
 	}
