Commit 03f2289f authored by Russ Cox's avatar Russ Cox

runtime: API

Delete Alloc, Free, Lookup, Semacquire, Semrelease

Fixes #2955.

R=golang-dev, r, bradfitz
CC=golang-dev
https://golang.org/cl/5675093
parent 83976e3a
...@@ -32,18 +32,6 @@ func NumCgoCall() int64 ...@@ -32,18 +32,6 @@ func NumCgoCall() int64
// NumGoroutine returns the number of goroutines that currently exist. // NumGoroutine returns the number of goroutines that currently exist.
func NumGoroutine() int32 func NumGoroutine() int32
// Alloc allocates a block of the given size.
// FOR TESTING AND DEBUGGING ONLY.
func Alloc(uintptr) *byte
// Free frees the block starting at the given pointer.
// FOR TESTING AND DEBUGGING ONLY.
func Free(*byte)
// Lookup returns the base and size of the block containing the given pointer.
// FOR TESTING AND DEBUGGING ONLY.
func Lookup(*byte) (*byte, uintptr)
// MemProfileRate controls the fraction of memory allocations // MemProfileRate controls the fraction of memory allocations
// that are recorded and reported in the memory profile. // that are recorded and reported in the memory profile.
// The profiler aims to sample an average of // The profiler aims to sample an average of
......
...@@ -68,17 +68,6 @@ func funcline_go(*Func, uintptr) (string, int) ...@@ -68,17 +68,6 @@ func funcline_go(*Func, uintptr) (string, int)
// mid returns the current os thread (m) id. // mid returns the current os thread (m) id.
func mid() uint32 func mid() uint32
// Semacquire waits until *s > 0 and then atomically decrements it.
// It is intended as a simple sleep primitive for use by the synchronization
// library and should not be used directly.
func Semacquire(s *uint32)
// Semrelease atomically increments *s and notifies a waiting goroutine
// if one is blocked in Semacquire.
// It is intended as a simple wakeup primitive for use by the synchronization
// library and should not be used directly.
func Semrelease(s *uint32)
// SetFinalizer sets the finalizer associated with x to f. // SetFinalizer sets the finalizer associated with x to f.
// When the garbage collector finds an unreachable block // When the garbage collector finds an unreachable block
// with an associated finalizer, it clears the association and runs // with an associated finalizer, it clears the association and runs
......
...@@ -446,18 +446,6 @@ runtime·stackfree(void *v, uintptr n) ...@@ -446,18 +446,6 @@ runtime·stackfree(void *v, uintptr n)
runtime·free(v); runtime·free(v);
} }
func Alloc(n uintptr) (p *byte) {
p = runtime·malloc(n);
}
func Free(p *byte) {
runtime·free(p);
}
func Lookup(p *byte) (base *byte, size uintptr) {
runtime·mlookup(p, &base, &size, nil);
}
func GC() { func GC() {
runtime·gc(1); runtime·gc(1);
} }
......
// run
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build ignore
// trivial malloc test // trivial malloc test
package main package main
......
// run
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build ignore
// Random malloc test. // Random malloc test.
package main package main
......
// run
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Repeated malloc test. // Repeated malloc test.
// +build ignore
package main package main
import ( import (
......
// run
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build ignore
// Repeated malloc test. // Repeated malloc test.
package main package main
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
// See Mullender and Cox, ``Semaphores in Plan 9,'' // See Mullender and Cox, ``Semaphores in Plan 9,''
// http://swtch.com/semaphore.pdf // http://swtch.com/semaphore.pdf
package runtime package sync
#include "runtime.h" #include "runtime.h"
#include "arch_GOARCH.h" #include "arch_GOARCH.h"
...@@ -169,10 +169,10 @@ runtime·semrelease(uint32 volatile *addr) ...@@ -169,10 +169,10 @@ runtime·semrelease(uint32 volatile *addr)
runtime·ready(s->g); runtime·ready(s->g);
} }
func Semacquire(addr *uint32) { func runtime_Semacquire(addr *uint32) {
runtime·semacquire(addr); runtime·semacquire(addr);
} }
func Semrelease(addr *uint32) { func runtime_Semrelease(addr *uint32) {
runtime·semrelease(addr); runtime·semrelease(addr);
} }
...@@ -4,8 +4,6 @@ ...@@ -4,8 +4,6 @@
package sync package sync
import "runtime"
// Cond implements a condition variable, a rendezvous point // Cond implements a condition variable, a rendezvous point
// for goroutines waiting for or announcing the occurrence // for goroutines waiting for or announcing the occurrence
// of an event. // of an event.
...@@ -66,7 +64,7 @@ func (c *Cond) Wait() { ...@@ -66,7 +64,7 @@ func (c *Cond) Wait() {
c.newWaiters++ c.newWaiters++
c.m.Unlock() c.m.Unlock()
c.L.Unlock() c.L.Unlock()
runtime.Semacquire(s) runtime_Semacquire(s)
c.L.Lock() c.L.Lock()
} }
...@@ -85,7 +83,7 @@ func (c *Cond) Signal() { ...@@ -85,7 +83,7 @@ func (c *Cond) Signal() {
} }
if c.oldWaiters > 0 { if c.oldWaiters > 0 {
c.oldWaiters-- c.oldWaiters--
runtime.Semrelease(c.oldSema) runtime_Semrelease(c.oldSema)
} }
c.m.Unlock() c.m.Unlock()
} }
...@@ -99,13 +97,13 @@ func (c *Cond) Broadcast() { ...@@ -99,13 +97,13 @@ func (c *Cond) Broadcast() {
// Wake both generations. // Wake both generations.
if c.oldWaiters > 0 { if c.oldWaiters > 0 {
for i := 0; i < c.oldWaiters; i++ { for i := 0; i < c.oldWaiters; i++ {
runtime.Semrelease(c.oldSema) runtime_Semrelease(c.oldSema)
} }
c.oldWaiters = 0 c.oldWaiters = 0
} }
if c.newWaiters > 0 { if c.newWaiters > 0 {
for i := 0; i < c.newWaiters; i++ { for i := 0; i < c.newWaiters; i++ {
runtime.Semrelease(c.newSema) runtime_Semrelease(c.newSema)
} }
c.newWaiters = 0 c.newWaiters = 0
c.newSema = nil c.newSema = nil
......
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package sync
// Export for testing.
var Runtime_Semacquire = runtime_Semacquire
var Runtime_Semrelease = runtime_Semrelease
...@@ -10,10 +10,7 @@ ...@@ -10,10 +10,7 @@
// Values containing the types defined in this package should not be copied. // Values containing the types defined in this package should not be copied.
package sync package sync
import ( import "sync/atomic"
"runtime"
"sync/atomic"
)
// A Mutex is a mutual exclusion lock. // A Mutex is a mutual exclusion lock.
// Mutexes can be created as part of other structures; // Mutexes can be created as part of other structures;
...@@ -60,7 +57,7 @@ func (m *Mutex) Lock() { ...@@ -60,7 +57,7 @@ func (m *Mutex) Lock() {
if old&mutexLocked == 0 { if old&mutexLocked == 0 {
break break
} }
runtime.Semacquire(&m.sema) runtime_Semacquire(&m.sema)
awoke = true awoke = true
} }
} }
...@@ -89,7 +86,7 @@ func (m *Mutex) Unlock() { ...@@ -89,7 +86,7 @@ func (m *Mutex) Unlock() {
// Grab the right to wake someone. // Grab the right to wake someone.
new = (old - 1<<mutexWaiterShift) | mutexWoken new = (old - 1<<mutexWaiterShift) | mutexWoken
if atomic.CompareAndSwapInt32(&m.state, old, new) { if atomic.CompareAndSwapInt32(&m.state, old, new) {
runtime.Semrelease(&m.sema) runtime_Semrelease(&m.sema)
return return
} }
old = m.state old = m.state
......
...@@ -15,8 +15,8 @@ import ( ...@@ -15,8 +15,8 @@ import (
func HammerSemaphore(s *uint32, loops int, cdone chan bool) { func HammerSemaphore(s *uint32, loops int, cdone chan bool) {
for i := 0; i < loops; i++ { for i := 0; i < loops; i++ {
runtime.Semacquire(s) Runtime_Semacquire(s)
runtime.Semrelease(s) Runtime_Semrelease(s)
} }
cdone <- true cdone <- true
} }
......
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package sync
// defined in package runtime
// Semacquire waits until *s > 0 and then atomically decrements it.
// It is intended as a simple sleep primitive for use by the synchronization
// library and should not be used directly.
func runtime_Semacquire(s *uint32)
// Semrelease atomically increments *s and notifies a waiting goroutine
// if one is blocked in Semacquire.
// It is intended as a simple wakeup primitive for use by the synchronization
// library and should not be used directly.
func runtime_Semrelease(s *uint32)
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package runtime_test package sync_test
import ( import (
"runtime" "runtime"
. "sync"
"sync/atomic" "sync/atomic"
"testing" "testing"
) )
...@@ -25,8 +26,8 @@ func BenchmarkSemaUncontended(b *testing.B) { ...@@ -25,8 +26,8 @@ func BenchmarkSemaUncontended(b *testing.B) {
for atomic.AddInt32(&N, -1) >= 0 { for atomic.AddInt32(&N, -1) >= 0 {
runtime.Gosched() runtime.Gosched()
for g := 0; g < CallsPerSched; g++ { for g := 0; g < CallsPerSched; g++ {
runtime.Semrelease(&sem.sem) Runtime_Semrelease(&sem.sem)
runtime.Semacquire(&sem.sem) Runtime_Semacquire(&sem.sem)
} }
} }
c <- true c <- true
...@@ -48,7 +49,7 @@ func benchmarkSema(b *testing.B, block, work bool) { ...@@ -48,7 +49,7 @@ func benchmarkSema(b *testing.B, block, work bool) {
if block { if block {
for p := 0; p < procs/2; p++ { for p := 0; p < procs/2; p++ {
go func() { go func() {
runtime.Semacquire(&sem) Runtime_Semacquire(&sem)
c2 <- true c2 <- true
}() }()
} }
...@@ -59,18 +60,18 @@ func benchmarkSema(b *testing.B, block, work bool) { ...@@ -59,18 +60,18 @@ func benchmarkSema(b *testing.B, block, work bool) {
for atomic.AddInt32(&N, -1) >= 0 { for atomic.AddInt32(&N, -1) >= 0 {
runtime.Gosched() runtime.Gosched()
for g := 0; g < CallsPerSched; g++ { for g := 0; g < CallsPerSched; g++ {
runtime.Semrelease(&sem) Runtime_Semrelease(&sem)
if work { if work {
for i := 0; i < LocalWork; i++ { for i := 0; i < LocalWork; i++ {
foo *= 2 foo *= 2
foo /= 2 foo /= 2
} }
} }
runtime.Semacquire(&sem) Runtime_Semacquire(&sem)
} }
} }
c <- foo == 42 c <- foo == 42
runtime.Semrelease(&sem) Runtime_Semrelease(&sem)
}() }()
} }
if block { if block {
......
...@@ -4,10 +4,7 @@ ...@@ -4,10 +4,7 @@
package sync package sync
import ( import "sync/atomic"
"runtime"
"sync/atomic"
)
// An RWMutex is a reader/writer mutual exclusion lock. // An RWMutex is a reader/writer mutual exclusion lock.
// The lock can be held by an arbitrary number of readers // The lock can be held by an arbitrary number of readers
...@@ -29,7 +26,7 @@ const rwmutexMaxReaders = 1 << 30 ...@@ -29,7 +26,7 @@ const rwmutexMaxReaders = 1 << 30
func (rw *RWMutex) RLock() { func (rw *RWMutex) RLock() {
if atomic.AddInt32(&rw.readerCount, 1) < 0 { if atomic.AddInt32(&rw.readerCount, 1) < 0 {
// A writer is pending, wait for it. // A writer is pending, wait for it.
runtime.Semacquire(&rw.readerSem) runtime_Semacquire(&rw.readerSem)
} }
} }
...@@ -42,7 +39,7 @@ func (rw *RWMutex) RUnlock() { ...@@ -42,7 +39,7 @@ func (rw *RWMutex) RUnlock() {
// A writer is pending. // A writer is pending.
if atomic.AddInt32(&rw.readerWait, -1) == 0 { if atomic.AddInt32(&rw.readerWait, -1) == 0 {
// The last reader unblocks the writer. // The last reader unblocks the writer.
runtime.Semrelease(&rw.writerSem) runtime_Semrelease(&rw.writerSem)
} }
} }
} }
...@@ -60,7 +57,7 @@ func (rw *RWMutex) Lock() { ...@@ -60,7 +57,7 @@ func (rw *RWMutex) Lock() {
r := atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders r := atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders
// Wait for active readers. // Wait for active readers.
if r != 0 && atomic.AddInt32(&rw.readerWait, r) != 0 { if r != 0 && atomic.AddInt32(&rw.readerWait, r) != 0 {
runtime.Semacquire(&rw.writerSem) runtime_Semacquire(&rw.writerSem)
} }
} }
...@@ -75,7 +72,7 @@ func (rw *RWMutex) Unlock() { ...@@ -75,7 +72,7 @@ func (rw *RWMutex) Unlock() {
r := atomic.AddInt32(&rw.readerCount, rwmutexMaxReaders) r := atomic.AddInt32(&rw.readerCount, rwmutexMaxReaders)
// Unblock blocked readers, if any. // Unblock blocked readers, if any.
for i := 0; i < int(r); i++ { for i := 0; i < int(r); i++ {
runtime.Semrelease(&rw.readerSem) runtime_Semrelease(&rw.readerSem)
} }
// Allow other writers to proceed. // Allow other writers to proceed.
rw.w.Unlock() rw.w.Unlock()
......
...@@ -4,10 +4,7 @@ ...@@ -4,10 +4,7 @@
package sync package sync
import ( import "sync/atomic"
"runtime"
"sync/atomic"
)
// A WaitGroup waits for a collection of goroutines to finish. // A WaitGroup waits for a collection of goroutines to finish.
// The main goroutine calls Add to set the number of // The main goroutine calls Add to set the number of
...@@ -60,7 +57,7 @@ func (wg *WaitGroup) Add(delta int) { ...@@ -60,7 +57,7 @@ func (wg *WaitGroup) Add(delta int) {
} }
wg.m.Lock() wg.m.Lock()
for i := int32(0); i < wg.waiters; i++ { for i := int32(0); i < wg.waiters; i++ {
runtime.Semrelease(wg.sema) runtime_Semrelease(wg.sema)
} }
wg.waiters = 0 wg.waiters = 0
wg.sema = nil wg.sema = nil
...@@ -93,5 +90,5 @@ func (wg *WaitGroup) Wait() { ...@@ -93,5 +90,5 @@ func (wg *WaitGroup) Wait() {
} }
s := wg.sema s := wg.sema
wg.m.Unlock() wg.m.Unlock()
runtime.Semacquire(s) runtime_Semacquire(s)
} }
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