summaryrefslogtreecommitdiff
path: root/libgo/runtime
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2015-01-15 00:27:56 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2015-01-15 00:27:56 +0000
commitf11c215565ea0c863197b9666581d69c225619c2 (patch)
tree58a1724fee16d2b03c65678c4dd9b50bb97137a9 /libgo/runtime
parent2bbc72db3287d2bff87b9640e85830337aac0672 (diff)
downloadgcc-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.c6
-rw-r--r--libgo/runtime/go-assert-interface.c2
-rw-r--r--libgo/runtime/go-can-convert-interface.c2
-rw-r--r--libgo/runtime/go-check-interface.c4
-rw-r--r--libgo/runtime/go-convert-interface.c2
-rw-r--r--libgo/runtime/go-make-slice.c2
-rw-r--r--libgo/runtime/go-reflect-map.c8
-rw-r--r--libgo/runtime/go-type.h7
-rw-r--r--libgo/runtime/go-unsafe-pointer.c4
-rw-r--r--libgo/runtime/go-unsetenv.c54
-rw-r--r--libgo/runtime/malloc.goc13
-rw-r--r--libgo/runtime/mgc0.c9
-rw-r--r--libgo/runtime/netpoll.goc36
-rw-r--r--libgo/runtime/runtime.c37
-rw-r--r--libgo/runtime/runtime.h5
-rw-r--r--libgo/runtime/runtime1.goc13
-rw-r--r--libgo/runtime/time.goc11
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;