diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-01-15 00:27:56 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-01-15 00:27:56 +0000 |
commit | f11c215565ea0c863197b9666581d69c225619c2 (patch) | |
tree | 58a1724fee16d2b03c65678c4dd9b50bb97137a9 /libgo/runtime | |
parent | 2bbc72db3287d2bff87b9640e85830337aac0672 (diff) | |
download | gcc-f11c215565ea0c863197b9666581d69c225619c2.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@219627 138bc75d-0d04-0410-961f-82ee72b054a4
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 ff4bf0c5b1f..ee3e4514554 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 2510f9aef8b..427916f8c42 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 4de558077a7..aac889d346d 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 c29971adac2..722a4219ab2 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 3eee6bf4a8f..0e8a3062435 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 855bb17ce59..ccd07e5ac51 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 ab116e85950..58e1b34a1ea 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 74e83400598..d7693353039 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 729e9a19736..71364f511b4 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 00000000000..409436a0d3f --- /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 f240ffbd8ee..b05c5fa4e22 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 b09054c02cc..0867abfd168 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 5308e01c8e9..2f3fa455f3d 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 496e77b75c5..6e0d164707d 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 c96290a0b06..1f1358ae947 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 e643965fda5..6d8f09a6c5f 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 cb13bbf39a2..ee24b9c52df 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; |