PERFORCE change 31058 for review

Marcel Moolenaar marcel at FreeBSD.org
Tue May 13 01:41:15 PDT 2003


http://perforce.freebsd.org/chv.cgi?CH=31058

Change 31058 by marcel at marcel_nfs on 2003/05/13 01:40:27

	Avoid using a random number generator to generate unique RIDs.
	We don't need randomness, nor uniform distribution. The cost
	generally increases with the number of RIDs allocated due to
	picking a RID that is in use already.
	Instead we maintain an index into a bitmap to the 64-bit word
	that still has unset bits (=unallocated RIDs). We advance the
	index if all bits are set.

Affected files ...

.. //depot/projects/ia64_epc/sys/ia64/ia64/pmap.c#12 edit

Differences ...

==== //depot/projects/ia64_epc/sys/ia64/ia64/pmap.c#12 (text+ko) ====

@@ -224,8 +224,11 @@
 /*
  * Data for the RID allocator
  */
-static u_int64_t *pmap_ridbusy;
-static int pmap_ridmax, pmap_ridcount;
+static int pmap_ridcount;
+static int pmap_rididx;
+static int pmap_ridmapsz;
+static int pmap_ridmax;
+static u_int64_t *pmap_ridmap;
 struct mtx pmap_ridmutex;
 
 /*
@@ -338,12 +341,18 @@
 			printf("Processor supports %d Region ID bits\n",
 			       ridbits);
 	}
-	pmap_ridmax = (1 << ridbits);
+
+	/*
+	 * XXX: If we have enough bits in the RID to use the thread ID then
+	 * we should avoid the overhead of the map and create unique RIDs
+	 * based on the thread ID.
+	 */
+ 	pmap_ridmax = (1 << ridbits);
+	pmap_ridmapsz = pmap_ridmax / 64;
+	pmap_ridmap = (u_int64_t *)pmap_steal_memory(pmap_ridmax / 8);
+	pmap_ridmap[0] |= 0xff;
+	pmap_rididx = 0;
 	pmap_ridcount = 8;
-	pmap_ridbusy = (u_int64_t *)
-		pmap_steal_memory(pmap_ridmax / 8);
-	bzero(pmap_ridbusy, pmap_ridmax / 8);
-	pmap_ridbusy[0] |= 0xff;
 	mtx_init(&pmap_ridmutex, "RID allocator lock", NULL, MTX_DEF);
 
 	/*
@@ -638,16 +647,29 @@
 static u_int32_t
 pmap_allocate_rid(void)
 {
+	uint64_t bit, bits;
 	int rid;
 
 	mtx_lock(&pmap_ridmutex);
 	if (pmap_ridcount == pmap_ridmax)
 		panic("pmap_allocate_rid: All Region IDs used");
 
-	do {
-		rid = arc4random() & (pmap_ridmax - 1);
-	} while (pmap_ridbusy[rid / 64] & (1L << (rid & 63)));
-	pmap_ridbusy[rid / 64] |= (1L << (rid & 63));
+	/* Find an index with a free bit. */
+	while ((bits = pmap_ridmap[pmap_rididx]) == ~0UL) {
+		pmap_rididx++;
+		if (pmap_rididx == pmap_ridmapsz)
+			pmap_rididx = 0;
+	}
+	rid = pmap_rididx * 64;
+
+	/* Find a free bit. */
+	bit = 1UL;
+	while (bits & bit) {
+		rid++;
+		bit <<= 1;
+	}
+
+	pmap_ridmap[pmap_rididx] |= bit;
 	pmap_ridcount++;
 	mtx_unlock(&pmap_ridmutex);
 
@@ -657,8 +679,14 @@
 static void
 pmap_free_rid(u_int32_t rid)
 {
+	uint64_t bit;
+	int idx;
+
+	idx = rid / 64;
+	bit = ~(1UL << (rid & 63));
+
 	mtx_lock(&pmap_ridmutex);
-	pmap_ridbusy[rid / 64] &= ~(1L << (rid & 63));
+	pmap_ridmap[idx] &= bit;
 	pmap_ridcount--;
 	mtx_unlock(&pmap_ridmutex);
 }


More information about the p4-projects mailing list