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