mirror of https://github.com/golang/go.git
runtime: eliminate parfor ctx field
Prior to the conversion of the runtime to Go, this void* was necessary to get closure information in to C callbacks. There are no more C callbacks and parfor is perfectly capable of invoking a Go closure now, so eliminate ctx and all of its unsafe-ness. (Plus, the runtime currently doesn't use ctx for anything.) Change-Id: I39fc53b7dd3d7f660710abc76b0d831bfc6296d8 Reviewed-on: https://go-review.googlesource.com/3395 Reviewed-by: Russ Cox <rsc@golang.org> Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
This commit is contained in:
parent
8e2bb7bb4a
commit
ebbdf2a14c
|
|
@ -41,7 +41,6 @@ type ParFor struct {
|
|||
Nthr uint32
|
||||
thrseq uint32
|
||||
Cnt uint32
|
||||
Ctx *byte
|
||||
wait bool
|
||||
}
|
||||
|
||||
|
|
@ -53,9 +52,9 @@ func NewParFor(nthrmax uint32) *ParFor {
|
|||
return desc
|
||||
}
|
||||
|
||||
func ParForSetup(desc *ParFor, nthr, n uint32, ctx *byte, wait bool, body func(*ParFor, uint32)) {
|
||||
func ParForSetup(desc *ParFor, nthr, n uint32, wait bool, body func(*ParFor, uint32)) {
|
||||
systemstack(func() {
|
||||
parforsetup((*parfor)(unsafe.Pointer(desc)), nthr, n, unsafe.Pointer(ctx), wait,
|
||||
parforsetup((*parfor)(unsafe.Pointer(desc)), nthr, n, wait,
|
||||
*(*func(*parfor, uint32))(unsafe.Pointer(&body)))
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1490,7 +1490,7 @@ func gcscan_m() {
|
|||
work.ndone = 0
|
||||
work.nproc = 1 // For now do not do this in parallel.
|
||||
// ackgcphase is not needed since we are not scanning running goroutines.
|
||||
parforsetup(work.markfor, work.nproc, uint32(_RootCount+local_allglen), nil, false, markroot)
|
||||
parforsetup(work.markfor, work.nproc, uint32(_RootCount+local_allglen), false, markroot)
|
||||
parfordo(work.markfor)
|
||||
|
||||
lock(&allglock)
|
||||
|
|
@ -1588,7 +1588,7 @@ func gc(start_time int64, eagersweep bool) {
|
|||
traceGCScanStart()
|
||||
}
|
||||
|
||||
parforsetup(work.markfor, work.nproc, uint32(_RootCount+allglen), nil, false, markroot)
|
||||
parforsetup(work.markfor, work.nproc, uint32(_RootCount+allglen), false, markroot)
|
||||
if work.nproc > 1 {
|
||||
noteclear(&work.alldone)
|
||||
helpgc(int32(work.nproc))
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ type parfor struct {
|
|||
nthr uint32 // total number of threads
|
||||
thrseq uint32 // thread id sequencer
|
||||
cnt uint32 // iteration space [0, cnt)
|
||||
ctx unsafe.Pointer // arbitrary user context
|
||||
wait bool // if true, wait while all threads finish processing,
|
||||
// otherwise parfor may return while other threads are still working
|
||||
|
||||
|
|
@ -58,9 +57,7 @@ func parforalloc(nthrmax uint32) *parfor {
|
|||
// If wait is false, parfordo may return when there is a small amount
|
||||
// of work left, under the assumption that another thread has that
|
||||
// work well in hand.
|
||||
// The opaque user context ctx is recorded as desc.ctx and can be used by body.
|
||||
// TODO(austin): Remove ctx in favor of using a closure for body.
|
||||
func parforsetup(desc *parfor, nthr, n uint32, ctx unsafe.Pointer, wait bool, body func(*parfor, uint32)) {
|
||||
func parforsetup(desc *parfor, nthr, n uint32, wait bool, body func(*parfor, uint32)) {
|
||||
if desc == nil || nthr == 0 || nthr > uint32(len(desc.thr)) || body == nil {
|
||||
print("desc=", desc, " nthr=", nthr, " count=", n, " body=", body, "\n")
|
||||
throw("parfor: invalid args")
|
||||
|
|
@ -71,7 +68,6 @@ func parforsetup(desc *parfor, nthr, n uint32, ctx unsafe.Pointer, wait bool, bo
|
|||
desc.nthr = nthr
|
||||
desc.thrseq = 0
|
||||
desc.cnt = n
|
||||
desc.ctx = ctx
|
||||
desc.wait = wait
|
||||
desc.nsteal = 0
|
||||
desc.nstealcnt = 0
|
||||
|
|
|
|||
|
|
@ -10,11 +10,8 @@ package runtime_test
|
|||
import (
|
||||
. "runtime"
|
||||
"testing"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var gdata []uint64
|
||||
|
||||
// Simple serial sanity test for parallelfor.
|
||||
func TestParFor(t *testing.T) {
|
||||
const P = 1
|
||||
|
|
@ -24,12 +21,7 @@ func TestParFor(t *testing.T) {
|
|||
data[i] = i
|
||||
}
|
||||
desc := NewParFor(P)
|
||||
// Avoid making func a closure: parfor cannot invoke them.
|
||||
// Since it doesn't happen in the C code, it's not worth doing
|
||||
// just for the test.
|
||||
gdata = data
|
||||
ParForSetup(desc, P, N, nil, true, func(desc *ParFor, i uint32) {
|
||||
data := gdata
|
||||
ParForSetup(desc, P, N, true, func(desc *ParFor, i uint32) {
|
||||
data[i] = data[i]*data[i] + 1
|
||||
})
|
||||
ParForDo(desc)
|
||||
|
|
@ -49,9 +41,8 @@ func TestParFor2(t *testing.T) {
|
|||
data[i] = i
|
||||
}
|
||||
desc := NewParFor(P)
|
||||
ParForSetup(desc, P, N, (*byte)(unsafe.Pointer(&data)), false, func(desc *ParFor, i uint32) {
|
||||
d := *(*[]uint64)(unsafe.Pointer(desc.Ctx))
|
||||
d[i] = d[i]*d[i] + 1
|
||||
ParForSetup(desc, P, N, false, func(desc *ParFor, i uint32) {
|
||||
data[i] = data[i]*data[i] + 1
|
||||
})
|
||||
for p := 0; p < P; p++ {
|
||||
ParForDo(desc)
|
||||
|
|
@ -70,7 +61,7 @@ func TestParForSetup(t *testing.T) {
|
|||
desc := NewParFor(P)
|
||||
for n := uint32(0); n < N; n++ {
|
||||
for p := uint32(1); p <= P; p++ {
|
||||
ParForSetup(desc, p, n, nil, true, func(desc *ParFor, i uint32) {})
|
||||
ParForSetup(desc, p, n, true, func(desc *ParFor, i uint32) {})
|
||||
sum := uint32(0)
|
||||
size0 := uint32(0)
|
||||
end0 := uint32(0)
|
||||
|
|
@ -113,9 +104,7 @@ func TestParForParallel(t *testing.T) {
|
|||
P := GOMAXPROCS(-1)
|
||||
c := make(chan bool, P)
|
||||
desc := NewParFor(uint32(P))
|
||||
gdata = data
|
||||
ParForSetup(desc, uint32(P), uint32(N), nil, false, func(desc *ParFor, i uint32) {
|
||||
data := gdata
|
||||
ParForSetup(desc, uint32(P), uint32(N), false, func(desc *ParFor, i uint32) {
|
||||
data[i] = data[i]*data[i] + 1
|
||||
})
|
||||
for p := 1; p < P; p++ {
|
||||
|
|
|
|||
Loading…
Reference in New Issue