Commit c3305938 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Avoid defer if possible in core code. This saves a malloc/free per

call.
parent f0adf638
......@@ -104,8 +104,6 @@ func (p *BufferPoolImpl) AllocBuffer(size uint32) []byte {
psz := sz / PAGESIZE
p.lock.Lock()
defer p.lock.Unlock()
var b []byte
b = p.getBuffer(psz)
......@@ -122,6 +120,8 @@ func (p *BufferPoolImpl) AllocBuffer(size uint32) []byte {
if paranoia && (p.createdBuffers > 50 || len(p.outstandingBuffers) > 50) {
panic("Leaking buffers")
}
p.lock.Unlock()
return b
}
......@@ -141,10 +141,10 @@ func (p *BufferPoolImpl) FreeBuffer(slice []byte) {
key := uintptr(unsafe.Pointer(&slice[0]))
p.lock.Lock()
defer p.lock.Unlock()
ok := p.outstandingBuffers[key]
if ok {
p.addBuffer(slice, psz)
delete(p.outstandingBuffers, key)
}
p.lock.Unlock()
}
......@@ -113,11 +113,12 @@ func (c *FileSystemConnector) toInode(nodeid uint64) *Inode {
// Must run outside treeLock. Returns the nodeId.
func (c *FileSystemConnector) lookupUpdate(node *Inode) uint64 {
node.treeLock.Lock()
defer node.treeLock.Unlock()
if node.lookupCount == 0 {
node.nodeId = c.inodeMap.Register(&node.handled, node)
}
node.lookupCount += 1
node.treeLock.Unlock()
return node.nodeId
}
......@@ -126,8 +127,6 @@ func (c *FileSystemConnector) forgetUpdate(node *Inode, forgetCount int) {
defer c.verify()
node.treeLock.Lock()
defer node.treeLock.Unlock()
node.lookupCount -= forgetCount
if node.lookupCount == 0 {
c.inodeMap.Forget(node.nodeId)
......@@ -137,6 +136,7 @@ func (c *FileSystemConnector) forgetUpdate(node *Inode, forgetCount int) {
}
c.recursiveConsiderDropInode(node)
node.treeLock.Unlock()
}
// InodeCount returns the number of inodes registered with the kernel.
......@@ -146,8 +146,8 @@ func (c *FileSystemConnector) InodeHandleCount() int {
func (c *FileSystemConnector) considerDropInode(node *Inode) {
node.treeLock.Lock()
defer node.treeLock.Unlock()
c.recursiveConsiderDropInode(node)
node.treeLock.Unlock()
}
// Must hold treeLock.
......@@ -176,8 +176,10 @@ func (c *FileSystemConnector) recursiveConsiderDropInode(n *Inode) (drop bool) {
}
n.openFilesMutex.Lock()
defer n.openFilesMutex.Unlock()
return len(n.openFiles) == 0
ok := len(n.openFiles) == 0
n.openFilesMutex.Unlock()
return ok
}
// Finds a node within the currently known inodes, returns the last
......
......@@ -95,8 +95,6 @@ func (m *fileSystemMount) unregisterFileHandle(handle uint64, node *Inode) *open
obj := m.openFiles.Forget(handle)
opened := (*openedFile)(unsafe.Pointer(obj))
node.openFilesMutex.Lock()
defer node.openFilesMutex.Unlock()
idx := -1
for i, v := range node.openFiles {
if v == opened {
......@@ -108,13 +106,13 @@ func (m *fileSystemMount) unregisterFileHandle(handle uint64, node *Inode) *open
l := len(node.openFiles)
node.openFiles[idx] = node.openFiles[l-1]
node.openFiles = node.openFiles[:l-1]
node.openFilesMutex.Unlock()
return opened
}
func (m *fileSystemMount) registerFileHandle(node *Inode, dir rawDir, f File, flags uint32) (uint64, *openedFile) {
node.openFilesMutex.Lock()
defer node.openFilesMutex.Unlock()
b := &openedFile{
dir: dir,
WithFlags: WithFlags{
......@@ -140,6 +138,7 @@ func (m *fileSystemMount) registerFileHandle(node *Inode, dir rawDir, f File, fl
}
node.openFiles = append(node.openFiles, b)
handle := m.openFiles.Register(&b.Handled, b)
node.openFilesMutex.Unlock()
return handle, b
}
......
......@@ -49,7 +49,6 @@ func (m *portableHandleMap) Register(obj *Handled, asInt interface{}) (handle ui
panic(_ALREADY_MSG)
}
m.Lock()
defer m.Unlock()
if len(m.freeIds) == 0 {
handle = uint64(len(m.handles))
......@@ -60,35 +59,39 @@ func (m *portableHandleMap) Register(obj *Handled, asInt interface{}) (handle ui
m.handles[handle] = obj
}
m.used++
m.Unlock()
return handle
}
func (m *portableHandleMap) Count() int {
m.RLock()
defer m.RUnlock()
return m.used
c := m.used
m.RUnlock()
return c
}
func (m *portableHandleMap) Decode(h uint64) *Handled {
m.RLock()
defer m.RUnlock()
return m.handles[h]
v := m.handles[h]
m.RUnlock()
return v
}
func (m *portableHandleMap) Forget(h uint64) *Handled {
m.Lock()
defer m.Unlock()
v := m.handles[h]
m.handles[h] = nil
m.freeIds = append(m.freeIds, h)
m.used--
m.Unlock()
return v
}
func (m *portableHandleMap) Has(h uint64) bool {
m.RLock()
defer m.RUnlock()
return m.handles[h] != nil
ok := m.handles[h] != nil
m.RUnlock()
return ok
}
// 32 bits version of HandleMap
......@@ -99,31 +102,33 @@ type int32HandleMap struct {
func (m *int32HandleMap) Register(obj *Handled, asInt interface{}) uint64 {
m.mutex.Lock()
defer m.mutex.Unlock()
handle := uint32(uintptr(unsafe.Pointer(obj)))
m.handles[handle] = obj
m.mutex.Unlock()
return uint64(handle)
}
func (m *int32HandleMap) Has(h uint64) bool {
m.mutex.Lock()
defer m.mutex.Unlock()
return m.handles[uint32(h)] != nil
ok := m.handles[uint32(h)] != nil
m.mutex.Unlock()
return ok
}
func (m *int32HandleMap) Count() int {
m.mutex.Lock()
defer m.mutex.Unlock()
return len(m.handles)
c := len(m.handles)
m.mutex.Unlock()
return c
}
func (m *int32HandleMap) Forget(handle uint64) *Handled {
val := m.Decode(handle)
m.mutex.Lock()
defer m.mutex.Unlock()
val.check = 0
delete(m.handles, uint32(handle))
m.mutex.Unlock()
return val
}
......@@ -185,8 +190,9 @@ func NewHandleMap(portable bool) (hm HandleMap) {
func (m *int64HandleMap) Count() int {
m.mutex.Lock()
defer m.mutex.Unlock()
return len(m.handles)
c := len(m.handles)
m.mutex.Unlock()
return c
}
func (m *int64HandleMap) Register(obj *Handled, asInterface interface{}) (handle uint64) {
......@@ -228,16 +234,17 @@ func (m *int64HandleMap) Forget(handle uint64) (val *Handled) {
val = m.Decode(handle)
m.mutex.Lock()
defer m.mutex.Unlock()
delete(m.handles, handle)
val.check = 0
m.mutex.Unlock()
return val
}
func (m *int64HandleMap) Has(handle uint64) bool {
m.mutex.Lock()
defer m.mutex.Unlock()
return m.handles[handle] != nil
ok := m.handles[handle] != nil
m.mutex.Unlock()
return ok
}
func (m *int64HandleMap) Decode(handle uint64) (val *Handled) {
......
......@@ -75,24 +75,24 @@ func newInode(isDir bool, fsNode FsNode) *Inode {
// Returns any open file, preferably a r/w one.
func (n *Inode) AnyFile() (file File) {
n.openFilesMutex.Lock()
defer n.openFilesMutex.Unlock()
for _, f := range n.openFiles {
if file == nil || f.WithFlags.OpenFlags&O_ANYWRITE != 0 {
file = f.WithFlags.File
}
}
n.openFilesMutex.Unlock()
return file
}
func (n *Inode) Children() (out map[string]*Inode) {
n.treeLock.RLock()
defer n.treeLock.RUnlock()
out = map[string]*Inode{}
for k, v := range n.children {
out[k] = v
}
n.treeLock.RUnlock()
return out
}
......@@ -100,14 +100,14 @@ func (n *Inode) Children() (out map[string]*Inode) {
// will skip mountpoints.
func (n *Inode) FsChildren() (out map[string]*Inode) {
n.treeLock.RLock()
defer n.treeLock.RUnlock()
out = map[string]*Inode{}
for k, v := range n.children {
if v.mount == n.mount {
out[k] = v
}
}
n.treeLock.RUnlock()
return out
}
......@@ -119,12 +119,12 @@ func (n *Inode) FsNode() FsNode {
// give mask. Use mask==0 to return all files.
func (n *Inode) Files(mask uint32) (files []WithFlags) {
n.openFilesMutex.Lock()
defer n.openFilesMutex.Unlock()
for _, f := range n.openFiles {
if mask == 0 || f.WithFlags.OpenFlags&mask != 0 {
files = append(files, f.WithFlags)
}
}
n.openFilesMutex.Unlock()
return files
}
......@@ -141,9 +141,10 @@ func (n *Inode) New(isDir bool, fsi FsNode) *Inode {
func (n *Inode) GetChild(name string) (child *Inode) {
n.treeLock.RLock()
defer n.treeLock.RUnlock()
child = n.children[name]
n.treeLock.RUnlock()
return n.children[name]
return child
}
func (n *Inode) AddChild(name string, child *Inode) {
......@@ -151,14 +152,15 @@ func (n *Inode) AddChild(name string, child *Inode) {
log.Panicf("adding nil child as %q", name)
}
n.treeLock.Lock()
defer n.treeLock.Unlock()
n.addChild(name, child)
n.treeLock.Unlock()
}
func (n *Inode) RmChild(name string) (ch *Inode) {
n.treeLock.Lock()
defer n.treeLock.Unlock()
return n.rmChild(name)
ch = n.rmChild(name)
n.treeLock.Unlock()
return
}
//////////////////////////////////////////////////////////////
......@@ -210,20 +212,21 @@ func (n *Inode) canUnmount() bool {
}
n.openFilesMutex.Lock()
defer n.openFilesMutex.Unlock()
return len(n.openFiles) == 0
ok := len(n.openFiles) == 0
n.openFilesMutex.Unlock()
return ok
}
func (n *Inode) getMountDirEntries() (out []DirEntry) {
n.treeLock.RLock()
defer n.treeLock.RUnlock()
for k := range n.mounts {
out = append(out, DirEntry{
Name: k,
Mode: S_IFDIR,
})
}
n.treeLock.RUnlock()
return out
}
......
......@@ -32,15 +32,16 @@ func NewLatencyMap() *LatencyMap {
func (m *LatencyMap) AddMany(args []LatencyArg) {
m.Mutex.Lock()
defer m.Mutex.Unlock()
for _, v := range args {
m.add(v.Name, v.Arg, v.DtNs)
}
m.Mutex.Unlock()
}
func (m *LatencyMap) Add(name string, arg string, dtNs int64) {
m.Mutex.Lock()
defer m.Mutex.Unlock()
m.add(name, arg, dtNs)
m.Mutex.Unlock()
}
func (m *LatencyMap) add(name string, arg string, dtNs int64) {
......@@ -62,40 +63,39 @@ func (m *LatencyMap) add(name string, arg string, dtNs int64) {
}
func (m *LatencyMap) Counts() map[string]int {
m.Mutex.Lock()
defer m.Mutex.Unlock()
r := make(map[string]int)
m.Mutex.Lock()
for k, v := range m.stats {
r[k] = v.count
}
m.Mutex.Unlock()
return r
}
// Latencies returns a map. Use 1e-3 for unit to get ms
// results.
func (m *LatencyMap) Latencies(unit float64) map[string]float64 {
m.Mutex.Lock()
defer m.Mutex.Unlock()
r := make(map[string]float64)
m.Mutex.Lock()
mult := 1 / (1e9 * unit)
for key, ent := range m.stats {
lat := mult * float64(ent.ns) / float64(ent.count)
r[key] = lat
}
m.Mutex.Unlock()
return r
}
func (m *LatencyMap) TopArgs(name string) []string {
m.Mutex.Lock()
defer m.Mutex.Unlock()
counts := m.secondaryStats[name]
results := make([]string, 0, len(counts))
for k, v := range counts {
results = append(results, fmt.Sprintf("% 9d %s", v, k))
}
m.Mutex.Unlock()
sort.Strings(results)
return results
}
......@@ -29,7 +29,6 @@ func (fs *MemNodeFs) Root() FsNode {
func (fs *MemNodeFs) newNode() *memNode {
fs.mutex.Lock()
defer fs.mutex.Unlock()
n := &memNode{
fs: fs,
id: fs.nextFree,
......@@ -38,6 +37,7 @@ func (fs *MemNodeFs) newNode() *memNode {
n.info.SetNs(now, now, now)
n.info.Mode = S_IFDIR | 0777
fs.nextFree++
fs.mutex.Unlock()
return n
}
......
......@@ -58,9 +58,9 @@ func (fs *PathNodeFs) ForgetClientInodes() {
return
}
fs.pathLock.Lock()
defer fs.pathLock.Unlock()
fs.clientInodeMap = map[uint64][]*clientInodePath{}
fs.root.forgetClientInodes()
fs.pathLock.Unlock()
}
// Rereads all inode numbers for all known files.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment