runtime: Support -buildmode=c-shared.
These changes permit using the go tool from the upcoming Go 1.5 release with -buildmode=c-archive to build gccgo code into an archive file that can be linked with a C program. From-SVN: r222594
This commit is contained in:
parent
2f79da78f3
commit
081564faed
7 changed files with 333 additions and 8 deletions
|
@ -105,7 +105,7 @@ toolexeclib_LTLIBRARIES = libgo-llgo.la
|
|||
toolexeclib_LIBRARIES = libgobegin-llgo.a
|
||||
else
|
||||
toolexeclib_LTLIBRARIES = libgo.la
|
||||
toolexeclib_LIBRARIES = libgobegin.a libnetgo.a
|
||||
toolexeclib_LIBRARIES = libgobegin.a libgolibbegin.a libnetgo.a
|
||||
endif
|
||||
|
||||
toolexeclibgo_DATA = \
|
||||
|
@ -2036,6 +2036,11 @@ libgobegin_llgo_a_SOURCES = \
|
|||
libgobegin_a_CFLAGS = $(AM_CFLAGS) -fPIC
|
||||
libgobegin_llgo_a_CFLAGS = $(AM_CFLAGS) -fPIC
|
||||
|
||||
libgolibbegin_a_SOURCES = \
|
||||
runtime/go-libmain.c
|
||||
|
||||
libgolibbegin_a_CFLAGS = $(AM_CFLAGS) -fPIC
|
||||
|
||||
libnetgo_a_SOURCES = $(go_netgo_files)
|
||||
libnetgo_a_LIBADD = netgo.o
|
||||
|
||||
|
@ -2067,7 +2072,7 @@ BUILDPACKAGE = \
|
|||
BUILDNETGO = \
|
||||
$(MKDIR_P) $(@D); \
|
||||
files=`echo $^ | sed -e 's/[^ ]*\.gox//g'`; \
|
||||
$(GOCOMPILE) -I . -c -fgo-pkgpath=net -o $@ $$files
|
||||
$(GOCOMPILE) -I . -c -fPIC -fgo-pkgpath=net -o $@ $$files
|
||||
|
||||
GOTESTFLAGS =
|
||||
GOBENCH =
|
||||
|
|
|
@ -136,6 +136,10 @@ libgobegin_a_AR = $(AR) $(ARFLAGS)
|
|||
libgobegin_a_LIBADD =
|
||||
am_libgobegin_a_OBJECTS = libgobegin_a-go-main.$(OBJEXT)
|
||||
libgobegin_a_OBJECTS = $(am_libgobegin_a_OBJECTS)
|
||||
libgolibbegin_a_AR = $(AR) $(ARFLAGS)
|
||||
libgolibbegin_a_LIBADD =
|
||||
am_libgolibbegin_a_OBJECTS = libgolibbegin_a-go-libmain.$(OBJEXT)
|
||||
libgolibbegin_a_OBJECTS = $(am_libgolibbegin_a_OBJECTS)
|
||||
libnetgo_a_AR = $(AR) $(ARFLAGS)
|
||||
libnetgo_a_DEPENDENCIES = netgo.o
|
||||
am__objects_1 =
|
||||
|
@ -264,8 +268,8 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
|||
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
SOURCES = $(libgobegin_llgo_a_SOURCES) $(libgobegin_a_SOURCES) \
|
||||
$(libnetgo_a_SOURCES) $(libgo_llgo_la_SOURCES) \
|
||||
$(libgo_la_SOURCES)
|
||||
$(libgolibbegin_a_SOURCES) $(libnetgo_a_SOURCES) \
|
||||
$(libgo_llgo_la_SOURCES) $(libgo_la_SOURCES)
|
||||
MULTISRCTOP =
|
||||
MULTIBUILDTOP =
|
||||
MULTIDIRS =
|
||||
|
@ -532,7 +536,7 @@ AM_MAKEFLAGS = \
|
|||
FLAGS_TO_PASS = $(AM_MAKEFLAGS)
|
||||
@GOC_IS_LLGO_FALSE@toolexeclib_LTLIBRARIES = libgo.la
|
||||
@GOC_IS_LLGO_TRUE@toolexeclib_LTLIBRARIES = libgo-llgo.la
|
||||
@GOC_IS_LLGO_FALSE@toolexeclib_LIBRARIES = libgobegin.a libnetgo.a
|
||||
@GOC_IS_LLGO_FALSE@toolexeclib_LIBRARIES = libgobegin.a libgolibbegin.a libnetgo.a
|
||||
@GOC_IS_LLGO_TRUE@toolexeclib_LIBRARIES = libgobegin-llgo.a
|
||||
toolexeclibgo_DATA = \
|
||||
bufio.gox \
|
||||
|
@ -2102,6 +2106,10 @@ libgobegin_llgo_a_SOURCES = \
|
|||
# Use -fPIC for libgobegin so that it can be put in a PIE.
|
||||
libgobegin_a_CFLAGS = $(AM_CFLAGS) -fPIC
|
||||
libgobegin_llgo_a_CFLAGS = $(AM_CFLAGS) -fPIC
|
||||
libgolibbegin_a_SOURCES = \
|
||||
runtime/go-libmain.c
|
||||
|
||||
libgolibbegin_a_CFLAGS = $(AM_CFLAGS) -fPIC
|
||||
libnetgo_a_SOURCES = $(go_netgo_files)
|
||||
libnetgo_a_LIBADD = netgo.o
|
||||
LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
|
||||
|
@ -2132,7 +2140,7 @@ BUILDPACKAGE = \
|
|||
BUILDNETGO = \
|
||||
$(MKDIR_P) $(@D); \
|
||||
files=`echo $^ | sed -e 's/[^ ]*\.gox//g'`; \
|
||||
$(GOCOMPILE) -I . -c -fgo-pkgpath=net -o $@ $$files
|
||||
$(GOCOMPILE) -I . -c -fPIC -fgo-pkgpath=net -o $@ $$files
|
||||
|
||||
GOTESTFLAGS =
|
||||
GOBENCH =
|
||||
|
@ -2421,6 +2429,10 @@ libgobegin.a: $(libgobegin_a_OBJECTS) $(libgobegin_a_DEPENDENCIES)
|
|||
-rm -f libgobegin.a
|
||||
$(libgobegin_a_AR) libgobegin.a $(libgobegin_a_OBJECTS) $(libgobegin_a_LIBADD)
|
||||
$(RANLIB) libgobegin.a
|
||||
libgolibbegin.a: $(libgolibbegin_a_OBJECTS) $(libgolibbegin_a_DEPENDENCIES)
|
||||
-rm -f libgolibbegin.a
|
||||
$(libgolibbegin_a_AR) libgolibbegin.a $(libgolibbegin_a_OBJECTS) $(libgolibbegin_a_LIBADD)
|
||||
$(RANLIB) libgolibbegin.a
|
||||
libnetgo.a: $(libnetgo_a_OBJECTS) $(libnetgo_a_DEPENDENCIES)
|
||||
-rm -f libnetgo.a
|
||||
$(libnetgo_a_AR) libnetgo.a $(libnetgo_a_OBJECTS) $(libnetgo_a_LIBADD)
|
||||
|
@ -2546,6 +2558,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lfstack.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgobegin_a-go-main.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgobegin_llgo_a-go-main.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgolibbegin_a-go-libmain.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lock_futex.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lock_sema.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/malloc.Plo@am__quote@
|
||||
|
@ -2631,6 +2644,20 @@ libgobegin_a-go-main.obj: runtime/go-main.c
|
|||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgobegin_a_CFLAGS) $(CFLAGS) -c -o libgobegin_a-go-main.obj `if test -f 'runtime/go-main.c'; then $(CYGPATH_W) 'runtime/go-main.c'; else $(CYGPATH_W) '$(srcdir)/runtime/go-main.c'; fi`
|
||||
|
||||
libgolibbegin_a-go-libmain.o: runtime/go-libmain.c
|
||||
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgolibbegin_a_CFLAGS) $(CFLAGS) -MT libgolibbegin_a-go-libmain.o -MD -MP -MF $(DEPDIR)/libgolibbegin_a-go-libmain.Tpo -c -o libgolibbegin_a-go-libmain.o `test -f 'runtime/go-libmain.c' || echo '$(srcdir)/'`runtime/go-libmain.c
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libgolibbegin_a-go-libmain.Tpo $(DEPDIR)/libgolibbegin_a-go-libmain.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-libmain.c' object='libgolibbegin_a-go-libmain.o' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgolibbegin_a_CFLAGS) $(CFLAGS) -c -o libgolibbegin_a-go-libmain.o `test -f 'runtime/go-libmain.c' || echo '$(srcdir)/'`runtime/go-libmain.c
|
||||
|
||||
libgolibbegin_a-go-libmain.obj: runtime/go-libmain.c
|
||||
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgolibbegin_a_CFLAGS) $(CFLAGS) -MT libgolibbegin_a-go-libmain.obj -MD -MP -MF $(DEPDIR)/libgolibbegin_a-go-libmain.Tpo -c -o libgolibbegin_a-go-libmain.obj `if test -f 'runtime/go-libmain.c'; then $(CYGPATH_W) 'runtime/go-libmain.c'; else $(CYGPATH_W) '$(srcdir)/runtime/go-libmain.c'; fi`
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libgolibbegin_a-go-libmain.Tpo $(DEPDIR)/libgolibbegin_a-go-libmain.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-libmain.c' object='libgolibbegin_a-go-libmain.obj' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgolibbegin_a_CFLAGS) $(CFLAGS) -c -o libgolibbegin_a-go-libmain.obj `if test -f 'runtime/go-libmain.c'; then $(CYGPATH_W) 'runtime/go-libmain.c'; else $(CYGPATH_W) '$(srcdir)/runtime/go-libmain.c'; fi`
|
||||
|
||||
go-append.lo: runtime/go-append.c
|
||||
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-append.lo -MD -MP -MF $(DEPDIR)/go-append.Tpo -c -o go-append.lo `test -f 'runtime/go-append.c' || echo '$(srcdir)/'`runtime/go-append.c
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-append.Tpo $(DEPDIR)/go-append.Plo
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
#include "go-alloc.h"
|
||||
#include "interface.h"
|
||||
#include "go-panic.h"
|
||||
#include "go-type.h"
|
||||
|
||||
extern void __go_receive (ChanType *, Hchan *, byte *);
|
||||
|
||||
/* Prepare to call from code written in Go to code written in C or
|
||||
C++. This takes the current goroutine out of the Go scheduler, as
|
||||
|
@ -86,6 +89,15 @@ syscall_cgocallback ()
|
|||
|
||||
runtime_exitsyscall ();
|
||||
|
||||
if (runtime_g ()->ncgo == 0)
|
||||
{
|
||||
/* The C call to Go came from a thread not currently running any
|
||||
Go. In the case of -buildmode=c-archive or c-shared, this
|
||||
call may be coming in before package initialization is
|
||||
complete. Wait until it is. */
|
||||
__go_receive (NULL, runtime_main_init_done, NULL);
|
||||
}
|
||||
|
||||
mp = runtime_m ();
|
||||
if (mp->needextram)
|
||||
{
|
||||
|
@ -177,3 +189,65 @@ _cgo_panic (const char *p)
|
|||
|
||||
__go_panic (e);
|
||||
}
|
||||
|
||||
/* Used for _cgo_wait_runtime_init_done. This is based on code in
|
||||
runtime/cgo/gcc_libinit.c in the master library. */
|
||||
|
||||
static pthread_cond_t runtime_init_cond = PTHREAD_COND_INITIALIZER;
|
||||
static pthread_mutex_t runtime_init_mu = PTHREAD_MUTEX_INITIALIZER;
|
||||
static _Bool runtime_init_done;
|
||||
|
||||
/* This is called by exported cgo functions to ensure that the runtime
|
||||
has been initialized before we enter the function. This is needed
|
||||
when building with -buildmode=c-archive or similar. */
|
||||
|
||||
void
|
||||
_cgo_wait_runtime_init_done (void)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (__atomic_load_n (&runtime_init_done, __ATOMIC_ACQUIRE))
|
||||
return;
|
||||
|
||||
err = pthread_mutex_lock (&runtime_init_mu);
|
||||
if (err != 0)
|
||||
abort ();
|
||||
while (!__atomic_load_n (&runtime_init_done, __ATOMIC_ACQUIRE))
|
||||
{
|
||||
err = pthread_cond_wait (&runtime_init_cond, &runtime_init_mu);
|
||||
if (err != 0)
|
||||
abort ();
|
||||
}
|
||||
err = pthread_mutex_unlock (&runtime_init_mu);
|
||||
if (err != 0)
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* This is called by runtime_main after the Go runtime is
|
||||
initialized. */
|
||||
|
||||
void
|
||||
_cgo_notify_runtime_init_done (void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = pthread_mutex_lock (&runtime_init_mu);
|
||||
if (err != 0)
|
||||
abort ();
|
||||
__atomic_store_n (&runtime_init_done, 1, __ATOMIC_RELEASE);
|
||||
err = pthread_cond_broadcast (&runtime_init_cond);
|
||||
if (err != 0)
|
||||
abort ();
|
||||
err = pthread_mutex_unlock (&runtime_init_mu);
|
||||
if (err != 0)
|
||||
abort ();
|
||||
}
|
||||
|
||||
// runtime_iscgo is set to true if some cgo code is linked in.
|
||||
// This is done by a constructor in the cgo generated code.
|
||||
_Bool runtime_iscgo;
|
||||
|
||||
// runtime_cgoHasExtraM is set on startup when an extra M is created
|
||||
// for cgo. The extra M must be created before any C/C++ code calls
|
||||
// cgocallback.
|
||||
_Bool runtime_cgoHasExtraM;
|
||||
|
|
114
libgo/runtime/go-libmain.c
Normal file
114
libgo/runtime/go-libmain.c
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* go-libmain.c -- the startup function for a Go library.
|
||||
|
||||
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 <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "runtime.h"
|
||||
#include "go-alloc.h"
|
||||
#include "array.h"
|
||||
#include "arch.h"
|
||||
#include "malloc.h"
|
||||
|
||||
/* This is used when building a standalone Go library using the Go
|
||||
command's -buildmode=c-archive or -buildmode=c-shared option. It
|
||||
starts up the Go code as a global constructor but does not take any
|
||||
other action. The main program is written in some other language
|
||||
and calls exported Go functions as needed. */
|
||||
|
||||
static void die (const char *, int);
|
||||
static void initfn (int, char **, char **);
|
||||
static void *gostart (void *);
|
||||
|
||||
/* Used to pass arguments to the thread that runs the Go startup. */
|
||||
|
||||
struct args {
|
||||
int argc;
|
||||
char **argv;
|
||||
};
|
||||
|
||||
/* We use .init_array so that we can get the command line arguments.
|
||||
This obviously assumes .init_array support; different systems may
|
||||
require other approaches. */
|
||||
|
||||
typedef void (*initarrayfn) (int, char **, char **);
|
||||
|
||||
static initarrayfn initarray[1]
|
||||
__attribute__ ((section (".init_array"), used)) =
|
||||
{ initfn };
|
||||
|
||||
/* This function is called at program startup time. It starts a new
|
||||
thread to do the actual Go startup, so that program startup is not
|
||||
paused waiting for the Go initialization functions. Exported cgo
|
||||
functions will wait for initialization to complete if
|
||||
necessary. */
|
||||
|
||||
static void
|
||||
initfn (int argc, char **argv, char** env __attribute__ ((unused)))
|
||||
{
|
||||
int err;
|
||||
pthread_attr_t attr;
|
||||
struct args *a;
|
||||
pthread_t tid;
|
||||
|
||||
a = (struct args *) malloc (sizeof *a);
|
||||
if (a == NULL)
|
||||
die ("malloc", errno);
|
||||
a->argc = argc;
|
||||
a->argv = argv;
|
||||
|
||||
err = pthread_attr_init (&attr);
|
||||
if (err != 0)
|
||||
die ("pthread_attr_init", err);
|
||||
err = pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
|
||||
if (err != 0)
|
||||
die ("pthread_attr_setdetachstate", err);
|
||||
|
||||
err = pthread_create (&tid, &attr, gostart, (void *) a);
|
||||
if (err != 0)
|
||||
die ("pthread_create", err);
|
||||
|
||||
err = pthread_attr_destroy (&attr);
|
||||
if (err != 0)
|
||||
die ("pthread_attr_destroy", err);
|
||||
}
|
||||
|
||||
/* Start up the Go runtime. */
|
||||
|
||||
static void *
|
||||
gostart (void *arg)
|
||||
{
|
||||
struct args *a = (struct args *) arg;
|
||||
|
||||
runtime_isarchive = true;
|
||||
|
||||
if (runtime_isstarted)
|
||||
return NULL;
|
||||
runtime_isstarted = true;
|
||||
|
||||
runtime_check ();
|
||||
runtime_args (a->argc, (byte **) a->argv);
|
||||
runtime_osinit ();
|
||||
runtime_schedinit ();
|
||||
__go_go (runtime_main, NULL);
|
||||
runtime_mstart (runtime_m ());
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* If something goes wrong during program startup, crash. There is no
|
||||
way to report failure and nobody to whom to report it. */
|
||||
|
||||
static void
|
||||
die (const char *fn, int err)
|
||||
{
|
||||
fprintf (stderr, "%s: %d\n", fn, err);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
|
@ -35,6 +35,12 @@ extern char **environ;
|
|||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
runtime_isarchive = false;
|
||||
|
||||
if (runtime_isstarted)
|
||||
return NULL;
|
||||
runtime_isstarted = true;
|
||||
|
||||
runtime_check ();
|
||||
runtime_args (argc, (byte **) argv);
|
||||
runtime_osinit ();
|
||||
|
|
|
@ -372,7 +372,6 @@ enum
|
|||
Sched runtime_sched;
|
||||
int32 runtime_gomaxprocs;
|
||||
uint32 runtime_needextram = 1;
|
||||
bool runtime_iscgo = true;
|
||||
M runtime_m0;
|
||||
G runtime_g0; // idle goroutine for m0
|
||||
G* runtime_lastg;
|
||||
|
@ -389,6 +388,8 @@ G** runtime_allg;
|
|||
uintptr runtime_allglen;
|
||||
static uintptr allgcap;
|
||||
|
||||
bool runtime_isarchive;
|
||||
|
||||
void* runtime_mstart(void*);
|
||||
static void runqput(P*, G*);
|
||||
static G* runqget(P*);
|
||||
|
@ -428,6 +429,8 @@ static bool preemptall(void);
|
|||
static bool exitsyscallfast(void);
|
||||
static void allgadd(G*);
|
||||
|
||||
bool runtime_isstarted;
|
||||
|
||||
// The bootstrap sequence is:
|
||||
//
|
||||
// call osinit
|
||||
|
@ -490,6 +493,64 @@ runtime_schedinit(void)
|
|||
extern void main_init(void) __asm__ (GOSYM_PREFIX "__go_init_main");
|
||||
extern void main_main(void) __asm__ (GOSYM_PREFIX "main.main");
|
||||
|
||||
// Used to determine the field alignment.
|
||||
|
||||
struct field_align
|
||||
{
|
||||
char c;
|
||||
Hchan *p;
|
||||
};
|
||||
|
||||
// main_init_done is a signal used by cgocallbackg that initialization
|
||||
// has been completed. It is made before _cgo_notify_runtime_init_done,
|
||||
// so all cgo calls can rely on it existing. When main_init is
|
||||
// complete, it is closed, meaning cgocallbackg can reliably receive
|
||||
// from it.
|
||||
Hchan *runtime_main_init_done;
|
||||
|
||||
// The chan bool type, for runtime_main_init_done.
|
||||
|
||||
extern const struct __go_type_descriptor bool_type_descriptor
|
||||
__asm__ (GOSYM_PREFIX "__go_tdn_bool");
|
||||
|
||||
static struct __go_channel_type chan_bool_type_descriptor =
|
||||
{
|
||||
/* __common */
|
||||
{
|
||||
/* __code */
|
||||
GO_CHAN,
|
||||
/* __align */
|
||||
__alignof (Hchan *),
|
||||
/* __field_align */
|
||||
offsetof (struct field_align, p) - 1,
|
||||
/* __size */
|
||||
sizeof (Hchan *),
|
||||
/* __hash */
|
||||
0, /* This value doesn't matter. */
|
||||
/* __hashfn */
|
||||
__go_type_hash_error,
|
||||
/* __equalfn */
|
||||
__go_type_equal_error,
|
||||
/* __gc */
|
||||
NULL, /* This value doesn't matter */
|
||||
/* __reflection */
|
||||
NULL, /* This value doesn't matter */
|
||||
/* __uncommon */
|
||||
NULL,
|
||||
/* __pointer_to_this */
|
||||
NULL,
|
||||
/* __zero */
|
||||
NULL /* This value doesn't matter */
|
||||
},
|
||||
/* __element_type */
|
||||
&bool_type_descriptor,
|
||||
/* __dir */
|
||||
CHANNEL_BOTH_DIR
|
||||
};
|
||||
|
||||
extern Hchan *__go_new_channel (ChanType *, uintptr);
|
||||
extern void closechan(Hchan *) __asm__ (GOSYM_PREFIX "runtime.closechan");
|
||||
|
||||
static void
|
||||
initDone(void *arg __attribute__ ((unused))) {
|
||||
runtime_unlockOSThread();
|
||||
|
@ -535,8 +596,15 @@ runtime_main(void* dummy __attribute__((unused)))
|
|||
if(m != &runtime_m0)
|
||||
runtime_throw("runtime_main not on m0");
|
||||
__go_go(runtime_MHeap_Scavenger, nil);
|
||||
|
||||
runtime_main_init_done = __go_new_channel(&chan_bool_type_descriptor, 0);
|
||||
|
||||
_cgo_notify_runtime_init_done();
|
||||
|
||||
main_init();
|
||||
|
||||
closechan(runtime_main_init_done);
|
||||
|
||||
if(g->defer != &d || d.__pfn != initDone)
|
||||
runtime_throw("runtime: bad defer entry after init");
|
||||
g->defer = d.__next;
|
||||
|
@ -547,6 +615,14 @@ runtime_main(void* dummy __attribute__((unused)))
|
|||
// roots.
|
||||
mstats.enablegc = 1;
|
||||
|
||||
if(runtime_isarchive) {
|
||||
// This is not a complete program, but is instead a
|
||||
// library built using -buildmode=c-archive or
|
||||
// c-shared. Now that we are initialized, there is
|
||||
// nothing further to do.
|
||||
return;
|
||||
}
|
||||
|
||||
main_main();
|
||||
|
||||
// Make racy client program work: if panicking on
|
||||
|
@ -1011,8 +1087,14 @@ runtime_mstart(void* mp)
|
|||
|
||||
// Install signal handlers; after minit so that minit can
|
||||
// prepare the thread to be able to handle the signals.
|
||||
if(m == &runtime_m0)
|
||||
if(m == &runtime_m0) {
|
||||
if(runtime_iscgo && !runtime_cgoHasExtraM) {
|
||||
runtime_cgoHasExtraM = true;
|
||||
runtime_newextram();
|
||||
runtime_needextram = 0;
|
||||
}
|
||||
runtime_initsig();
|
||||
}
|
||||
|
||||
if(m->mstartfn)
|
||||
m->mstartfn();
|
||||
|
@ -2747,6 +2829,13 @@ checkdead(void)
|
|||
int32 run, grunning, s;
|
||||
uintptr i;
|
||||
|
||||
// For -buildmode=c-shared or -buildmode=c-archive it's OK if
|
||||
// there are no running goroutines. The calling program is
|
||||
// assumed to be running.
|
||||
if(runtime_isarchive) {
|
||||
return;
|
||||
}
|
||||
|
||||
// -1 for sysmon
|
||||
run = runtime_sched.mcount - runtime_sched.nmidle - runtime_sched.nmidlelocked - 1 - countextra();
|
||||
if(run > 0)
|
||||
|
@ -3332,6 +3421,7 @@ void
|
|||
runtime_proc_scan(struct Workbuf** wbufp, void (*enqueue1)(struct Workbuf**, Obj))
|
||||
{
|
||||
enqueue1(wbufp, (Obj){(byte*)&runtime_sched, sizeof runtime_sched, 0});
|
||||
enqueue1(wbufp, (Obj){(byte*)&runtime_main_init_done, sizeof runtime_main_init_done, 0});
|
||||
}
|
||||
|
||||
// Return whether we are waiting for a GC. This gc toolchain uses
|
||||
|
|
|
@ -509,6 +509,9 @@ extern uint32 runtime_Hchansize;
|
|||
extern DebugVars runtime_debug;
|
||||
extern uintptr runtime_maxstacksize;
|
||||
|
||||
extern bool runtime_isstarted;
|
||||
extern bool runtime_isarchive;
|
||||
|
||||
/*
|
||||
* common functions and data
|
||||
*/
|
||||
|
@ -845,3 +848,9 @@ struct time_now_ret
|
|||
|
||||
struct time_now_ret now() __asm__ (GOSYM_PREFIX "time.now")
|
||||
__attribute__ ((no_split_stack));
|
||||
|
||||
extern void _cgo_wait_runtime_init_done (void);
|
||||
extern void _cgo_notify_runtime_init_done (void);
|
||||
extern _Bool runtime_iscgo;
|
||||
extern _Bool runtime_cgoHasExtraM;
|
||||
extern Hchan *runtime_main_init_done;
|
||||
|
|
Loading…
Add table
Reference in a new issue