]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: remove untyped allocation of ParFor
authorRuss Cox <rsc@golang.org>
Tue, 16 Sep 2014 15:03:11 +0000 (11:03 -0400)
committerRuss Cox <rsc@golang.org>
Tue, 16 Sep 2014 15:03:11 +0000 (11:03 -0400)
Now it's two allocations. I don't see much downside to that,
since the two pieces were in different cache lines anyway.

Rename 'conservative' to 'cgo_conservative_type' and make
clear that _cgo_allocate is the only allowed user.

This depends on CL 141490043, which removes the other
use of conservative (in defer).

LGTM=dvyukov, iant
R=khr, dvyukov, iant
CC=golang-codereviews, rlh
https://golang.org/cl/139610043

12 files changed:
misc/cgo/test/callback.go
misc/cgo/test/callback_c_gc.c
misc/cgo/test/callback_c_gccgo.c
misc/cgo/test/cgo_test.go
misc/cgo/test/exports.go
src/cmd/api/goapi.go
src/runtime/cgocallback.go
src/runtime/malloc.c
src/runtime/malloc.h
src/runtime/mgc0.go
src/runtime/parfor.c
src/runtime/runtime.go

index 281e79494e39cf88343f4953e6f74449134d0b25..a7f1a3ecd67a8a35ecf8927f2ff3e03d0f8b8bb9 100644 (file)
@@ -9,6 +9,7 @@ void callback(void *f);
 void callGoFoo(void);
 void callGoStackCheck(void);
 void callPanic(void);
+void callCgoAllocate(void);
 */
 import "C"
 
@@ -207,6 +208,10 @@ func testPanicFromC(t *testing.T) {
        C.callPanic()
 }
 
+func testAllocateFromC(t *testing.T) {
+       C.callCgoAllocate() // crashes or exits on failure
+}
+
 func testCallbackStack(t *testing.T) {
        // Make cgo call and callback with different amount of stack stack available.
        // We do not do any explicit checks, just ensure that it does not crash.
index 8953b74a67a8948f87f3ad98afe07d55875a4f5e..32bfed0c02ca0cc5d22403f87e40f511730aaf8e 100644 (file)
@@ -5,11 +5,15 @@
 // +build gc
 
 #include "_cgo_export.h"
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
 
 /* Test calling panic from C.  This is what SWIG does.  */
 
 extern void crosscall2(void (*fn)(void *, int), void *, int);
 extern void _cgo_panic(void *, int);
+extern void _cgo_allocate(void *, int);
 
 void
 callPanic(void)
@@ -19,3 +23,48 @@ callPanic(void)
        crosscall2(_cgo_panic, &a, sizeof a);
        *(int*)1 = 1;
 }
+
+/* Test calling cgo_allocate from C. This is what SWIG does. */
+
+typedef struct List List;
+struct List
+{
+       List *next;
+       int x;
+};
+
+void
+callCgoAllocate(void)
+{
+       int i;
+       struct { size_t n; void *ret; } a;
+       List *l, *head, **tail;
+       
+       head = 0;
+       tail = &head;
+       for(i=0; i<100; i++) {
+               a.n = sizeof *l;
+               crosscall2(_cgo_allocate, &a, sizeof a);
+               l = a.ret;
+               l->x = i;
+               l->next = 0;
+               *tail = l;
+               tail = &l->next;
+       }
+       
+       gc();
+       
+       l = head;
+       for(i=0; i<100; i++) {
+               if(l->x != i) {
+                       fprintf(stderr, "callCgoAllocate: lost memory\n");
+                       exit(2);
+               }
+               l = l->next;
+       }
+       if(l != 0) {
+               fprintf(stderr, "callCgoAllocate: lost memory\n");
+               exit(2);
+       }
+}
+
index 0ea7296c6247cc4823692ff42d5db56c1d680c0a..d92dca00937d8f1ed5627659189852fefcd7655a 100644 (file)
@@ -5,13 +5,59 @@
 // +build gccgo
 
 #include "_cgo_export.h"
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
 
 /* Test calling panic from C.  This is what SWIG does.  */
 
 extern void _cgo_panic(const char *);
+extern void *_cgo_allocate(size_t);
 
 void
 callPanic(void)
 {
        _cgo_panic("panic from C");
 }
+
+/* Test calling cgo_allocate from C. This is what SWIG does. */
+
+typedef struct List List;
+struct List
+{
+       List *next;
+       int x;
+};
+
+void
+callCgoAllocate(void)
+{
+       int i;
+       List *l, *head, **tail;
+       
+       head = 0;
+       tail = &head;
+       for(i=0; i<100; i++) {
+               l = _cgo_allocate(sizeof *l);
+               l->x = i;
+               l->next = 0;
+               *tail = l;
+               tail = &l->next;
+       }
+       
+       gc();
+       
+       l = head;
+       for(i=0; i<100; i++) {
+               if(l->x != i) {
+                       fprintf(stderr, "callCgoAllocate: lost memory\n");
+                       exit(2);
+               }
+               l = l->next;
+       }
+       if(l != 0) {
+               fprintf(stderr, "callCgoAllocate: lost memory\n");
+               exit(2);
+       }
+}
+
index 3cc83060fce11fcf786b4d82ba5d65818b65711f..3783af061c77532d3312228016d0a46f8f1b2b20 100644 (file)
@@ -23,6 +23,7 @@ func TestCallbackPanic(t *testing.T)       { testCallbackPanic(t) }
 func TestCallbackPanicLoop(t *testing.T)   { testCallbackPanicLoop(t) }
 func TestCallbackPanicLocked(t *testing.T) { testCallbackPanicLocked(t) }
 func TestPanicFromC(t *testing.T)          { testPanicFromC(t) }
+func TestAllocateFromC(t *testing.T)       { testAllocateFromC(t) }
 func TestZeroArgCallback(t *testing.T)     { testZeroArgCallback(t) }
 func TestBlocking(t *testing.T)            { testBlocking(t) }
 func Test1328(t *testing.T)                { test1328(t) }
index f96c60b004e6203c154c1ca03203213f6a1439bb..4fe1703a60db6058150cd375312e40a5c73bf750 100644 (file)
@@ -5,8 +5,14 @@
 package cgotest
 
 import "C"
+import "runtime"
 
 //export ReturnIntLong
 func ReturnIntLong() (int, C.long) {
        return 1, 2
 }
+
+//export gc
+func gc() {
+       runtime.GC()
+}
index 78b7d6edf16f82e685eeb719ee421fa310c4efcb..5a8c87603395fec73e5823044585998a39447ebf 100644 (file)
@@ -404,6 +404,7 @@ func (w *Walker) parseFile(dir, file string) (*ast.File, error) {
                        " mutex struct{};" +
                        " note struct{};" +
                        " p struct{};" +
+                       " parfor struct{};" +
                        " slicetype struct{};" +
                        " stkframe struct{};" +
                        " sudog struct{};" +
index b3edfb672a8783a73d37a76b79522918027454d2..1e1b576072d3b1c58082e09070ec69c504a880cd 100644 (file)
@@ -21,7 +21,7 @@ import "unsafe"
 // Either we need to add types or we need to stop using it.
 
 func _cgo_allocate_internal(len uintptr) unsafe.Pointer {
-       ret := mallocgc(len, conservative, 0)
+       ret := unsafe.Pointer(&make([]unsafe.Pointer, (len+ptrSize-1)/ptrSize)[0])
        c := new(cgomal)
        c.alloc = ret
        gp := getg()
index e5c7e095928dfe6eb2ab5a7cf4c4a5f7e8ee5422..cfb698ac216b853b4413d3e73f8123bf9b42a6ff 100644 (file)
@@ -21,10 +21,6 @@ MHeap runtime·mheap;
 #pragma dataflag NOPTR
 MStats runtime·memstats;
 
-Type* runtime·conservative;
-
-void runtime·gc_notype_ptr(Eface*);
-
 int32
 runtime·mlookup(void *v, byte **base, uintptr *size, MSpan **sp)
 {
@@ -115,7 +111,6 @@ runtime·mallocinit(void)
        uintptr limit;
        uint64 i;
        bool reserved;
-       Eface notype_eface;
 
        p = nil;
        p_size = 0;
@@ -243,9 +238,6 @@ runtime·mallocinit(void)
        // Initialize the rest of the allocator.        
        runtime·MHeap_Init(&runtime·mheap);
        g->m->mcache = runtime·allocmcache();
-
-       runtime·gc_notype_ptr(&notype_eface);
-       runtime·conservative = notype_eface.type;
 }
 
 void*
index 60b87da78c14759e74062eb35836936ab802f722..c496cc70e3b66aa3eb3fa4631768dddc728ec6ea 100644 (file)
@@ -528,7 +528,6 @@ void*       runtime·cnewarray(Type*, intgo);
 void   runtime·tracealloc(void*, uintptr, Type*);
 void   runtime·tracefree(void*, uintptr);
 void   runtime·tracegc(void);
-extern Type*   runtime·conservative;
 
 int32  runtime·gcpercent;
 int32  runtime·readgogc(void);
index bd5ebab46e00073e4a7b688d379a8f6c907ad4c8..0e17599c2ad6229333b0a68fd0f6676d62a5a4ed 100644 (file)
@@ -21,15 +21,6 @@ func gc_itab_ptr(ret *interface{}) {
        *ret = (*itab)(nil)
 }
 
-// Type used for "conservative" allocations in C code.
-type notype [8]*byte
-
-// Called from C. Returns the Go type used for C allocations w/o type.
-func gc_notype_ptr(ret *interface{}) {
-       var x notype
-       *ret = x
-}
-
 func gc_unixnanotime(now *int64) {
        sec, nsec := timenow()
        *now = sec*1e9 + int64(nsec)
index ba17303b237c1f6612164b243b66b04ba5cb5ef6..e44956840089cf6c2f55c1ea0eb521f7cb9d04e7 100644 (file)
@@ -21,19 +21,6 @@ struct ParForThread
        byte pad[CacheLineSize];
 };
 
-ParFor*
-runtime·parforalloc(uint32 nthrmax)
-{
-       ParFor *desc;
-
-       // The ParFor object is followed by CacheLineSize padding
-       // and then nthrmax ParForThread.
-       desc = (ParFor*)runtime·mallocgc(sizeof(ParFor) + CacheLineSize + nthrmax * sizeof(ParForThread), runtime·conservative, 0);
-       desc->thr = (ParForThread*)((byte*)(desc+1) + CacheLineSize);
-       desc->nthrmax = nthrmax;
-       return desc;
-}
-
 void
 runtime·parforsetup(ParFor *desc, uint32 nthr, uint32 n, void *ctx, bool wait, void (*body)(ParFor*, uint32))
 {
index d4f7c64a52cb97e970f89ea6e6ba666caf396b86..dbaea45a66216fce84aac5a61f8160cd22ffea70 100644 (file)
@@ -39,3 +39,11 @@ func tickspersecond() int64 {
 func makeStringSlice(n int) []string {
        return make([]string, n)
 }
+
+// TODO: Move to parfor.go when parfor.c becomes parfor.go.
+func parforalloc(nthrmax uint32) *parfor {
+       return &parfor{
+               thr:     &make([]parforthread, nthrmax)[0],
+               nthrmax: nthrmax,
+       }
+}