mirror of
https://github.com/golang/go
synced 2024-11-18 14:44:41 -07:00
runtime/cgo: darwin/arm cgo support
Change-Id: I936be12eed95b99d1d20ed16fb785182e1817b33 Reviewed-on: https://go-review.googlesource.com/2124 Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
parent
b64dedabea
commit
a5bff443c7
@ -11,7 +11,7 @@ package cgo
|
||||
|
||||
/*
|
||||
|
||||
#cgo darwin LDFLAGS: -lpthread
|
||||
#cgo darwin,!arm LDFLAGS: -lpthread
|
||||
#cgo dragonfly LDFLAGS: -lpthread
|
||||
#cgo freebsd LDFLAGS: -lpthread
|
||||
#cgo android LDFLAGS: -llog
|
||||
|
@ -11,6 +11,10 @@
|
||||
#define EXT(s) s
|
||||
#endif
|
||||
|
||||
// Apple's ld64 wants 4-byte alignment for ARM code sections.
|
||||
// .align in both Apple as and GNU as treat n as aligning to 2**n bytes.
|
||||
.align 2
|
||||
|
||||
/*
|
||||
* void crosscall_arm1(void (*fn)(void), void (*setg_gcc)(void *g), void *g)
|
||||
*
|
||||
|
99
src/runtime/cgo/gcc_darwin_arm.c
Normal file
99
src/runtime/cgo/gcc_darwin_arm.c
Normal file
@ -0,0 +1,99 @@
|
||||
// Copyright 2014 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 <string.h> /* for strerror */
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <limits.h>
|
||||
#include "libcgo.h"
|
||||
|
||||
#define magic (0xe696c4f4U)
|
||||
|
||||
// inittls allocates a thread-local storage slot for g.
|
||||
//
|
||||
// It finds the first available slot using pthread_key_create and uses
|
||||
// it as the offset value for runtime.tlsg.
|
||||
static void
|
||||
inittls(void **tlsg, void **tlsbase)
|
||||
{
|
||||
pthread_key_t k;
|
||||
int i, err;
|
||||
|
||||
err = pthread_key_create(&k, nil);
|
||||
if(err != 0) {
|
||||
fprintf(stderr, "runtime/cgo: pthread_key_create failed: %d\n", err);
|
||||
abort();
|
||||
}
|
||||
//fprintf(stderr, "runtime/cgo: k = %d, tlsbase = %p\n", (int)k, tlsbase); // debug
|
||||
pthread_setspecific(k, (void*)magic);
|
||||
// The first key should be at 258.
|
||||
for (i=0; i<PTHREAD_KEYS_MAX; i++) {
|
||||
if (*(tlsbase+i) == (void*)magic) {
|
||||
*tlsg = (void*)(i*sizeof(void *));
|
||||
pthread_setspecific(k, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "runtime/cgo: could not find pthread key.\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
static void *threadentry(void*);
|
||||
void (*setg_gcc)(void*);
|
||||
|
||||
void
|
||||
_cgo_sys_thread_start(ThreadStart *ts)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
sigset_t ign, oset;
|
||||
pthread_t p;
|
||||
size_t size;
|
||||
int err;
|
||||
|
||||
sigfillset(&ign);
|
||||
pthread_sigmask(SIG_SETMASK, &ign, &oset);
|
||||
|
||||
pthread_attr_init(&attr);
|
||||
size = 0;
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
// Leave stacklo=0 and set stackhi=size; mstack will do the rest.
|
||||
ts->g->stackhi = size;
|
||||
err = pthread_create(&p, &attr, threadentry, ts);
|
||||
|
||||
pthread_sigmask(SIG_SETMASK, &oset, nil);
|
||||
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
extern void crosscall_arm1(void (*fn)(void), void (*setg_gcc)(void*), void *g);
|
||||
static void*
|
||||
threadentry(void *v)
|
||||
{
|
||||
ThreadStart ts;
|
||||
|
||||
ts = *(ThreadStart*)v;
|
||||
free(v);
|
||||
|
||||
crosscall_arm1(ts.fn, setg_gcc, (void*)ts.g);
|
||||
return nil;
|
||||
}
|
||||
|
||||
void
|
||||
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
size_t size;
|
||||
|
||||
setg_gcc = setg;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_getstacksize(&attr, &size);
|
||||
g->stacklo = (uintptr)&attr - size + 4096;
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
// yes, tlsbase from mrc might not be correctly aligned.
|
||||
inittls(tlsg, (void**)((uintptr)tlsbase & ~3));
|
||||
}
|
Loading…
Reference in New Issue
Block a user