diff options
author | Ian Lance Taylor <iant@google.com> | 2015-01-15 00:27:56 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2015-01-15 00:27:56 +0000 |
commit | f8d9fa9e80b57f89e7877ce6cad8a3464879009b (patch) | |
tree | 58a1724fee16d2b03c65678c4dd9b50bb97137a9 /libgo/runtime | |
parent | 6bd3f109d8d8fa58eeccd6b3504721b4f20c00c2 (diff) | |
download | gcc-f8d9fa9e80b57f89e7877ce6cad8a3464879009b.zip gcc-f8d9fa9e80b57f89e7877ce6cad8a3464879009b.tar.gz gcc-f8d9fa9e80b57f89e7877ce6cad8a3464879009b.tar.bz2 |
libgo, compiler: Upgrade libgo to Go 1.4, except for runtime.
This upgrades all of libgo other than the runtime package to
the Go 1.4 release. In Go 1.4 much of the runtime was
rewritten into Go. Merging that code will take more time and
will not change the API, so I'm putting it off for now.
There are a few runtime changes anyhow, to accomodate other
packages that rely on minor modifications to the runtime
support.
The compiler changes slightly to add a one-bit flag to each
type descriptor kind that is stored directly in an interface,
which for gccgo is currently only pointer types. Another
one-bit flag (gcprog) is reserved because it is used by the gc
compiler, but gccgo does not currently use it.
There is another error check in the compiler since I ran
across it during testing.
gotools/:
* Makefile.am (go_cmd_go_files): Sort entries. Add generate.go.
* Makefile.in: Rebuild.
From-SVN: r219627
Diffstat (limited to 'libgo/runtime')
-rw-r--r-- | libgo/runtime/env_posix.c | 6 | ||||
-rw-r--r-- | libgo/runtime/go-assert-interface.c | 2 | ||||
-rw-r--r-- | libgo/runtime/go-can-convert-interface.c | 2 | ||||
-rw-r--r-- | libgo/runtime/go-check-interface.c | 4 | ||||
-rw-r--r-- | libgo/runtime/go-convert-interface.c | 2 | ||||
-rw-r--r-- | libgo/runtime/go-make-slice.c | 2 | ||||
-rw-r--r-- | libgo/runtime/go-reflect-map.c | 8 | ||||
-rw-r--r-- | libgo/runtime/go-type.h | 7 | ||||
-rw-r--r-- | libgo/runtime/go-unsafe-pointer.c | 4 | ||||
-rw-r--r-- | libgo/runtime/go-unsetenv.c | 54 | ||||
-rw-r--r-- | libgo/runtime/malloc.goc | 13 | ||||
-rw-r--r-- | libgo/runtime/mgc0.c | 9 | ||||
-rw-r--r-- | libgo/runtime/netpoll.goc | 36 | ||||
-rw-r--r-- | libgo/runtime/runtime.c | 37 | ||||
-rw-r--r-- | libgo/runtime/runtime.h | 5 | ||||
-rw-r--r-- | libgo/runtime/runtime1.goc | 13 | ||||
-rw-r--r-- | libgo/runtime/time.goc | 11 |
17 files changed, 154 insertions, 61 deletions
diff --git a/libgo/runtime/env_posix.c b/libgo/runtime/env_posix.c index ff4bf0c..ee3e451 100644 --- a/libgo/runtime/env_posix.c +++ b/libgo/runtime/env_posix.c @@ -9,7 +9,7 @@ #include "arch.h" #include "malloc.h" -extern Slice syscall_Envs __asm__ (GOSYM_PREFIX "syscall.Envs"); +extern Slice envs; const byte* runtime_getenv(const char *s) @@ -22,8 +22,8 @@ runtime_getenv(const char *s) bs = (const byte*)s; len = runtime_findnull(bs); - envv = (String*)syscall_Envs.__values; - envc = syscall_Envs.__count; + envv = (String*)envs.__values; + envc = envs.__count; for(i=0; i<envc; i++){ if(envv[i].len <= len) continue; diff --git a/libgo/runtime/go-assert-interface.c b/libgo/runtime/go-assert-interface.c index 2510f9a..427916f 100644 --- a/libgo/runtime/go-assert-interface.c +++ b/libgo/runtime/go-assert-interface.c @@ -36,7 +36,7 @@ __go_assert_interface (const struct __go_type_descriptor *lhs_descriptor, /* A type assertion to an empty interface just returns the object descriptor. */ - __go_assert (lhs_descriptor->__code == GO_INTERFACE); + __go_assert ((lhs_descriptor->__code & GO_CODE_MASK) == GO_INTERFACE); lhs_interface = (const struct __go_interface_type *) lhs_descriptor; if (lhs_interface->__methods.__count == 0) return rhs_descriptor; diff --git a/libgo/runtime/go-can-convert-interface.c b/libgo/runtime/go-can-convert-interface.c index 4de5580..aac889d 100644 --- a/libgo/runtime/go-can-convert-interface.c +++ b/libgo/runtime/go-can-convert-interface.c @@ -31,7 +31,7 @@ __go_can_convert_to_interface ( if (from_descriptor == NULL) return 0; - __go_assert (to_descriptor->__code == GO_INTERFACE); + __go_assert ((to_descriptor->__code & GO_CODE_MASK) == GO_INTERFACE); to_interface = (const struct __go_interface_type *) to_descriptor; to_method_count = to_interface->__methods.__count; to_method = ((const struct __go_interface_method *) diff --git a/libgo/runtime/go-check-interface.c b/libgo/runtime/go-check-interface.c index c29971a..722a421 100644 --- a/libgo/runtime/go-check-interface.c +++ b/libgo/runtime/go-check-interface.c @@ -30,9 +30,9 @@ __go_check_interface_type ( if (lhs_descriptor != rhs_descriptor && !__go_type_descriptors_equal (lhs_descriptor, rhs_descriptor) - && (lhs_descriptor->__code != GO_UNSAFE_POINTER + && ((lhs_descriptor->__code & GO_CODE_MASK) != GO_UNSAFE_POINTER || !__go_is_pointer_type (rhs_descriptor)) - && (rhs_descriptor->__code != GO_UNSAFE_POINTER + && ((rhs_descriptor->__code & GO_CODE_MASK) != GO_UNSAFE_POINTER || !__go_is_pointer_type (lhs_descriptor))) { struct __go_empty_interface panic_arg; diff --git a/libgo/runtime/go-convert-interface.c b/libgo/runtime/go-convert-interface.c index 3eee6bf4..0e8a306 100644 --- a/libgo/runtime/go-convert-interface.c +++ b/libgo/runtime/go-convert-interface.c @@ -41,7 +41,7 @@ __go_convert_interface_2 (const struct __go_type_descriptor *lhs_descriptor, return NULL; } - __go_assert (lhs_descriptor->__code == GO_INTERFACE); + __go_assert ((lhs_descriptor->__code & GO_CODE_MASK) == GO_INTERFACE); lhs_interface = (const struct __go_interface_type *) lhs_descriptor; lhs_method_count = lhs_interface->__methods.__count; lhs_methods = ((const struct __go_interface_method *) diff --git a/libgo/runtime/go-make-slice.c b/libgo/runtime/go-make-slice.c index 855bb17..ccd07e5 100644 --- a/libgo/runtime/go-make-slice.c +++ b/libgo/runtime/go-make-slice.c @@ -30,7 +30,7 @@ __go_make_slice2 (const struct __go_type_descriptor *td, uintptr_t len, uintptr_t size; struct __go_open_array ret; - __go_assert (td->__code == GO_SLICE); + __go_assert ((td->__code & GO_CODE_MASK) == GO_SLICE); std = (const struct __go_slice_type *) td; ilen = (intgo) len; diff --git a/libgo/runtime/go-reflect-map.c b/libgo/runtime/go-reflect-map.c index ab116e8..58e1b34 100644 --- a/libgo/runtime/go-reflect-map.c +++ b/libgo/runtime/go-reflect-map.c @@ -24,7 +24,7 @@ mapaccess (struct __go_map_type *mt, void *m, void *key) { struct __go_map *map = (struct __go_map *) m; - __go_assert (mt->__common.__code == GO_MAP); + __go_assert ((mt->__common.__code & GO_CODE_MASK) == GO_MAP); if (map == NULL) return NULL; else @@ -40,7 +40,7 @@ mapassign (struct __go_map_type *mt, void *m, void *key, void *val) struct __go_map *map = (struct __go_map *) m; void *p; - __go_assert (mt->__common.__code == GO_MAP); + __go_assert ((mt->__common.__code & GO_CODE_MASK) == GO_MAP); if (map == NULL) runtime_panicstring ("assignment to entry in nil map"); p = __go_map_index (map, key, 1); @@ -55,7 +55,7 @@ mapdelete (struct __go_map_type *mt, void *m, void *key) { struct __go_map *map = (struct __go_map *) m; - __go_assert (mt->__common.__code == GO_MAP); + __go_assert ((mt->__common.__code & GO_CODE_MASK) == GO_MAP); if (map == NULL) return; __go_map_delete (map, key); @@ -81,7 +81,7 @@ mapiterinit (struct __go_map_type *mt, void *m) { struct __go_hash_iter *it; - __go_assert (mt->__common.__code == GO_MAP); + __go_assert ((mt->__common.__code & GO_CODE_MASK) == GO_MAP); it = __go_alloc (sizeof (struct __go_hash_iter)); __go_mapiterinit ((struct __go_map *) m, it); return (unsigned char *) it; diff --git a/libgo/runtime/go-type.h b/libgo/runtime/go-type.h index 74e8340..d769335 100644 --- a/libgo/runtime/go-type.h +++ b/libgo/runtime/go-type.h @@ -54,9 +54,11 @@ struct String; #define GO_STRUCT 25 #define GO_UNSAFE_POINTER 26 +#define GO_DIRECT_IFACE (1 << 5) +#define GO_GC_PROG (1 << 6) #define GO_NO_POINTERS (1 << 7) -#define GO_CODE_MASK 0x7f +#define GO_CODE_MASK 0x1f /* For each Go type the compiler constructs one of these structures. This is used for type reflection, interfaces, maps, and reference @@ -310,7 +312,8 @@ struct __go_struct_type static inline _Bool __go_is_pointer_type (const struct __go_type_descriptor *td) { - return td->__code == GO_PTR || td->__code == GO_UNSAFE_POINTER; + return ((td->__code & GO_CODE_MASK) == GO_PTR + || (td->__code & GO_CODE_MASK) == GO_UNSAFE_POINTER); } extern _Bool diff --git a/libgo/runtime/go-unsafe-pointer.c b/libgo/runtime/go-unsafe-pointer.c index 729e9a1..71364f5 100644 --- a/libgo/runtime/go-unsafe-pointer.c +++ b/libgo/runtime/go-unsafe-pointer.c @@ -44,7 +44,7 @@ const uintptr unsafe_Pointer_gc[] = {sizeof(void*), GC_APTR, 0, GC_END}; const struct __go_type_descriptor unsafe_Pointer = { /* __code */ - GO_UNSAFE_POINTER, + GO_UNSAFE_POINTER | GO_DIRECT_IFACE, /* __align */ __alignof (void *), /* __field_align */ @@ -89,7 +89,7 @@ const struct __go_ptr_type pointer_unsafe_Pointer = /* __common */ { /* __code */ - GO_PTR, + GO_PTR | GO_DIRECT_IFACE, /* __align */ __alignof (void *), /* __field_align */ diff --git a/libgo/runtime/go-unsetenv.c b/libgo/runtime/go-unsetenv.c new file mode 100644 index 0000000..409436a --- /dev/null +++ b/libgo/runtime/go-unsetenv.c @@ -0,0 +1,54 @@ +/* go-unsetenv.c -- unset an environment variable from Go. + + Copyright 2015 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. */ + +#include "config.h" + +#include <stddef.h> +#include <stdlib.h> + +#include "go-alloc.h" +#include "runtime.h" +#include "arch.h" +#include "malloc.h" + +/* Unset an environment variable from Go. This is called by + syscall.Unsetenv. */ + +void unsetenv_c (String) __asm__ (GOSYM_PREFIX "syscall.unsetenv_c"); + +void +unsetenv_c (String k) +{ + const byte *ks; + unsigned char *kn; + intgo len; + + ks = k.str; + if (ks == NULL) + ks = (const byte *) ""; + kn = NULL; + +#ifdef HAVE_UNSETENV + + if (ks != NULL && ks[k.len] != 0) + { + // Objects that are explicitly freed must be at least 16 bytes in size, + // so that they are not allocated using tiny alloc. + len = k.len + 1; + if (len < TinySize) + len = TinySize; + kn = __go_alloc (len); + __builtin_memcpy (kn, ks, k.len); + ks = kn; + } + + unsetenv ((const char *) ks); + +#endif /* !defined(HAVE_UNSETENV) */ + + if (kn != NULL) + __go_free (kn); +} diff --git a/libgo/runtime/malloc.goc b/libgo/runtime/malloc.goc index f240ffb..b05c5fa 100644 --- a/libgo/runtime/malloc.goc +++ b/libgo/runtime/malloc.goc @@ -25,6 +25,7 @@ package runtime #define string __reflection #define KindPtr GO_PTR #define KindNoPointers GO_NO_POINTERS +#define kindMask GO_CODE_MASK // GCCGO SPECIFIC CHANGE // @@ -935,7 +936,7 @@ func SetFinalizer(obj Eface, finalizer Eface) { runtime_printf("runtime.SetFinalizer: first argument is nil interface\n"); goto throw; } - if(obj.__type_descriptor->__code != GO_PTR) { + if((obj.__type_descriptor->kind&kindMask) != GO_PTR) { runtime_printf("runtime.SetFinalizer: first argument is %S, not pointer\n", *obj.__type_descriptor->__reflection); goto throw; } @@ -956,14 +957,14 @@ func SetFinalizer(obj Eface, finalizer Eface) { if(!runtime_mlookup(obj.__object, &base, &size, nil) || obj.__object != base) { // As an implementation detail we allow to set finalizers for an inner byte // of an object if it could come from tiny alloc (see mallocgc for details). - if(ot->__element_type == nil || (ot->__element_type->__code&KindNoPointers) == 0 || ot->__element_type->__size >= TinySize) { + if(ot->__element_type == nil || (ot->__element_type->kind&KindNoPointers) == 0 || ot->__element_type->__size >= TinySize) { runtime_printf("runtime.SetFinalizer: pointer not at beginning of allocated block (%p)\n", obj.__object); goto throw; } } if(finalizer.__type_descriptor != nil) { runtime_createfing(); - if(finalizer.__type_descriptor->__code != GO_FUNC) + if((finalizer.__type_descriptor->kind&kindMask) != GO_FUNC) goto badfunc; ft = (const FuncType*)finalizer.__type_descriptor; if(ft->__dotdotdot || ft->__in.__count != 1) @@ -971,12 +972,12 @@ func SetFinalizer(obj Eface, finalizer Eface) { fint = *(Type**)ft->__in.__values; if(__go_type_descriptors_equal(fint, obj.__type_descriptor)) { // ok - same type - } else if(fint->__code == GO_PTR && (fint->__uncommon == nil || fint->__uncommon->__name == nil || obj.type->__uncommon == nil || obj.type->__uncommon->__name == nil) && __go_type_descriptors_equal(((const PtrType*)fint)->__element_type, ((const PtrType*)obj.type)->__element_type)) { + } else if((fint->kind&kindMask) == GO_PTR && (fint->__uncommon == nil || fint->__uncommon->__name == nil || obj.type->__uncommon == nil || obj.type->__uncommon->__name == nil) && __go_type_descriptors_equal(((const PtrType*)fint)->__element_type, ((const PtrType*)obj.type)->__element_type)) { // ok - not same type, but both pointers, // one or the other is unnamed, and same element type, so assignable. - } else if(fint->kind == GO_INTERFACE && ((const InterfaceType*)fint)->__methods.__count == 0) { + } else if((fint->kind&kindMask) == GO_INTERFACE && ((const InterfaceType*)fint)->__methods.__count == 0) { // ok - satisfies empty interface - } else if(fint->kind == GO_INTERFACE && __go_convert_interface_2(fint, obj.__type_descriptor, 1) != nil) { + } else if((fint->kind&kindMask) == GO_INTERFACE && __go_convert_interface_2(fint, obj.__type_descriptor, 1) != nil) { // ok - satisfies non-empty interface } else goto badfunc; diff --git a/libgo/runtime/mgc0.c b/libgo/runtime/mgc0.c index b09054c..0867abf 100644 --- a/libgo/runtime/mgc0.c +++ b/libgo/runtime/mgc0.c @@ -71,6 +71,7 @@ typedef struct __go_map Hmap; #define string __reflection #define KindPtr GO_PTR #define KindNoPointers GO_NO_POINTERS +#define kindMask GO_CODE_MASK // PtrType aka __go_ptr_type #define elem __element_type @@ -946,7 +947,7 @@ scanblock(Workbuf *wbuf, bool keepworking) continue; obj = eface->__object; - if((t->__code & ~KindNoPointers) == KindPtr) { + if((t->__code & kindMask) == KindPtr) { // Only use type information if it is a pointer-containing type. // This matches the GC programs written by cmd/gc/reflect.c's // dgcsym1 in case TPTR32/case TPTR64. See rationale there. @@ -984,7 +985,7 @@ scanblock(Workbuf *wbuf, bool keepworking) continue; obj = iface->__object; - if((t->__code & ~KindNoPointers) == KindPtr) { + if((t->__code & kindMask) == KindPtr) { // Only use type information if it is a pointer-containing type. // This matches the GC programs written by cmd/gc/reflect.c's // dgcsym1 in case TPTR32/case TPTR64. See rationale there. @@ -2369,6 +2370,8 @@ gc(struct gc_args *args) // Sweep all spans eagerly. while(runtime_sweepone() != (uintptr)-1) gcstats.npausesweep++; + // Do an additional mProf_GC, because all 'free' events are now real as well. + runtime_MProf_GC(); } runtime_MProf_GC(); @@ -2514,7 +2517,7 @@ runfinq(void* dummy __attribute__ ((unused))) f = &fb->fin[i]; fint = ((const Type**)f->ft->__in.array)[0]; - if(fint->__code == KindPtr) { + if((fint->__code & kindMask) == KindPtr) { // direct use of pointer param = &f->arg; } else if(((const InterfaceType*)fint)->__methods.__count == 0) { diff --git a/libgo/runtime/netpoll.goc b/libgo/runtime/netpoll.goc index 5308e01..2f3fa45 100644 --- a/libgo/runtime/netpoll.goc +++ b/libgo/runtime/netpoll.goc @@ -79,9 +79,9 @@ static struct static bool netpollblock(PollDesc*, int32, bool); static G* netpollunblock(PollDesc*, int32, bool); -static void deadline(int64, Eface); -static void readDeadline(int64, Eface); -static void writeDeadline(int64, Eface); +static void deadline(Eface, uintptr); +static void readDeadline(Eface, uintptr); +static void writeDeadline(Eface, uintptr); static PollDesc* allocPollDesc(void); static intgo checkerr(PollDesc *pd, int32 mode); @@ -197,22 +197,25 @@ func runtime_pollSetDeadline(pd *PollDesc, d int64, mode int) { // Copy current seq into the timer arg. // Timer func will check the seq against current descriptor seq, // if they differ the descriptor was reused or timers were reset. - pd->rt.arg.type = (Type*)pd->seq; + pd->rt.arg.type = nil; // should be *pollDesc type descriptor. pd->rt.arg.data = pd; + pd->rt.seq = pd->seq; runtime_addtimer(&pd->rt); } else { if(pd->rd > 0) { pd->rt.fv = &readDeadlineFn; pd->rt.when = pd->rd; - pd->rt.arg.type = (Type*)pd->seq; + pd->rt.arg.type = nil; // should be *pollDesc type descriptor. pd->rt.arg.data = pd; + pd->rt.seq = pd->seq; runtime_addtimer(&pd->rt); } if(pd->wd > 0) { pd->wt.fv = &writeDeadlineFn; pd->wt.when = pd->wd; - pd->wt.arg.type = (Type*)pd->seq; + pd->wt.arg.type = nil; // should be *pollDesc type descriptor. pd->wt.arg.data = pd; + pd->wt.seq = pd->seq; runtime_addtimer(&pd->wt); } } @@ -389,19 +392,16 @@ netpollunblock(PollDesc *pd, int32 mode, bool ioready) } static void -deadlineimpl(int64 now, Eface arg, bool read, bool write) +deadlineimpl(Eface arg, uintptr seq, bool read, bool write) { PollDesc *pd; - uint32 seq; G *rg, *wg; - USED(now); pd = (PollDesc*)arg.data; - // This is the seq when the timer was set. - // If it's stale, ignore the timer event. - seq = (uintptr)arg.type; rg = wg = nil; runtime_lock(pd); + // Seq arg is seq when the timer was set. + // If it's stale, ignore the timer event. if(seq != pd->seq) { // The descriptor was reused or timers were reset. runtime_unlock(pd); @@ -429,21 +429,21 @@ deadlineimpl(int64 now, Eface arg, bool read, bool write) } static void -deadline(int64 now, Eface arg) +deadline(Eface arg, uintptr seq) { - deadlineimpl(now, arg, true, true); + deadlineimpl(arg, seq, true, true); } static void -readDeadline(int64 now, Eface arg) +readDeadline(Eface arg, uintptr seq) { - deadlineimpl(now, arg, true, false); + deadlineimpl(arg, seq, true, false); } static void -writeDeadline(int64 now, Eface arg) +writeDeadline(Eface arg, uintptr seq) { - deadlineimpl(now, arg, false, true); + deadlineimpl(arg, seq, false, true); } static PollDesc* diff --git a/libgo/runtime/runtime.c b/libgo/runtime/runtime.c index 496e77b..6e0d164 100644 --- a/libgo/runtime/runtime.c +++ b/libgo/runtime/runtime.c @@ -59,8 +59,8 @@ runtime_gotraceback(bool *crash) static int32 argc; static byte** argv; -extern Slice os_Args __asm__ (GOSYM_PREFIX "os.Args"); -extern Slice syscall_Envs __asm__ (GOSYM_PREFIX "syscall.Envs"); +static Slice args; +Slice envs; void (*runtime_sysargs)(int32, uint8**); @@ -92,9 +92,9 @@ runtime_goargs(void) s = runtime_malloc(argc*sizeof s[0]); for(i=0; i<argc; i++) s[i] = runtime_gostringnocopy((const byte*)argv[i]); - os_Args.__values = (void*)s; - os_Args.__count = argc; - os_Args.__capacity = argc; + args.__values = (void*)s; + args.__count = argc; + args.__capacity = argc; } void @@ -109,9 +109,26 @@ runtime_goenvs_unix(void) s = runtime_malloc(n*sizeof s[0]); for(i=0; i<n; i++) s[i] = runtime_gostringnocopy(argv[argc+1+i]); - syscall_Envs.__values = (void*)s; - syscall_Envs.__count = n; - syscall_Envs.__capacity = n; + envs.__values = (void*)s; + envs.__count = n; + envs.__capacity = n; +} + +// Called from the syscall package. +Slice runtime_envs(void) __asm__ (GOSYM_PREFIX "syscall.runtime_envs"); + +Slice +runtime_envs() +{ + return envs; +} + +Slice os_runtime_args(void) __asm__ (GOSYM_PREFIX "os.runtime_args"); + +Slice +os_runtime_args() +{ + return args; } int32 @@ -127,8 +144,8 @@ runtime_atoi(const byte *p) static struct root_list runtime_roots = { nil, - { { &syscall_Envs, sizeof syscall_Envs }, - { &os_Args, sizeof os_Args }, + { { &envs, sizeof envs }, + { &args, sizeof args }, { nil, 0 } }, }; diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h index c96290a..1f1358a 100644 --- a/libgo/runtime/runtime.h +++ b/libgo/runtime/runtime.h @@ -400,7 +400,7 @@ struct Timers // If this struct changes, adjust ../syscall/net_nacl.go:/runtimeTimer. struct Timer { - int32 i; // heap index + intgo i; // heap index // Timer wakes up at when, and then at when+period, ... (period > 0 only) // each time calling f(now, arg) in the timer goroutine, so f must be @@ -409,6 +409,7 @@ struct Timer int64 period; FuncVal *fv; Eface arg; + uintptr seq; }; // Lock-free stack node. @@ -774,8 +775,6 @@ void runtime_printany(Eface) __asm__ (GOSYM_PREFIX "runtime.Printany"); void runtime_newTypeAssertionError(const String*, const String*, const String*, const String*, Eface*) __asm__ (GOSYM_PREFIX "runtime.NewTypeAssertionError"); -void runtime_newErrorString(String, Eface*) - __asm__ (GOSYM_PREFIX "runtime.NewErrorString"); void runtime_newErrorCString(const char*, Eface*) __asm__ (GOSYM_PREFIX "runtime.NewErrorCString"); diff --git a/libgo/runtime/runtime1.goc b/libgo/runtime/runtime1.goc index e643965..6d8f09a 100644 --- a/libgo/runtime/runtime1.goc +++ b/libgo/runtime/runtime1.goc @@ -74,3 +74,16 @@ func sync.runtime_procPin() (p int) { func sync.runtime_procUnpin() { runtime_m()->locks--; } + +func sync_atomic.runtime_procPin() (p int) { + M *mp; + + mp = runtime_m(); + // Disable preemption. + mp->locks++; + p = mp->p->id; +} + +func sync_atomic.runtime_procUnpin() { + runtime_m()->locks--; +} diff --git a/libgo/runtime/time.goc b/libgo/runtime/time.goc index cb13bbf..ee24b9c 100644 --- a/libgo/runtime/time.goc +++ b/libgo/runtime/time.goc @@ -66,9 +66,9 @@ static void siftdown(int32); // Ready the goroutine e.data. static void -ready(int64 now, Eface e) +ready(Eface e, uintptr seq) { - USED(now); + USED(seq); runtime_ready(e.__object); } @@ -91,6 +91,7 @@ runtime_tsleep(int64 ns, const char *reason) t.period = 0; t.fv = &readyv; t.arg.__object = g; + t.seq = 0; runtime_lock(&timers); addtimer(&t); runtime_parkunlock(&timers, reason); @@ -203,8 +204,9 @@ timerproc(void* dummy __attribute__ ((unused))) int64 delta, now; Timer *t; FuncVal *fv; - void (*f)(int64, Eface); + void (*f)(Eface, uintptr); Eface arg; + uintptr seq; for(;;) { runtime_lock(&timers); @@ -233,9 +235,10 @@ timerproc(void* dummy __attribute__ ((unused))) fv = t->fv; f = (void*)t->fv->fn; arg = t->arg; + seq = t->seq; runtime_unlock(&timers); __go_set_closure(fv); - f(now, arg); + f(arg, seq); // clear f and arg to avoid leak while sleeping for next timer f = nil; |