Bladeren bron

unix: fix build on Go 1.8

Don't use math/bits yet. Go 1.8 doesn't have it, and Go 1.8 is still
supported for a few weeks.

Fixes golang/go#23353

Change-Id: Ie69163f6f6dca95d4652441849e0152d2e346cd0
Reviewed-on: https://go-review.googlesource.com/86477
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Brad Fitzpatrick 8 jaren geleden
bovenliggende
commit
dd9ec17814
1 gewijzigde bestanden met toevoegingen van 40 en 2 verwijderingen
  1. 40 2
      unix/affinity_linux.go

+ 40 - 2
unix/affinity_linux.go

@@ -7,7 +7,6 @@
 package unix
 
 import (
-	"math/bits"
 	"unsafe"
 )
 
@@ -80,7 +79,46 @@ func (s *CPUSet) IsSet(cpu int) bool {
 func (s *CPUSet) Count() int {
 	c := 0
 	for _, b := range s {
-		c += bits.OnesCount64(uint64(b))
+		c += onesCount64(uint64(b))
 	}
 	return c
 }
+
+// onesCount64 is a copy of Go 1.9's math/bits.OnesCount64.
+// Once this package can require Go 1.9, we can delete this
+// and update the caller to use bits.OnesCount64.
+func onesCount64(x uint64) int {
+	const m0 = 0x5555555555555555 // 01010101 ...
+	const m1 = 0x3333333333333333 // 00110011 ...
+	const m2 = 0x0f0f0f0f0f0f0f0f // 00001111 ...
+	const m3 = 0x00ff00ff00ff00ff // etc.
+	const m4 = 0x0000ffff0000ffff
+
+	// Implementation: Parallel summing of adjacent bits.
+	// See "Hacker's Delight", Chap. 5: Counting Bits.
+	// The following pattern shows the general approach:
+	//
+	//   x = x>>1&(m0&m) + x&(m0&m)
+	//   x = x>>2&(m1&m) + x&(m1&m)
+	//   x = x>>4&(m2&m) + x&(m2&m)
+	//   x = x>>8&(m3&m) + x&(m3&m)
+	//   x = x>>16&(m4&m) + x&(m4&m)
+	//   x = x>>32&(m5&m) + x&(m5&m)
+	//   return int(x)
+	//
+	// Masking (& operations) can be left away when there's no
+	// danger that a field's sum will carry over into the next
+	// field: Since the result cannot be > 64, 8 bits is enough
+	// and we can ignore the masks for the shifts by 8 and up.
+	// Per "Hacker's Delight", the first line can be simplified
+	// more, but it saves at best one instruction, so we leave
+	// it alone for clarity.
+	const m = 1<<64 - 1
+	x = x>>1&(m0&m) + x&(m0&m)
+	x = x>>2&(m1&m) + x&(m1&m)
+	x = (x>>4 + x) & (m2 & m)
+	x += x >> 8
+	x += x >> 16
+	x += x >> 32
+	return int(x) & (1<<7 - 1)
+}