github.com/songzhibin97/gkit@v1.2.13/structure/lscq/util.go (about) 1 // Copyright 2021 ByteDance Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package lscq 16 17 import ( 18 "unsafe" 19 20 "golang.org/x/sys/cpu" 21 ) 22 23 const ( 24 scqsize = 1 << 16 25 cacheLineSize = unsafe.Sizeof(cpu.CacheLinePad{}) 26 ) 27 28 func uint64Get63(value uint64) uint64 { 29 return value & ((1 << 63) - 1) 30 } 31 32 func uint64Get1(value uint64) bool { 33 return (value & (1 << 63)) == (1 << 63) 34 } 35 36 func uint64GetAll(value uint64) (bool, uint64) { 37 return (value & (1 << 63)) == (1 << 63), value & ((1 << 63) - 1) 38 } 39 40 func loadSCQFlags(flags uint64) (isSafe bool, isEmpty bool, cycle uint64) { 41 isSafe = (flags & (1 << 63)) == (1 << 63) 42 isEmpty = (flags & (1 << 62)) == (1 << 62) 43 cycle = flags & ((1 << 62) - 1) 44 return isSafe, isEmpty, cycle 45 } 46 47 func newSCQFlags(isSafe bool, isEmpty bool, cycle uint64) uint64 { 48 v := cycle & ((1 << 62) - 1) 49 if isSafe { 50 v += 1 << 63 51 } 52 if isEmpty { 53 v += 1 << 62 54 } 55 return v 56 } 57 58 func cacheRemap16Byte(index uint64) uint64 { 59 const cacheLineSize = cacheLineSize / 2 60 rawIndex := index & uint64(scqsize-1) 61 cacheLineNum := (rawIndex) % (scqsize / uint64(cacheLineSize)) 62 cacheLineIdx := rawIndex / (scqsize / uint64(cacheLineSize)) 63 return cacheLineNum*uint64(cacheLineSize) + cacheLineIdx 64 }