2008-07-13 15:29:46 -06:00
|
|
|
// Copyright 2009 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.
|
|
|
|
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
package runtime
|
2008-07-13 15:29:46 -06:00
|
|
|
#include "runtime.h"
|
2012-09-24 12:58:34 -06:00
|
|
|
#include "arch_GOARCH.h"
|
2009-09-08 14:46:54 -06:00
|
|
|
#include "type.h"
|
2012-10-07 12:05:32 -06:00
|
|
|
#include "race.h"
|
2012-09-24 12:58:34 -06:00
|
|
|
#include "malloc.h"
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
#include "chan.h"
|
2013-08-12 14:47:18 -06:00
|
|
|
#include "../../cmd/ld/textflag.h"
|
2008-07-13 15:29:46 -06:00
|
|
|
|
2013-02-25 13:58:23 -07:00
|
|
|
uint32 runtime·Hchansize = sizeof(Hchan);
|
|
|
|
|
2011-07-21 11:57:13 -06:00
|
|
|
static void dequeueg(WaitQ*);
|
|
|
|
static SudoG* dequeue(WaitQ*);
|
2008-07-24 16:57:30 -06:00
|
|
|
static void enqueue(WaitQ*, SudoG*);
|
2010-02-08 22:41:54 -07:00
|
|
|
static void destroychan(Hchan*);
|
2012-10-07 12:05:32 -06:00
|
|
|
static void racesync(Hchan*, SudoG*);
|
2008-07-20 21:13:07 -06:00
|
|
|
|
2014-02-12 11:21:38 -07:00
|
|
|
static Hchan*
|
|
|
|
makechan(ChanType *t, int64 hint)
|
2008-07-13 15:29:46 -06:00
|
|
|
{
|
|
|
|
Hchan *c;
|
2011-08-17 13:54:17 -06:00
|
|
|
Type *elem;
|
2012-05-29 12:02:29 -06:00
|
|
|
|
2011-08-17 13:54:17 -06:00
|
|
|
elem = t->elem;
|
2008-07-13 15:29:46 -06:00
|
|
|
|
2012-09-24 12:58:34 -06:00
|
|
|
// compiler checks this but be safe.
|
|
|
|
if(elem->size >= (1<<16))
|
|
|
|
runtime·throw("makechan: invalid channel element type");
|
2013-06-06 13:06:12 -06:00
|
|
|
if((sizeof(*c)%MAXALIGN) != 0 || elem->align > MAXALIGN)
|
|
|
|
runtime·throw("makechan: bad alignment");
|
2012-09-24 12:58:34 -06:00
|
|
|
|
2014-01-28 11:37:35 -07:00
|
|
|
if(hint < 0 || (intgo)hint != hint || (elem->size > 0 && hint > (MaxMem - sizeof(*c)) / elem->size))
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·panicstring("makechan: size out of range");
|
2010-05-01 14:15:42 -06:00
|
|
|
|
2011-03-22 19:41:17 -06:00
|
|
|
// allocate memory in one call
|
runtime: refactor mallocgc
Make it accept type, combine flags.
Several reasons for the change:
1. mallocgc and settype must be atomic wrt GC
2. settype is called from only one place now
3. it will help performance (eventually settype
functionality must be combined with markallocated)
4. flags are easier to read now (no mallocgc(sz, 0, 1, 0) anymore)
R=golang-dev, iant, nightlyone, rsc, dave, khr, bradfitz, r
CC=golang-dev
https://golang.org/cl/10136043
2013-07-26 11:17:24 -06:00
|
|
|
c = (Hchan*)runtime·mallocgc(sizeof(*c) + hint*elem->size, (uintptr)t | TypeInfo_Chan, 0);
|
2009-09-08 14:46:54 -06:00
|
|
|
c->elemsize = elem->size;
|
2014-01-21 23:36:17 -07:00
|
|
|
c->elemtype = elem;
|
2011-04-13 21:42:06 -06:00
|
|
|
c->dataqsiz = hint;
|
2008-07-13 15:29:46 -06:00
|
|
|
|
2010-04-01 12:56:18 -06:00
|
|
|
if(debug)
|
2013-06-06 13:06:12 -06:00
|
|
|
runtime·printf("makechan: chan=%p; elemsize=%D; elemalg=%p; dataqsiz=%D\n",
|
|
|
|
c, (int64)elem->size, elem->alg, (int64)c->dataqsiz);
|
2009-07-08 16:00:54 -06:00
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func reflect·makechan(t *ChanType, size uint64) (c *Hchan) {
|
2014-02-12 11:21:38 -07:00
|
|
|
c = makechan(t, size);
|
reflect: more efficient; cannot Set result of NewValue anymore
* Reduces malloc counts during gob encoder/decoder test from 6/6 to 3/5.
The current reflect uses Set to mean two subtly different things.
(1) If you have a reflect.Value v, it might just represent
itself (as in v = reflect.NewValue(42)), in which case calling
v.Set only changed v, not any other data in the program.
(2) If you have a reflect Value v derived from a pointer
or a slice (as in x := []int{42}; v = reflect.NewValue(x).Index(0)),
v represents the value held there. Changing x[0] affects the
value returned by v.Int(), and calling v.Set affects x[0].
This was not really by design; it just happened that way.
The motivation for the new reflect implementation was
to remove mallocs. The use case (1) has an implicit malloc
inside it. If you can do:
v := reflect.NewValue(0)
v.Set(42)
i := v.Int() // i = 42
then that implies that v is referring to some underlying
chunk of memory in order to remember the 42; that is,
NewValue must have allocated some memory.
Almost all the time you are using reflect the goal is to
inspect or to change other data, not to manipulate data
stored solely inside a reflect.Value.
This CL removes use case (1), so that an assignable
reflect.Value must always refer to some other piece of data
in the program. Put another way, removing this case would
make
v := reflect.NewValue(0)
v.Set(42)
as illegal as
0 = 42.
It would also make this illegal:
x := 0
v := reflect.NewValue(x)
v.Set(42)
for the same reason. (Note that right now, v.Set(42) "succeeds"
but does not change the value of x.)
If you really wanted to make v refer to x, you'd start with &x
and dereference it:
x := 0
v := reflect.NewValue(&x).Elem() // v = *&x
v.Set(42)
It's pretty rare, except in tests, to want to use NewValue and then
call Set to change the Value itself instead of some other piece of
data in the program. I haven't seen it happen once yet while
making the tree build with this change.
For the same reasons, reflect.Zero (formerly reflect.MakeZero)
would also return an unassignable, unaddressable value.
This invalidates the (awkward) idiom:
pv := ... some Ptr Value we have ...
v := reflect.Zero(pv.Type().Elem())
pv.PointTo(v)
which, when the API changed, turned into:
pv := ... some Ptr Value we have ...
v := reflect.Zero(pv.Type().Elem())
pv.Set(v.Addr())
In both, it is far from clear what the code is trying to do. Now that
it is possible, this CL adds reflect.New(Type) Value that does the
obvious thing (same as Go's new), so this code would be replaced by:
pv := ... some Ptr Value we have ...
pv.Set(reflect.New(pv.Type().Elem()))
The changes just described can be confusing to think about,
but I believe it is because the old API was confusing - it was
conflating two different kinds of Values - and that the new API
by itself is pretty simple: you can only Set (or call Addr on)
a Value if it actually addresses some real piece of data; that is,
only if it is the result of dereferencing a Ptr or indexing a Slice.
If you really want the old behavior, you'd get it by translating:
v := reflect.NewValue(x)
into
v := reflect.New(reflect.Typeof(x)).Elem()
v.Set(reflect.NewValue(x))
Gofix will not be able to help with this, because whether
and how to change the code depends on whether the original
code meant use (1) or use (2), so the developer has to read
and think about the code.
You can see the effect on packages in the tree in
https://golang.org/cl/4423043/.
R=r
CC=golang-dev
https://golang.org/cl/4435042
2011-04-18 12:35:33 -06:00
|
|
|
}
|
|
|
|
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func makechan(t *ChanType, size int64) (c *Hchan) {
|
|
|
|
c = makechan(t, size);
|
2008-07-13 15:29:46 -06:00
|
|
|
}
|
|
|
|
|
2008-07-26 15:21:21 -06:00
|
|
|
/*
|
|
|
|
* generic single channel send/recv
|
|
|
|
* if the bool pointer is nil,
|
|
|
|
* then the full exchange will
|
|
|
|
* occur. if pres is not nil,
|
|
|
|
* then the protocol will not
|
|
|
|
* sleep but return if it could
|
2010-04-01 12:56:18 -06:00
|
|
|
* not complete.
|
|
|
|
*
|
|
|
|
* sleep can wake up with g->param == nil
|
|
|
|
* when a channel involved in the sleep has
|
|
|
|
* been closed. it is easiest to loop and re-run
|
|
|
|
* the operation; we'll see that it's now closed.
|
2008-07-26 15:21:21 -06:00
|
|
|
*/
|
2014-02-12 11:21:38 -07:00
|
|
|
static bool
|
|
|
|
chansend(ChanType *t, Hchan *c, byte *ep, bool block, void *pc)
|
2008-07-13 15:29:46 -06:00
|
|
|
{
|
2008-07-26 15:21:21 -06:00
|
|
|
SudoG *sg;
|
2011-07-20 09:51:25 -06:00
|
|
|
SudoG mysg;
|
2008-07-26 15:21:21 -06:00
|
|
|
G* gp;
|
pprof: add goroutine blocking profiling
The profiler collects goroutine blocking information similar to Google Perf Tools.
You may see an example of the profile (converted to svg) attached to
http://code.google.com/p/go/issues/detail?id=3946
The public API changes are:
+pkg runtime, func BlockProfile([]BlockProfileRecord) (int, bool)
+pkg runtime, func SetBlockProfileRate(int)
+pkg runtime, method (*BlockProfileRecord) Stack() []uintptr
+pkg runtime, type BlockProfileRecord struct
+pkg runtime, type BlockProfileRecord struct, Count int64
+pkg runtime, type BlockProfileRecord struct, Cycles int64
+pkg runtime, type BlockProfileRecord struct, embedded StackRecord
R=rsc, dave, minux.ma, r
CC=gobot, golang-dev, r, remyoudompheng
https://golang.org/cl/6443115
2012-10-06 02:56:04 -06:00
|
|
|
int64 t0;
|
2008-07-13 15:29:46 -06:00
|
|
|
|
2014-01-21 00:17:44 -07:00
|
|
|
if(raceenabled)
|
2014-02-12 11:21:38 -07:00
|
|
|
runtime·racereadobjectpc(ep, t->elem, runtime·getcallerpc(&t), chansend);
|
2014-01-21 00:17:44 -07:00
|
|
|
|
2011-08-17 13:54:17 -06:00
|
|
|
if(c == nil) {
|
|
|
|
USED(t);
|
2014-02-12 11:21:38 -07:00
|
|
|
if(!block)
|
|
|
|
return false;
|
2012-09-18 11:15:46 -06:00
|
|
|
runtime·park(nil, nil, "chan send (nil chan)");
|
2014-02-12 11:21:38 -07:00
|
|
|
return false; // not reached
|
2011-08-17 13:54:17 -06:00
|
|
|
}
|
2010-07-13 18:27:26 -06:00
|
|
|
|
2008-07-13 15:29:46 -06:00
|
|
|
if(debug) {
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·printf("chansend: chan=%p; elem=", c);
|
2014-01-21 23:36:17 -07:00
|
|
|
c->elemtype->alg->print(c->elemsize, ep);
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·prints("\n");
|
2008-07-13 15:29:46 -06:00
|
|
|
}
|
2008-07-26 15:21:21 -06:00
|
|
|
|
pprof: add goroutine blocking profiling
The profiler collects goroutine blocking information similar to Google Perf Tools.
You may see an example of the profile (converted to svg) attached to
http://code.google.com/p/go/issues/detail?id=3946
The public API changes are:
+pkg runtime, func BlockProfile([]BlockProfileRecord) (int, bool)
+pkg runtime, func SetBlockProfileRate(int)
+pkg runtime, method (*BlockProfileRecord) Stack() []uintptr
+pkg runtime, type BlockProfileRecord struct
+pkg runtime, type BlockProfileRecord struct, Count int64
+pkg runtime, type BlockProfileRecord struct, Cycles int64
+pkg runtime, type BlockProfileRecord struct, embedded StackRecord
R=rsc, dave, minux.ma, r
CC=gobot, golang-dev, r, remyoudompheng
https://golang.org/cl/6443115
2012-10-06 02:56:04 -06:00
|
|
|
t0 = 0;
|
|
|
|
mysg.releasetime = 0;
|
|
|
|
if(runtime·blockprofilerate > 0) {
|
|
|
|
t0 = runtime·cputicks();
|
|
|
|
mysg.releasetime = -1;
|
|
|
|
}
|
|
|
|
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·lock(c);
|
2012-10-07 12:05:32 -06:00
|
|
|
if(raceenabled)
|
2014-02-12 11:21:38 -07:00
|
|
|
runtime·racereadpc(c, pc, chansend);
|
2011-03-11 12:47:26 -07:00
|
|
|
if(c->closed)
|
2009-03-23 19:50:35 -06:00
|
|
|
goto closed;
|
2009-03-13 17:47:54 -06:00
|
|
|
|
2008-07-14 15:33:39 -06:00
|
|
|
if(c->dataqsiz > 0)
|
|
|
|
goto asynch;
|
|
|
|
|
2011-07-21 11:57:13 -06:00
|
|
|
sg = dequeue(&c->recvq);
|
2008-07-26 15:21:21 -06:00
|
|
|
if(sg != nil) {
|
2012-10-07 12:05:32 -06:00
|
|
|
if(raceenabled)
|
|
|
|
racesync(c, sg);
|
2011-07-20 09:51:25 -06:00
|
|
|
runtime·unlock(c);
|
2012-05-29 12:02:29 -06:00
|
|
|
|
2008-07-26 15:21:21 -06:00
|
|
|
gp = sg->g;
|
|
|
|
gp->param = sg;
|
2011-07-20 09:51:25 -06:00
|
|
|
if(sg->elem != nil)
|
2014-01-21 23:36:17 -07:00
|
|
|
c->elemtype->alg->copy(c->elemsize, sg->elem, ep);
|
pprof: add goroutine blocking profiling
The profiler collects goroutine blocking information similar to Google Perf Tools.
You may see an example of the profile (converted to svg) attached to
http://code.google.com/p/go/issues/detail?id=3946
The public API changes are:
+pkg runtime, func BlockProfile([]BlockProfileRecord) (int, bool)
+pkg runtime, func SetBlockProfileRate(int)
+pkg runtime, method (*BlockProfileRecord) Stack() []uintptr
+pkg runtime, type BlockProfileRecord struct
+pkg runtime, type BlockProfileRecord struct, Count int64
+pkg runtime, type BlockProfileRecord struct, Cycles int64
+pkg runtime, type BlockProfileRecord struct, embedded StackRecord
R=rsc, dave, minux.ma, r
CC=gobot, golang-dev, r, remyoudompheng
https://golang.org/cl/6443115
2012-10-06 02:56:04 -06:00
|
|
|
if(sg->releasetime)
|
|
|
|
sg->releasetime = runtime·cputicks();
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·ready(gp);
|
2014-02-12 11:21:38 -07:00
|
|
|
return true;
|
2008-07-14 15:33:39 -06:00
|
|
|
}
|
2008-07-20 21:13:07 -06:00
|
|
|
|
2014-02-12 11:21:38 -07:00
|
|
|
if(!block) {
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·unlock(c);
|
2014-02-12 11:21:38 -07:00
|
|
|
return false;
|
2008-07-26 15:21:21 -06:00
|
|
|
}
|
|
|
|
|
2011-07-20 09:51:25 -06:00
|
|
|
mysg.elem = ep;
|
|
|
|
mysg.g = g;
|
2014-02-12 11:21:38 -07:00
|
|
|
mysg.selectdone = nil;
|
2008-07-26 15:21:21 -06:00
|
|
|
g->param = nil;
|
2011-07-20 09:51:25 -06:00
|
|
|
enqueue(&c->sendq, &mysg);
|
2014-01-22 00:27:16 -07:00
|
|
|
runtime·parkunlock(c, "chan send");
|
2008-07-26 15:21:21 -06:00
|
|
|
|
2011-07-20 09:51:25 -06:00
|
|
|
if(g->param == nil) {
|
|
|
|
runtime·lock(c);
|
|
|
|
if(!c->closed)
|
|
|
|
runtime·throw("chansend: spurious wakeup");
|
|
|
|
goto closed;
|
|
|
|
}
|
|
|
|
|
pprof: add goroutine blocking profiling
The profiler collects goroutine blocking information similar to Google Perf Tools.
You may see an example of the profile (converted to svg) attached to
http://code.google.com/p/go/issues/detail?id=3946
The public API changes are:
+pkg runtime, func BlockProfile([]BlockProfileRecord) (int, bool)
+pkg runtime, func SetBlockProfileRate(int)
+pkg runtime, method (*BlockProfileRecord) Stack() []uintptr
+pkg runtime, type BlockProfileRecord struct
+pkg runtime, type BlockProfileRecord struct, Count int64
+pkg runtime, type BlockProfileRecord struct, Cycles int64
+pkg runtime, type BlockProfileRecord struct, embedded StackRecord
R=rsc, dave, minux.ma, r
CC=gobot, golang-dev, r, remyoudompheng
https://golang.org/cl/6443115
2012-10-06 02:56:04 -06:00
|
|
|
if(mysg.releasetime > 0)
|
|
|
|
runtime·blockevent(mysg.releasetime - t0, 2);
|
|
|
|
|
2014-02-12 11:21:38 -07:00
|
|
|
return true;
|
2008-07-14 15:33:39 -06:00
|
|
|
|
|
|
|
asynch:
|
2011-03-11 12:47:26 -07:00
|
|
|
if(c->closed)
|
2009-03-13 17:47:54 -06:00
|
|
|
goto closed;
|
|
|
|
|
|
|
|
if(c->qcount >= c->dataqsiz) {
|
2014-02-12 11:21:38 -07:00
|
|
|
if(!block) {
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·unlock(c);
|
2014-02-12 11:21:38 -07:00
|
|
|
return false;
|
2008-09-26 12:47:04 -06:00
|
|
|
}
|
2011-07-20 09:51:25 -06:00
|
|
|
mysg.g = g;
|
|
|
|
mysg.elem = nil;
|
2014-02-12 11:21:38 -07:00
|
|
|
mysg.selectdone = nil;
|
2011-07-20 09:51:25 -06:00
|
|
|
enqueue(&c->sendq, &mysg);
|
2014-01-22 00:27:16 -07:00
|
|
|
runtime·parkunlock(c, "chan send");
|
2008-09-19 21:43:30 -06:00
|
|
|
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·lock(c);
|
2009-03-13 17:47:54 -06:00
|
|
|
goto asynch;
|
2008-07-14 18:41:38 -06:00
|
|
|
}
|
2012-10-07 12:05:32 -06:00
|
|
|
|
2014-03-26 09:05:48 -06:00
|
|
|
if(raceenabled) {
|
|
|
|
if(c->dataqsiz == 1)
|
|
|
|
runtime·raceacquire(chanbuf(c, c->sendx));
|
2012-10-07 12:05:32 -06:00
|
|
|
runtime·racerelease(chanbuf(c, c->sendx));
|
2014-03-26 09:05:48 -06:00
|
|
|
}
|
2012-10-07 12:05:32 -06:00
|
|
|
|
2014-01-21 23:36:17 -07:00
|
|
|
c->elemtype->alg->copy(c->elemsize, chanbuf(c, c->sendx), ep);
|
2011-04-13 21:42:06 -06:00
|
|
|
if(++c->sendx == c->dataqsiz)
|
|
|
|
c->sendx = 0;
|
2008-07-14 18:41:38 -06:00
|
|
|
c->qcount++;
|
2008-07-26 15:21:21 -06:00
|
|
|
|
2011-07-21 11:57:13 -06:00
|
|
|
sg = dequeue(&c->recvq);
|
2008-07-26 15:21:21 -06:00
|
|
|
if(sg != nil) {
|
|
|
|
gp = sg->g;
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·unlock(c);
|
pprof: add goroutine blocking profiling
The profiler collects goroutine blocking information similar to Google Perf Tools.
You may see an example of the profile (converted to svg) attached to
http://code.google.com/p/go/issues/detail?id=3946
The public API changes are:
+pkg runtime, func BlockProfile([]BlockProfileRecord) (int, bool)
+pkg runtime, func SetBlockProfileRate(int)
+pkg runtime, method (*BlockProfileRecord) Stack() []uintptr
+pkg runtime, type BlockProfileRecord struct
+pkg runtime, type BlockProfileRecord struct, Count int64
+pkg runtime, type BlockProfileRecord struct, Cycles int64
+pkg runtime, type BlockProfileRecord struct, embedded StackRecord
R=rsc, dave, minux.ma, r
CC=gobot, golang-dev, r, remyoudompheng
https://golang.org/cl/6443115
2012-10-06 02:56:04 -06:00
|
|
|
if(sg->releasetime)
|
|
|
|
sg->releasetime = runtime·cputicks();
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·ready(gp);
|
2008-09-19 21:43:30 -06:00
|
|
|
} else
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·unlock(c);
|
pprof: add goroutine blocking profiling
The profiler collects goroutine blocking information similar to Google Perf Tools.
You may see an example of the profile (converted to svg) attached to
http://code.google.com/p/go/issues/detail?id=3946
The public API changes are:
+pkg runtime, func BlockProfile([]BlockProfileRecord) (int, bool)
+pkg runtime, func SetBlockProfileRate(int)
+pkg runtime, method (*BlockProfileRecord) Stack() []uintptr
+pkg runtime, type BlockProfileRecord struct
+pkg runtime, type BlockProfileRecord struct, Count int64
+pkg runtime, type BlockProfileRecord struct, Cycles int64
+pkg runtime, type BlockProfileRecord struct, embedded StackRecord
R=rsc, dave, minux.ma, r
CC=gobot, golang-dev, r, remyoudompheng
https://golang.org/cl/6443115
2012-10-06 02:56:04 -06:00
|
|
|
if(mysg.releasetime > 0)
|
|
|
|
runtime·blockevent(mysg.releasetime - t0, 2);
|
2014-02-12 11:21:38 -07:00
|
|
|
return true;
|
2009-03-13 17:47:54 -06:00
|
|
|
|
|
|
|
closed:
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·unlock(c);
|
spec, runtime, tests: send on closed channel panics
Close of closed channel panics.
Receive from closed channel never panics,
even if done repeatedly.
Fixes #1349.
Fixes #1419.
R=gri, iant, ken2, r, gri1, r2, iant2, rog, albert.strasheim, niemeyer, ejsherry
CC=golang-dev
https://golang.org/cl/3989042
2011-01-21 13:07:13 -07:00
|
|
|
runtime·panicstring("send on closed channel");
|
2014-02-12 11:21:38 -07:00
|
|
|
return false; // not reached
|
2008-07-13 15:29:46 -06:00
|
|
|
}
|
2008-07-13 17:20:27 -06:00
|
|
|
|
reflect: more efficient; cannot Set result of NewValue anymore
* Reduces malloc counts during gob encoder/decoder test from 6/6 to 3/5.
The current reflect uses Set to mean two subtly different things.
(1) If you have a reflect.Value v, it might just represent
itself (as in v = reflect.NewValue(42)), in which case calling
v.Set only changed v, not any other data in the program.
(2) If you have a reflect Value v derived from a pointer
or a slice (as in x := []int{42}; v = reflect.NewValue(x).Index(0)),
v represents the value held there. Changing x[0] affects the
value returned by v.Int(), and calling v.Set affects x[0].
This was not really by design; it just happened that way.
The motivation for the new reflect implementation was
to remove mallocs. The use case (1) has an implicit malloc
inside it. If you can do:
v := reflect.NewValue(0)
v.Set(42)
i := v.Int() // i = 42
then that implies that v is referring to some underlying
chunk of memory in order to remember the 42; that is,
NewValue must have allocated some memory.
Almost all the time you are using reflect the goal is to
inspect or to change other data, not to manipulate data
stored solely inside a reflect.Value.
This CL removes use case (1), so that an assignable
reflect.Value must always refer to some other piece of data
in the program. Put another way, removing this case would
make
v := reflect.NewValue(0)
v.Set(42)
as illegal as
0 = 42.
It would also make this illegal:
x := 0
v := reflect.NewValue(x)
v.Set(42)
for the same reason. (Note that right now, v.Set(42) "succeeds"
but does not change the value of x.)
If you really wanted to make v refer to x, you'd start with &x
and dereference it:
x := 0
v := reflect.NewValue(&x).Elem() // v = *&x
v.Set(42)
It's pretty rare, except in tests, to want to use NewValue and then
call Set to change the Value itself instead of some other piece of
data in the program. I haven't seen it happen once yet while
making the tree build with this change.
For the same reasons, reflect.Zero (formerly reflect.MakeZero)
would also return an unassignable, unaddressable value.
This invalidates the (awkward) idiom:
pv := ... some Ptr Value we have ...
v := reflect.Zero(pv.Type().Elem())
pv.PointTo(v)
which, when the API changed, turned into:
pv := ... some Ptr Value we have ...
v := reflect.Zero(pv.Type().Elem())
pv.Set(v.Addr())
In both, it is far from clear what the code is trying to do. Now that
it is possible, this CL adds reflect.New(Type) Value that does the
obvious thing (same as Go's new), so this code would be replaced by:
pv := ... some Ptr Value we have ...
pv.Set(reflect.New(pv.Type().Elem()))
The changes just described can be confusing to think about,
but I believe it is because the old API was confusing - it was
conflating two different kinds of Values - and that the new API
by itself is pretty simple: you can only Set (or call Addr on)
a Value if it actually addresses some real piece of data; that is,
only if it is the result of dereferencing a Ptr or indexing a Slice.
If you really want the old behavior, you'd get it by translating:
v := reflect.NewValue(x)
into
v := reflect.New(reflect.Typeof(x)).Elem()
v.Set(reflect.NewValue(x))
Gofix will not be able to help with this, because whether
and how to change the code depends on whether the original
code meant use (1) or use (2), so the developer has to read
and think about the code.
You can see the effect on packages in the tree in
https://golang.org/cl/4423043/.
R=r
CC=golang-dev
https://golang.org/cl/4435042
2011-04-18 12:35:33 -06:00
|
|
|
|
2014-02-12 11:21:38 -07:00
|
|
|
static bool
|
|
|
|
chanrecv(ChanType *t, Hchan* c, byte *ep, bool block, bool *received)
|
2008-07-15 22:07:59 -06:00
|
|
|
{
|
2008-07-26 15:21:21 -06:00
|
|
|
SudoG *sg;
|
2011-07-20 09:51:25 -06:00
|
|
|
SudoG mysg;
|
2008-07-26 15:21:21 -06:00
|
|
|
G *gp;
|
pprof: add goroutine blocking profiling
The profiler collects goroutine blocking information similar to Google Perf Tools.
You may see an example of the profile (converted to svg) attached to
http://code.google.com/p/go/issues/detail?id=3946
The public API changes are:
+pkg runtime, func BlockProfile([]BlockProfileRecord) (int, bool)
+pkg runtime, func SetBlockProfileRate(int)
+pkg runtime, method (*BlockProfileRecord) Stack() []uintptr
+pkg runtime, type BlockProfileRecord struct
+pkg runtime, type BlockProfileRecord struct, Count int64
+pkg runtime, type BlockProfileRecord struct, Cycles int64
+pkg runtime, type BlockProfileRecord struct, embedded StackRecord
R=rsc, dave, minux.ma, r
CC=gobot, golang-dev, r, remyoudompheng
https://golang.org/cl/6443115
2012-10-06 02:56:04 -06:00
|
|
|
int64 t0;
|
2008-07-16 12:46:33 -06:00
|
|
|
|
2014-01-21 00:17:44 -07:00
|
|
|
// raceenabled: don't need to check ep, as it is always on the stack.
|
|
|
|
|
2010-04-01 12:56:18 -06:00
|
|
|
if(debug)
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·printf("chanrecv: chan=%p\n", c);
|
2008-07-26 15:21:21 -06:00
|
|
|
|
2011-08-17 13:54:17 -06:00
|
|
|
if(c == nil) {
|
|
|
|
USED(t);
|
2014-02-12 11:21:38 -07:00
|
|
|
if(!block)
|
|
|
|
return false;
|
2012-09-18 11:15:46 -06:00
|
|
|
runtime·park(nil, nil, "chan receive (nil chan)");
|
2014-02-12 11:21:38 -07:00
|
|
|
return false; // not reached
|
2011-08-17 13:54:17 -06:00
|
|
|
}
|
|
|
|
|
pprof: add goroutine blocking profiling
The profiler collects goroutine blocking information similar to Google Perf Tools.
You may see an example of the profile (converted to svg) attached to
http://code.google.com/p/go/issues/detail?id=3946
The public API changes are:
+pkg runtime, func BlockProfile([]BlockProfileRecord) (int, bool)
+pkg runtime, func SetBlockProfileRate(int)
+pkg runtime, method (*BlockProfileRecord) Stack() []uintptr
+pkg runtime, type BlockProfileRecord struct
+pkg runtime, type BlockProfileRecord struct, Count int64
+pkg runtime, type BlockProfileRecord struct, Cycles int64
+pkg runtime, type BlockProfileRecord struct, embedded StackRecord
R=rsc, dave, minux.ma, r
CC=gobot, golang-dev, r, remyoudompheng
https://golang.org/cl/6443115
2012-10-06 02:56:04 -06:00
|
|
|
t0 = 0;
|
|
|
|
mysg.releasetime = 0;
|
|
|
|
if(runtime·blockprofilerate > 0) {
|
|
|
|
t0 = runtime·cputicks();
|
|
|
|
mysg.releasetime = -1;
|
|
|
|
}
|
|
|
|
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·lock(c);
|
2008-07-15 22:07:59 -06:00
|
|
|
if(c->dataqsiz > 0)
|
|
|
|
goto asynch;
|
|
|
|
|
2011-03-11 12:47:26 -07:00
|
|
|
if(c->closed)
|
2009-03-13 17:47:54 -06:00
|
|
|
goto closed;
|
|
|
|
|
2011-07-21 11:57:13 -06:00
|
|
|
sg = dequeue(&c->sendq);
|
2008-07-26 15:21:21 -06:00
|
|
|
if(sg != nil) {
|
2012-10-07 12:05:32 -06:00
|
|
|
if(raceenabled)
|
|
|
|
racesync(c, sg);
|
2011-07-20 09:51:25 -06:00
|
|
|
runtime·unlock(c);
|
|
|
|
|
2011-01-30 14:07:57 -07:00
|
|
|
if(ep != nil)
|
2014-01-21 23:36:17 -07:00
|
|
|
c->elemtype->alg->copy(c->elemsize, ep, sg->elem);
|
2008-07-26 15:21:21 -06:00
|
|
|
gp = sg->g;
|
|
|
|
gp->param = sg;
|
pprof: add goroutine blocking profiling
The profiler collects goroutine blocking information similar to Google Perf Tools.
You may see an example of the profile (converted to svg) attached to
http://code.google.com/p/go/issues/detail?id=3946
The public API changes are:
+pkg runtime, func BlockProfile([]BlockProfileRecord) (int, bool)
+pkg runtime, func SetBlockProfileRate(int)
+pkg runtime, method (*BlockProfileRecord) Stack() []uintptr
+pkg runtime, type BlockProfileRecord struct
+pkg runtime, type BlockProfileRecord struct, Count int64
+pkg runtime, type BlockProfileRecord struct, Cycles int64
+pkg runtime, type BlockProfileRecord struct, embedded StackRecord
R=rsc, dave, minux.ma, r
CC=gobot, golang-dev, r, remyoudompheng
https://golang.org/cl/6443115
2012-10-06 02:56:04 -06:00
|
|
|
if(sg->releasetime)
|
|
|
|
sg->releasetime = runtime·cputicks();
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·ready(gp);
|
2008-07-15 22:07:59 -06:00
|
|
|
|
2011-03-11 12:47:26 -07:00
|
|
|
if(received != nil)
|
|
|
|
*received = true;
|
2014-02-12 11:21:38 -07:00
|
|
|
return true;
|
2008-07-15 22:07:59 -06:00
|
|
|
}
|
2008-07-24 16:57:30 -06:00
|
|
|
|
2014-02-12 11:21:38 -07:00
|
|
|
if(!block) {
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·unlock(c);
|
2014-02-12 11:21:38 -07:00
|
|
|
return false;
|
2008-07-14 15:33:39 -06:00
|
|
|
}
|
2008-08-05 15:21:42 -06:00
|
|
|
|
2011-07-20 09:51:25 -06:00
|
|
|
mysg.elem = ep;
|
|
|
|
mysg.g = g;
|
2014-02-12 11:21:38 -07:00
|
|
|
mysg.selectdone = nil;
|
2008-07-26 15:21:21 -06:00
|
|
|
g->param = nil;
|
2011-07-20 09:51:25 -06:00
|
|
|
enqueue(&c->recvq, &mysg);
|
2014-01-22 00:27:16 -07:00
|
|
|
runtime·parkunlock(c, "chan receive");
|
2008-07-26 15:21:21 -06:00
|
|
|
|
2011-07-20 09:51:25 -06:00
|
|
|
if(g->param == nil) {
|
|
|
|
runtime·lock(c);
|
|
|
|
if(!c->closed)
|
|
|
|
runtime·throw("chanrecv: spurious wakeup");
|
|
|
|
goto closed;
|
|
|
|
}
|
2009-03-13 17:47:54 -06:00
|
|
|
|
2011-03-11 12:47:26 -07:00
|
|
|
if(received != nil)
|
|
|
|
*received = true;
|
pprof: add goroutine blocking profiling
The profiler collects goroutine blocking information similar to Google Perf Tools.
You may see an example of the profile (converted to svg) attached to
http://code.google.com/p/go/issues/detail?id=3946
The public API changes are:
+pkg runtime, func BlockProfile([]BlockProfileRecord) (int, bool)
+pkg runtime, func SetBlockProfileRate(int)
+pkg runtime, method (*BlockProfileRecord) Stack() []uintptr
+pkg runtime, type BlockProfileRecord struct
+pkg runtime, type BlockProfileRecord struct, Count int64
+pkg runtime, type BlockProfileRecord struct, Cycles int64
+pkg runtime, type BlockProfileRecord struct, embedded StackRecord
R=rsc, dave, minux.ma, r
CC=gobot, golang-dev, r, remyoudompheng
https://golang.org/cl/6443115
2012-10-06 02:56:04 -06:00
|
|
|
if(mysg.releasetime > 0)
|
|
|
|
runtime·blockevent(mysg.releasetime - t0, 2);
|
2014-02-12 11:21:38 -07:00
|
|
|
return true;
|
2008-07-14 15:33:39 -06:00
|
|
|
|
|
|
|
asynch:
|
2009-03-13 17:47:54 -06:00
|
|
|
if(c->qcount <= 0) {
|
2011-03-11 12:47:26 -07:00
|
|
|
if(c->closed)
|
2009-03-13 17:47:54 -06:00
|
|
|
goto closed;
|
|
|
|
|
2014-02-12 11:21:38 -07:00
|
|
|
if(!block) {
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·unlock(c);
|
2011-03-25 11:36:22 -06:00
|
|
|
if(received != nil)
|
|
|
|
*received = false;
|
2014-02-12 11:21:38 -07:00
|
|
|
return false;
|
2008-09-26 12:47:04 -06:00
|
|
|
}
|
2011-07-20 09:51:25 -06:00
|
|
|
mysg.g = g;
|
|
|
|
mysg.elem = nil;
|
2014-02-12 11:21:38 -07:00
|
|
|
mysg.selectdone = nil;
|
2011-07-20 09:51:25 -06:00
|
|
|
enqueue(&c->recvq, &mysg);
|
2014-01-22 00:27:16 -07:00
|
|
|
runtime·parkunlock(c, "chan receive");
|
2009-03-13 17:47:54 -06:00
|
|
|
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·lock(c);
|
2009-03-13 17:47:54 -06:00
|
|
|
goto asynch;
|
2008-07-14 18:41:38 -06:00
|
|
|
}
|
2012-10-07 12:05:32 -06:00
|
|
|
|
2014-03-26 09:05:48 -06:00
|
|
|
if(raceenabled) {
|
2012-10-07 12:05:32 -06:00
|
|
|
runtime·raceacquire(chanbuf(c, c->recvx));
|
2014-03-26 09:05:48 -06:00
|
|
|
if(c->dataqsiz == 1)
|
|
|
|
runtime·racerelease(chanbuf(c, c->recvx));
|
|
|
|
}
|
2012-10-07 12:05:32 -06:00
|
|
|
|
2011-01-30 14:07:57 -07:00
|
|
|
if(ep != nil)
|
2014-01-21 23:36:17 -07:00
|
|
|
c->elemtype->alg->copy(c->elemsize, ep, chanbuf(c, c->recvx));
|
|
|
|
c->elemtype->alg->copy(c->elemsize, chanbuf(c, c->recvx), nil);
|
2011-04-13 21:42:06 -06:00
|
|
|
if(++c->recvx == c->dataqsiz)
|
|
|
|
c->recvx = 0;
|
2008-07-14 18:41:38 -06:00
|
|
|
c->qcount--;
|
2011-07-20 09:51:25 -06:00
|
|
|
|
2011-07-21 11:57:13 -06:00
|
|
|
sg = dequeue(&c->sendq);
|
2008-07-26 15:21:21 -06:00
|
|
|
if(sg != nil) {
|
|
|
|
gp = sg->g;
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·unlock(c);
|
pprof: add goroutine blocking profiling
The profiler collects goroutine blocking information similar to Google Perf Tools.
You may see an example of the profile (converted to svg) attached to
http://code.google.com/p/go/issues/detail?id=3946
The public API changes are:
+pkg runtime, func BlockProfile([]BlockProfileRecord) (int, bool)
+pkg runtime, func SetBlockProfileRate(int)
+pkg runtime, method (*BlockProfileRecord) Stack() []uintptr
+pkg runtime, type BlockProfileRecord struct
+pkg runtime, type BlockProfileRecord struct, Count int64
+pkg runtime, type BlockProfileRecord struct, Cycles int64
+pkg runtime, type BlockProfileRecord struct, embedded StackRecord
R=rsc, dave, minux.ma, r
CC=gobot, golang-dev, r, remyoudompheng
https://golang.org/cl/6443115
2012-10-06 02:56:04 -06:00
|
|
|
if(sg->releasetime)
|
|
|
|
sg->releasetime = runtime·cputicks();
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·ready(gp);
|
2011-03-11 12:47:26 -07:00
|
|
|
} else
|
|
|
|
runtime·unlock(c);
|
2009-03-13 17:47:54 -06:00
|
|
|
|
2011-03-11 12:47:26 -07:00
|
|
|
if(received != nil)
|
|
|
|
*received = true;
|
pprof: add goroutine blocking profiling
The profiler collects goroutine blocking information similar to Google Perf Tools.
You may see an example of the profile (converted to svg) attached to
http://code.google.com/p/go/issues/detail?id=3946
The public API changes are:
+pkg runtime, func BlockProfile([]BlockProfileRecord) (int, bool)
+pkg runtime, func SetBlockProfileRate(int)
+pkg runtime, method (*BlockProfileRecord) Stack() []uintptr
+pkg runtime, type BlockProfileRecord struct
+pkg runtime, type BlockProfileRecord struct, Count int64
+pkg runtime, type BlockProfileRecord struct, Cycles int64
+pkg runtime, type BlockProfileRecord struct, embedded StackRecord
R=rsc, dave, minux.ma, r
CC=gobot, golang-dev, r, remyoudompheng
https://golang.org/cl/6443115
2012-10-06 02:56:04 -06:00
|
|
|
if(mysg.releasetime > 0)
|
|
|
|
runtime·blockevent(mysg.releasetime - t0, 2);
|
2014-02-12 11:21:38 -07:00
|
|
|
return true;
|
2009-03-13 17:47:54 -06:00
|
|
|
|
|
|
|
closed:
|
2011-01-30 14:07:57 -07:00
|
|
|
if(ep != nil)
|
2014-01-21 23:36:17 -07:00
|
|
|
c->elemtype->alg->copy(c->elemsize, ep, nil);
|
2011-03-11 12:47:26 -07:00
|
|
|
if(received != nil)
|
|
|
|
*received = false;
|
2012-10-07 12:05:32 -06:00
|
|
|
if(raceenabled)
|
|
|
|
runtime·raceacquire(c);
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·unlock(c);
|
pprof: add goroutine blocking profiling
The profiler collects goroutine blocking information similar to Google Perf Tools.
You may see an example of the profile (converted to svg) attached to
http://code.google.com/p/go/issues/detail?id=3946
The public API changes are:
+pkg runtime, func BlockProfile([]BlockProfileRecord) (int, bool)
+pkg runtime, func SetBlockProfileRate(int)
+pkg runtime, method (*BlockProfileRecord) Stack() []uintptr
+pkg runtime, type BlockProfileRecord struct
+pkg runtime, type BlockProfileRecord struct, Count int64
+pkg runtime, type BlockProfileRecord struct, Cycles int64
+pkg runtime, type BlockProfileRecord struct, embedded StackRecord
R=rsc, dave, minux.ma, r
CC=gobot, golang-dev, r, remyoudompheng
https://golang.org/cl/6443115
2012-10-06 02:56:04 -06:00
|
|
|
if(mysg.releasetime > 0)
|
|
|
|
runtime·blockevent(mysg.releasetime - t0, 2);
|
2014-02-12 11:21:38 -07:00
|
|
|
return true;
|
2008-07-13 17:20:27 -06:00
|
|
|
}
|
|
|
|
|
2013-08-12 14:47:18 -06:00
|
|
|
#pragma textflag NOSPLIT
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func chansend1(t *ChanType, c *Hchan, elem *byte) {
|
|
|
|
chansend(t, c, elem, true, runtime·getcallerpc(&t));
|
2008-07-26 15:21:21 -06:00
|
|
|
}
|
|
|
|
|
2013-08-12 14:47:18 -06:00
|
|
|
#pragma textflag NOSPLIT
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func chanrecv1(t *ChanType, c *Hchan, elem *byte) {
|
|
|
|
chanrecv(t, c, elem, true, nil);
|
2008-07-26 15:21:21 -06:00
|
|
|
}
|
2008-07-14 15:33:39 -06:00
|
|
|
|
2014-01-17 15:48:45 -07:00
|
|
|
// chanrecv2(hchan *chan any, elem *any) (received bool);
|
2013-08-12 14:47:18 -06:00
|
|
|
#pragma textflag NOSPLIT
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func chanrecv2(t *ChanType, c *Hchan, elem *byte) (received bool) {
|
|
|
|
chanrecv(t, c, elem, true, &received);
|
2008-07-26 15:21:21 -06:00
|
|
|
}
|
|
|
|
|
2011-01-30 14:07:57 -07:00
|
|
|
// compiler implements
|
|
|
|
//
|
|
|
|
// select {
|
|
|
|
// case c <- v:
|
|
|
|
// ... foo
|
|
|
|
// default:
|
|
|
|
// ... bar
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// as
|
|
|
|
//
|
2011-08-17 13:54:17 -06:00
|
|
|
// if selectnbsend(c, v) {
|
2011-01-30 14:07:57 -07:00
|
|
|
// ... foo
|
|
|
|
// } else {
|
|
|
|
// ... bar
|
|
|
|
// }
|
|
|
|
//
|
2013-08-12 14:47:18 -06:00
|
|
|
#pragma textflag NOSPLIT
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func selectnbsend(t *ChanType, c *Hchan, elem *byte) (selected bool) {
|
|
|
|
selected = chansend(t, c, elem, false, runtime·getcallerpc(&t));
|
2011-01-30 14:07:57 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// compiler implements
|
|
|
|
//
|
|
|
|
// select {
|
|
|
|
// case v = <-c:
|
|
|
|
// ... foo
|
|
|
|
// default:
|
|
|
|
// ... bar
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// as
|
|
|
|
//
|
2011-08-17 13:54:17 -06:00
|
|
|
// if selectnbrecv(&v, c) {
|
2011-01-30 14:07:57 -07:00
|
|
|
// ... foo
|
|
|
|
// } else {
|
|
|
|
// ... bar
|
|
|
|
// }
|
|
|
|
//
|
2013-08-12 14:47:18 -06:00
|
|
|
#pragma textflag NOSPLIT
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func selectnbrecv(t *ChanType, elem *byte, c *Hchan) (selected bool) {
|
|
|
|
selected = chanrecv(t, c, elem, false, nil);
|
2012-05-29 12:02:29 -06:00
|
|
|
}
|
2011-03-11 12:47:26 -07:00
|
|
|
|
|
|
|
// compiler implements
|
|
|
|
//
|
|
|
|
// select {
|
2011-03-25 11:36:22 -06:00
|
|
|
// case v, ok = <-c:
|
2011-03-11 12:47:26 -07:00
|
|
|
// ... foo
|
|
|
|
// default:
|
|
|
|
// ... bar
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// as
|
|
|
|
//
|
2011-03-25 11:36:22 -06:00
|
|
|
// if c != nil && selectnbrecv2(&v, &ok, c) {
|
2011-03-11 12:47:26 -07:00
|
|
|
// ... foo
|
|
|
|
// } else {
|
|
|
|
// ... bar
|
|
|
|
// }
|
|
|
|
//
|
2013-08-12 14:47:18 -06:00
|
|
|
#pragma textflag NOSPLIT
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func selectnbrecv2(t *ChanType, elem *byte, received *bool, c *Hchan) (selected bool) {
|
|
|
|
selected = chanrecv(t, c, elem, false, received);
|
2012-05-29 12:02:29 -06:00
|
|
|
}
|
2011-01-30 14:07:57 -07:00
|
|
|
|
2013-08-12 14:47:18 -06:00
|
|
|
#pragma textflag NOSPLIT
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func reflect·chansend(t *ChanType, c *Hchan, elem *byte, nb bool) (selected bool) {
|
|
|
|
selected = chansend(t, c, elem, !nb, runtime·getcallerpc(&t));
|
reflect: more efficient; cannot Set result of NewValue anymore
* Reduces malloc counts during gob encoder/decoder test from 6/6 to 3/5.
The current reflect uses Set to mean two subtly different things.
(1) If you have a reflect.Value v, it might just represent
itself (as in v = reflect.NewValue(42)), in which case calling
v.Set only changed v, not any other data in the program.
(2) If you have a reflect Value v derived from a pointer
or a slice (as in x := []int{42}; v = reflect.NewValue(x).Index(0)),
v represents the value held there. Changing x[0] affects the
value returned by v.Int(), and calling v.Set affects x[0].
This was not really by design; it just happened that way.
The motivation for the new reflect implementation was
to remove mallocs. The use case (1) has an implicit malloc
inside it. If you can do:
v := reflect.NewValue(0)
v.Set(42)
i := v.Int() // i = 42
then that implies that v is referring to some underlying
chunk of memory in order to remember the 42; that is,
NewValue must have allocated some memory.
Almost all the time you are using reflect the goal is to
inspect or to change other data, not to manipulate data
stored solely inside a reflect.Value.
This CL removes use case (1), so that an assignable
reflect.Value must always refer to some other piece of data
in the program. Put another way, removing this case would
make
v := reflect.NewValue(0)
v.Set(42)
as illegal as
0 = 42.
It would also make this illegal:
x := 0
v := reflect.NewValue(x)
v.Set(42)
for the same reason. (Note that right now, v.Set(42) "succeeds"
but does not change the value of x.)
If you really wanted to make v refer to x, you'd start with &x
and dereference it:
x := 0
v := reflect.NewValue(&x).Elem() // v = *&x
v.Set(42)
It's pretty rare, except in tests, to want to use NewValue and then
call Set to change the Value itself instead of some other piece of
data in the program. I haven't seen it happen once yet while
making the tree build with this change.
For the same reasons, reflect.Zero (formerly reflect.MakeZero)
would also return an unassignable, unaddressable value.
This invalidates the (awkward) idiom:
pv := ... some Ptr Value we have ...
v := reflect.Zero(pv.Type().Elem())
pv.PointTo(v)
which, when the API changed, turned into:
pv := ... some Ptr Value we have ...
v := reflect.Zero(pv.Type().Elem())
pv.Set(v.Addr())
In both, it is far from clear what the code is trying to do. Now that
it is possible, this CL adds reflect.New(Type) Value that does the
obvious thing (same as Go's new), so this code would be replaced by:
pv := ... some Ptr Value we have ...
pv.Set(reflect.New(pv.Type().Elem()))
The changes just described can be confusing to think about,
but I believe it is because the old API was confusing - it was
conflating two different kinds of Values - and that the new API
by itself is pretty simple: you can only Set (or call Addr on)
a Value if it actually addresses some real piece of data; that is,
only if it is the result of dereferencing a Ptr or indexing a Slice.
If you really want the old behavior, you'd get it by translating:
v := reflect.NewValue(x)
into
v := reflect.New(reflect.Typeof(x)).Elem()
v.Set(reflect.NewValue(x))
Gofix will not be able to help with this, because whether
and how to change the code depends on whether the original
code meant use (1) or use (2), so the developer has to read
and think about the code.
You can see the effect on packages in the tree in
https://golang.org/cl/4423043/.
R=r
CC=golang-dev
https://golang.org/cl/4435042
2011-04-18 12:35:33 -06:00
|
|
|
}
|
|
|
|
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func reflect·chanrecv(t *ChanType, c *Hchan, nb bool, elem *byte) (selected bool, received bool) {
|
reflect: more efficient; cannot Set result of NewValue anymore
* Reduces malloc counts during gob encoder/decoder test from 6/6 to 3/5.
The current reflect uses Set to mean two subtly different things.
(1) If you have a reflect.Value v, it might just represent
itself (as in v = reflect.NewValue(42)), in which case calling
v.Set only changed v, not any other data in the program.
(2) If you have a reflect Value v derived from a pointer
or a slice (as in x := []int{42}; v = reflect.NewValue(x).Index(0)),
v represents the value held there. Changing x[0] affects the
value returned by v.Int(), and calling v.Set affects x[0].
This was not really by design; it just happened that way.
The motivation for the new reflect implementation was
to remove mallocs. The use case (1) has an implicit malloc
inside it. If you can do:
v := reflect.NewValue(0)
v.Set(42)
i := v.Int() // i = 42
then that implies that v is referring to some underlying
chunk of memory in order to remember the 42; that is,
NewValue must have allocated some memory.
Almost all the time you are using reflect the goal is to
inspect or to change other data, not to manipulate data
stored solely inside a reflect.Value.
This CL removes use case (1), so that an assignable
reflect.Value must always refer to some other piece of data
in the program. Put another way, removing this case would
make
v := reflect.NewValue(0)
v.Set(42)
as illegal as
0 = 42.
It would also make this illegal:
x := 0
v := reflect.NewValue(x)
v.Set(42)
for the same reason. (Note that right now, v.Set(42) "succeeds"
but does not change the value of x.)
If you really wanted to make v refer to x, you'd start with &x
and dereference it:
x := 0
v := reflect.NewValue(&x).Elem() // v = *&x
v.Set(42)
It's pretty rare, except in tests, to want to use NewValue and then
call Set to change the Value itself instead of some other piece of
data in the program. I haven't seen it happen once yet while
making the tree build with this change.
For the same reasons, reflect.Zero (formerly reflect.MakeZero)
would also return an unassignable, unaddressable value.
This invalidates the (awkward) idiom:
pv := ... some Ptr Value we have ...
v := reflect.Zero(pv.Type().Elem())
pv.PointTo(v)
which, when the API changed, turned into:
pv := ... some Ptr Value we have ...
v := reflect.Zero(pv.Type().Elem())
pv.Set(v.Addr())
In both, it is far from clear what the code is trying to do. Now that
it is possible, this CL adds reflect.New(Type) Value that does the
obvious thing (same as Go's new), so this code would be replaced by:
pv := ... some Ptr Value we have ...
pv.Set(reflect.New(pv.Type().Elem()))
The changes just described can be confusing to think about,
but I believe it is because the old API was confusing - it was
conflating two different kinds of Values - and that the new API
by itself is pretty simple: you can only Set (or call Addr on)
a Value if it actually addresses some real piece of data; that is,
only if it is the result of dereferencing a Ptr or indexing a Slice.
If you really want the old behavior, you'd get it by translating:
v := reflect.NewValue(x)
into
v := reflect.New(reflect.Typeof(x)).Elem()
v.Set(reflect.NewValue(x))
Gofix will not be able to help with this, because whether
and how to change the code depends on whether the original
code meant use (1) or use (2), so the developer has to read
and think about the code.
You can see the effect on packages in the tree in
https://golang.org/cl/4423043/.
R=r
CC=golang-dev
https://golang.org/cl/4435042
2011-04-18 12:35:33 -06:00
|
|
|
received = false;
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
selected = chanrecv(t, c, elem, !nb, &received);
|
reflect: more efficient; cannot Set result of NewValue anymore
* Reduces malloc counts during gob encoder/decoder test from 6/6 to 3/5.
The current reflect uses Set to mean two subtly different things.
(1) If you have a reflect.Value v, it might just represent
itself (as in v = reflect.NewValue(42)), in which case calling
v.Set only changed v, not any other data in the program.
(2) If you have a reflect Value v derived from a pointer
or a slice (as in x := []int{42}; v = reflect.NewValue(x).Index(0)),
v represents the value held there. Changing x[0] affects the
value returned by v.Int(), and calling v.Set affects x[0].
This was not really by design; it just happened that way.
The motivation for the new reflect implementation was
to remove mallocs. The use case (1) has an implicit malloc
inside it. If you can do:
v := reflect.NewValue(0)
v.Set(42)
i := v.Int() // i = 42
then that implies that v is referring to some underlying
chunk of memory in order to remember the 42; that is,
NewValue must have allocated some memory.
Almost all the time you are using reflect the goal is to
inspect or to change other data, not to manipulate data
stored solely inside a reflect.Value.
This CL removes use case (1), so that an assignable
reflect.Value must always refer to some other piece of data
in the program. Put another way, removing this case would
make
v := reflect.NewValue(0)
v.Set(42)
as illegal as
0 = 42.
It would also make this illegal:
x := 0
v := reflect.NewValue(x)
v.Set(42)
for the same reason. (Note that right now, v.Set(42) "succeeds"
but does not change the value of x.)
If you really wanted to make v refer to x, you'd start with &x
and dereference it:
x := 0
v := reflect.NewValue(&x).Elem() // v = *&x
v.Set(42)
It's pretty rare, except in tests, to want to use NewValue and then
call Set to change the Value itself instead of some other piece of
data in the program. I haven't seen it happen once yet while
making the tree build with this change.
For the same reasons, reflect.Zero (formerly reflect.MakeZero)
would also return an unassignable, unaddressable value.
This invalidates the (awkward) idiom:
pv := ... some Ptr Value we have ...
v := reflect.Zero(pv.Type().Elem())
pv.PointTo(v)
which, when the API changed, turned into:
pv := ... some Ptr Value we have ...
v := reflect.Zero(pv.Type().Elem())
pv.Set(v.Addr())
In both, it is far from clear what the code is trying to do. Now that
it is possible, this CL adds reflect.New(Type) Value that does the
obvious thing (same as Go's new), so this code would be replaced by:
pv := ... some Ptr Value we have ...
pv.Set(reflect.New(pv.Type().Elem()))
The changes just described can be confusing to think about,
but I believe it is because the old API was confusing - it was
conflating two different kinds of Values - and that the new API
by itself is pretty simple: you can only Set (or call Addr on)
a Value if it actually addresses some real piece of data; that is,
only if it is the result of dereferencing a Ptr or indexing a Slice.
If you really want the old behavior, you'd get it by translating:
v := reflect.NewValue(x)
into
v := reflect.New(reflect.Typeof(x)).Elem()
v.Set(reflect.NewValue(x))
Gofix will not be able to help with this, because whether
and how to change the code depends on whether the original
code meant use (1) or use (2), so the developer has to read
and think about the code.
You can see the effect on packages in the tree in
https://golang.org/cl/4423043/.
R=r
CC=golang-dev
https://golang.org/cl/4435042
2011-04-18 12:35:33 -06:00
|
|
|
}
|
|
|
|
|
2014-01-17 15:48:45 -07:00
|
|
|
static Select* newselect(int32);
|
2011-02-22 15:40:40 -07:00
|
|
|
|
2013-08-12 14:47:18 -06:00
|
|
|
#pragma textflag NOSPLIT
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func newselect(size int32) (sel *byte) {
|
2014-01-17 15:48:45 -07:00
|
|
|
sel = (byte*)newselect(size);
|
2011-02-22 15:40:40 -07:00
|
|
|
}
|
|
|
|
|
2014-01-17 15:48:45 -07:00
|
|
|
static Select*
|
|
|
|
newselect(int32 size)
|
2011-02-22 15:40:40 -07:00
|
|
|
{
|
|
|
|
int32 n;
|
|
|
|
Select *sel;
|
|
|
|
|
2008-07-24 16:57:30 -06:00
|
|
|
n = 0;
|
|
|
|
if(size > 1)
|
|
|
|
n = size-1;
|
2008-07-26 15:21:21 -06:00
|
|
|
|
2012-02-10 22:24:14 -07:00
|
|
|
// allocate all the memory we need in a single allocation
|
|
|
|
// start with Select with size cases
|
|
|
|
// then lockorder with size entries
|
|
|
|
// then pollorder with size entries
|
2011-07-21 11:57:13 -06:00
|
|
|
sel = runtime·mal(sizeof(*sel) +
|
|
|
|
n*sizeof(sel->scase[0]) +
|
|
|
|
size*sizeof(sel->lockorder[0]) +
|
|
|
|
size*sizeof(sel->pollorder[0]));
|
2008-07-26 15:21:21 -06:00
|
|
|
|
2008-07-24 16:57:30 -06:00
|
|
|
sel->tcase = size;
|
|
|
|
sel->ncase = 0;
|
2012-02-10 22:24:14 -07:00
|
|
|
sel->lockorder = (void*)(sel->scase + size);
|
|
|
|
sel->pollorder = (void*)(sel->lockorder + size);
|
2011-07-21 11:57:13 -06:00
|
|
|
|
2010-04-01 12:56:18 -06:00
|
|
|
if(debug)
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·printf("newselect s=%p size=%d\n", sel, size);
|
2014-01-17 15:48:45 -07:00
|
|
|
return sel;
|
2008-07-24 16:57:30 -06:00
|
|
|
}
|
|
|
|
|
2011-03-23 09:28:24 -06:00
|
|
|
// cut in half to give stack a chance to split
|
2011-07-21 11:57:13 -06:00
|
|
|
static void selectsend(Select *sel, Hchan *c, void *pc, void *elem, int32 so);
|
2011-03-23 09:28:24 -06:00
|
|
|
|
2013-08-12 14:47:18 -06:00
|
|
|
#pragma textflag NOSPLIT
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func selectsend(sel *Select, c *Hchan, elem *byte) (selected bool) {
|
2011-07-21 12:10:39 -06:00
|
|
|
selected = false;
|
|
|
|
|
2008-07-25 16:55:12 -06:00
|
|
|
// nil cases do not compete
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
if(c != nil)
|
|
|
|
selectsend(sel, c, runtime·getcallerpc(&sel), elem, (byte*)&selected - (byte*)&sel);
|
2011-03-23 09:28:24 -06:00
|
|
|
}
|
2008-07-24 16:57:30 -06:00
|
|
|
|
2011-03-23 09:28:24 -06:00
|
|
|
static void
|
2011-07-21 11:57:13 -06:00
|
|
|
selectsend(Select *sel, Hchan *c, void *pc, void *elem, int32 so)
|
2011-03-23 09:28:24 -06:00
|
|
|
{
|
2011-07-21 11:57:13 -06:00
|
|
|
int32 i;
|
2011-03-23 09:28:24 -06:00
|
|
|
Scase *cas;
|
2012-05-29 12:02:29 -06:00
|
|
|
|
2008-07-24 16:57:30 -06:00
|
|
|
i = sel->ncase;
|
|
|
|
if(i >= sel->tcase)
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·throw("selectsend: too many cases");
|
2008-07-24 16:57:30 -06:00
|
|
|
sel->ncase = i+1;
|
2011-07-21 11:57:13 -06:00
|
|
|
cas = &sel->scase[i];
|
2008-07-24 16:57:30 -06:00
|
|
|
|
2011-03-23 09:28:24 -06:00
|
|
|
cas->pc = pc;
|
2008-07-24 16:57:30 -06:00
|
|
|
cas->chan = c;
|
2011-07-21 11:57:13 -06:00
|
|
|
cas->so = so;
|
2011-03-11 12:47:26 -07:00
|
|
|
cas->kind = CaseSend;
|
2011-07-21 11:57:13 -06:00
|
|
|
cas->sg.elem = elem;
|
2008-07-24 16:57:30 -06:00
|
|
|
|
2010-04-01 12:56:18 -06:00
|
|
|
if(debug)
|
2011-03-11 12:47:26 -07:00
|
|
|
runtime·printf("selectsend s=%p pc=%p chan=%p so=%d\n",
|
|
|
|
sel, cas->pc, cas->chan, cas->so);
|
2008-07-24 16:57:30 -06:00
|
|
|
}
|
|
|
|
|
2011-03-23 09:28:24 -06:00
|
|
|
// cut in half to give stack a chance to split
|
|
|
|
static void selectrecv(Select *sel, Hchan *c, void *pc, void *elem, bool*, int32 so);
|
|
|
|
|
2013-08-12 14:47:18 -06:00
|
|
|
#pragma textflag NOSPLIT
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func selectrecv(sel *Select, c *Hchan, elem *byte) (selected bool) {
|
2011-07-21 12:10:39 -06:00
|
|
|
selected = false;
|
|
|
|
|
2008-07-25 16:55:12 -06:00
|
|
|
// nil cases do not compete
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
if(c != nil)
|
|
|
|
selectrecv(sel, c, runtime·getcallerpc(&sel), elem, nil, (byte*)&selected - (byte*)&sel);
|
2011-03-11 12:47:26 -07:00
|
|
|
}
|
|
|
|
|
2013-08-12 14:47:18 -06:00
|
|
|
#pragma textflag NOSPLIT
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func selectrecv2(sel *Select, c *Hchan, elem *byte, received *bool) (selected bool) {
|
2011-07-21 12:10:39 -06:00
|
|
|
selected = false;
|
|
|
|
|
2011-03-11 12:47:26 -07:00
|
|
|
// nil cases do not compete
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
if(c != nil)
|
|
|
|
selectrecv(sel, c, runtime·getcallerpc(&sel), elem, received, (byte*)&selected - (byte*)&sel);
|
2011-03-23 09:28:24 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
selectrecv(Select *sel, Hchan *c, void *pc, void *elem, bool *received, int32 so)
|
|
|
|
{
|
|
|
|
int32 i;
|
|
|
|
Scase *cas;
|
|
|
|
|
2011-03-11 12:47:26 -07:00
|
|
|
i = sel->ncase;
|
|
|
|
if(i >= sel->tcase)
|
|
|
|
runtime·throw("selectrecv: too many cases");
|
|
|
|
sel->ncase = i+1;
|
2011-07-21 11:57:13 -06:00
|
|
|
cas = &sel->scase[i];
|
2011-03-23 09:28:24 -06:00
|
|
|
cas->pc = pc;
|
2011-03-11 12:47:26 -07:00
|
|
|
cas->chan = c;
|
|
|
|
|
2011-03-23 09:28:24 -06:00
|
|
|
cas->so = so;
|
2011-03-11 12:47:26 -07:00
|
|
|
cas->kind = CaseRecv;
|
2011-07-21 11:57:13 -06:00
|
|
|
cas->sg.elem = elem;
|
|
|
|
cas->receivedp = received;
|
2008-07-25 12:58:26 -06:00
|
|
|
|
2010-04-01 12:56:18 -06:00
|
|
|
if(debug)
|
2011-03-23 09:28:24 -06:00
|
|
|
runtime·printf("selectrecv s=%p pc=%p chan=%p so=%d\n",
|
|
|
|
sel, cas->pc, cas->chan, cas->so);
|
2008-07-24 16:57:30 -06:00
|
|
|
}
|
|
|
|
|
2011-03-23 09:28:24 -06:00
|
|
|
// cut in half to give stack a chance to split
|
2011-03-11 12:47:26 -07:00
|
|
|
static void selectdefault(Select*, void*, int32);
|
2011-02-22 15:40:40 -07:00
|
|
|
|
2013-08-12 14:47:18 -06:00
|
|
|
#pragma textflag NOSPLIT
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func selectdefault(sel *Select) (selected bool) {
|
2011-07-21 12:10:39 -06:00
|
|
|
selected = false;
|
2011-03-11 12:47:26 -07:00
|
|
|
selectdefault(sel, runtime·getcallerpc(&sel), (byte*)&selected - (byte*)&sel);
|
2011-02-22 15:40:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-03-11 12:47:26 -07:00
|
|
|
selectdefault(Select *sel, void *callerpc, int32 so)
|
2011-02-22 15:40:40 -07:00
|
|
|
{
|
2008-11-05 22:50:28 -07:00
|
|
|
int32 i;
|
2008-11-05 19:04:24 -07:00
|
|
|
Scase *cas;
|
2008-12-09 17:16:07 -07:00
|
|
|
|
2008-11-05 19:04:24 -07:00
|
|
|
i = sel->ncase;
|
|
|
|
if(i >= sel->tcase)
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·throw("selectdefault: too many cases");
|
2008-11-05 19:04:24 -07:00
|
|
|
sel->ncase = i+1;
|
2011-07-21 11:57:13 -06:00
|
|
|
cas = &sel->scase[i];
|
2011-02-22 19:10:02 -07:00
|
|
|
cas->pc = callerpc;
|
2008-11-05 22:50:28 -07:00
|
|
|
cas->chan = nil;
|
2008-11-05 19:04:24 -07:00
|
|
|
|
2011-03-11 12:47:26 -07:00
|
|
|
cas->so = so;
|
|
|
|
cas->kind = CaseDefault;
|
2008-11-05 19:04:24 -07:00
|
|
|
|
2010-04-01 12:56:18 -06:00
|
|
|
if(debug)
|
2011-03-11 12:47:26 -07:00
|
|
|
runtime·printf("selectdefault s=%p pc=%p so=%d\n",
|
|
|
|
sel, cas->pc, cas->so);
|
2008-11-05 19:04:24 -07:00
|
|
|
}
|
|
|
|
|
2009-12-04 11:57:01 -07:00
|
|
|
static void
|
|
|
|
sellock(Select *sel)
|
|
|
|
{
|
|
|
|
uint32 i;
|
2011-07-21 11:57:13 -06:00
|
|
|
Hchan *c, *c0;
|
2009-12-04 11:57:01 -07:00
|
|
|
|
|
|
|
c = nil;
|
|
|
|
for(i=0; i<sel->ncase; i++) {
|
2011-07-21 11:57:13 -06:00
|
|
|
c0 = sel->lockorder[i];
|
|
|
|
if(c0 && c0 != c) {
|
|
|
|
c = sel->lockorder[i];
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·lock(c);
|
2009-12-04 11:57:01 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
selunlock(Select *sel)
|
|
|
|
{
|
2013-05-08 15:58:34 -06:00
|
|
|
int32 i, n, r;
|
|
|
|
Hchan *c;
|
2009-12-04 11:57:01 -07:00
|
|
|
|
2013-05-08 15:58:34 -06:00
|
|
|
// We must be very careful here to not touch sel after we have unlocked
|
|
|
|
// the last lock, because sel can be freed right after the last unlock.
|
|
|
|
// Consider the following situation.
|
|
|
|
// First M calls runtime·park() in runtime·selectgo() passing the sel.
|
|
|
|
// Once runtime·park() has unlocked the last lock, another M makes
|
|
|
|
// the G that calls select runnable again and schedules it for execution.
|
|
|
|
// When the G runs on another M, it locks all the locks and frees sel.
|
|
|
|
// Now if the first M touches sel, it will access freed memory.
|
|
|
|
n = (int32)sel->ncase;
|
|
|
|
r = 0;
|
|
|
|
// skip the default case
|
|
|
|
if(n>0 && sel->lockorder[0] == nil)
|
|
|
|
r = 1;
|
|
|
|
for(i = n-1; i >= r; i--) {
|
|
|
|
c = sel->lockorder[i];
|
|
|
|
if(i>0 && sel->lockorder[i-1] == c)
|
|
|
|
continue; // will unlock it on the next iteration
|
|
|
|
runtime·unlock(c);
|
2009-12-04 11:57:01 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-22 00:27:16 -07:00
|
|
|
static bool
|
|
|
|
selparkcommit(G *gp, void *sel)
|
|
|
|
{
|
|
|
|
USED(gp);
|
|
|
|
selunlock(sel);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func block() {
|
2012-09-18 11:15:46 -06:00
|
|
|
runtime·park(nil, nil, "select (no cases)"); // forever
|
2011-01-30 14:07:57 -07:00
|
|
|
}
|
|
|
|
|
2011-02-22 19:10:02 -07:00
|
|
|
static void* selectgo(Select**);
|
2011-02-22 15:40:40 -07:00
|
|
|
|
2008-07-24 16:57:30 -06:00
|
|
|
// selectgo(sel *byte);
|
2010-10-20 13:54:17 -06:00
|
|
|
//
|
|
|
|
// overwrites return pc on stack to signal which case of the select
|
|
|
|
// to run, so cannot appear at the top of a split stack.
|
2013-08-12 14:47:18 -06:00
|
|
|
#pragma textflag NOSPLIT
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func selectgo(sel *Select) {
|
2011-02-22 19:10:02 -07:00
|
|
|
runtime·setcallerpc(&sel, selectgo(&sel));
|
2011-02-22 15:40:40 -07:00
|
|
|
}
|
|
|
|
|
2011-02-22 19:10:02 -07:00
|
|
|
static void*
|
2011-02-22 15:40:40 -07:00
|
|
|
selectgo(Select **selp)
|
|
|
|
{
|
|
|
|
Select *sel;
|
2014-02-12 11:21:38 -07:00
|
|
|
uint32 o, i, j, k, done;
|
2013-08-14 03:56:01 -06:00
|
|
|
int64 t0;
|
2008-11-05 18:57:18 -07:00
|
|
|
Scase *cas, *dfl;
|
2008-07-24 16:57:30 -06:00
|
|
|
Hchan *c;
|
2008-07-25 16:55:12 -06:00
|
|
|
SudoG *sg;
|
|
|
|
G *gp;
|
2008-08-05 15:18:47 -06:00
|
|
|
byte *as;
|
2011-02-22 19:10:02 -07:00
|
|
|
void *pc;
|
2008-07-24 16:57:30 -06:00
|
|
|
|
2011-02-22 15:40:40 -07:00
|
|
|
sel = *selp;
|
2010-01-09 10:47:45 -07:00
|
|
|
|
2010-04-01 12:56:18 -06:00
|
|
|
if(debug)
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·printf("select: sel=%p\n", sel);
|
2008-07-25 12:58:26 -06:00
|
|
|
|
2013-08-14 03:56:01 -06:00
|
|
|
t0 = 0;
|
|
|
|
if(runtime·blockprofilerate > 0) {
|
|
|
|
t0 = runtime·cputicks();
|
|
|
|
for(i=0; i<sel->ncase; i++)
|
|
|
|
sel->scase[i].sg.releasetime = -1;
|
|
|
|
}
|
|
|
|
|
2011-01-30 14:07:57 -07:00
|
|
|
// The compiler rewrites selects that statically have
|
|
|
|
// only 0 or 1 cases plus default into simpler constructs.
|
|
|
|
// The only way we can end up with such small sel->ncase
|
|
|
|
// values here is for a larger select in which most channels
|
|
|
|
// have been nilled out. The general code handles those
|
|
|
|
// cases correctly, and they are rare enough not to bother
|
|
|
|
// optimizing (and needing to test).
|
2008-07-24 16:57:30 -06:00
|
|
|
|
2011-01-20 07:20:47 -07:00
|
|
|
// generate permuted order
|
|
|
|
for(i=0; i<sel->ncase; i++)
|
2011-07-21 11:57:13 -06:00
|
|
|
sel->pollorder[i] = i;
|
2011-01-20 07:20:47 -07:00
|
|
|
for(i=1; i<sel->ncase; i++) {
|
2011-07-21 11:57:13 -06:00
|
|
|
o = sel->pollorder[i];
|
2011-07-20 12:28:55 -06:00
|
|
|
j = runtime·fastrand1()%(i+1);
|
2011-07-21 11:57:13 -06:00
|
|
|
sel->pollorder[i] = sel->pollorder[j];
|
|
|
|
sel->pollorder[j] = o;
|
2008-07-24 16:57:30 -06:00
|
|
|
}
|
2008-07-25 16:55:12 -06:00
|
|
|
|
2009-12-04 11:57:01 -07:00
|
|
|
// sort the cases by Hchan address to get the locking order.
|
2013-02-19 08:15:13 -07:00
|
|
|
// simple heap sort, to guarantee n log n time and constant stack footprint.
|
2011-07-21 11:57:13 -06:00
|
|
|
for(i=0; i<sel->ncase; i++) {
|
2013-02-19 08:15:13 -07:00
|
|
|
j = i;
|
|
|
|
c = sel->scase[j].chan;
|
|
|
|
while(j > 0 && sel->lockorder[k=(j-1)/2] < c) {
|
|
|
|
sel->lockorder[j] = sel->lockorder[k];
|
|
|
|
j = k;
|
|
|
|
}
|
2011-07-21 11:57:13 -06:00
|
|
|
sel->lockorder[j] = c;
|
2009-12-04 11:57:01 -07:00
|
|
|
}
|
2013-02-19 08:15:13 -07:00
|
|
|
for(i=sel->ncase; i-->0; ) {
|
|
|
|
c = sel->lockorder[i];
|
|
|
|
sel->lockorder[i] = sel->lockorder[0];
|
|
|
|
j = 0;
|
|
|
|
for(;;) {
|
|
|
|
k = j*2+1;
|
|
|
|
if(k >= i)
|
|
|
|
break;
|
|
|
|
if(k+1 < i && sel->lockorder[k] < sel->lockorder[k+1])
|
|
|
|
k++;
|
|
|
|
if(c < sel->lockorder[k]) {
|
|
|
|
sel->lockorder[j] = sel->lockorder[k];
|
|
|
|
j = k;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
sel->lockorder[j] = c;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
for(i=0; i+1<sel->ncase; i++)
|
|
|
|
if(sel->lockorder[i] > sel->lockorder[i+1]) {
|
|
|
|
runtime·printf("i=%d %p %p\n", i, sel->lockorder[i], sel->lockorder[i+1]);
|
|
|
|
runtime·throw("select: broken sort");
|
|
|
|
}
|
|
|
|
*/
|
2009-12-04 11:57:01 -07:00
|
|
|
sellock(sel);
|
2008-09-09 12:50:14 -06:00
|
|
|
|
2009-01-24 16:58:44 -07:00
|
|
|
loop:
|
2008-07-25 16:55:12 -06:00
|
|
|
// pass 1 - look for something already waiting
|
2008-11-05 18:57:18 -07:00
|
|
|
dfl = nil;
|
2008-07-24 16:57:30 -06:00
|
|
|
for(i=0; i<sel->ncase; i++) {
|
2011-07-21 11:57:13 -06:00
|
|
|
o = sel->pollorder[i];
|
|
|
|
cas = &sel->scase[o];
|
2008-07-24 16:57:30 -06:00
|
|
|
c = cas->chan;
|
2010-04-01 12:56:18 -06:00
|
|
|
|
2011-03-11 12:47:26 -07:00
|
|
|
switch(cas->kind) {
|
|
|
|
case CaseRecv:
|
2010-04-01 12:56:18 -06:00
|
|
|
if(c->dataqsiz > 0) {
|
|
|
|
if(c->qcount > 0)
|
|
|
|
goto asyncrecv;
|
|
|
|
} else {
|
2011-07-21 11:57:13 -06:00
|
|
|
sg = dequeue(&c->sendq);
|
2010-04-01 12:56:18 -06:00
|
|
|
if(sg != nil)
|
|
|
|
goto syncrecv;
|
2008-07-26 15:21:21 -06:00
|
|
|
}
|
2011-03-11 12:47:26 -07:00
|
|
|
if(c->closed)
|
2009-03-23 19:50:35 -06:00
|
|
|
goto rclose;
|
2010-04-01 12:56:18 -06:00
|
|
|
break;
|
2008-07-25 12:58:26 -06:00
|
|
|
|
2011-03-11 12:47:26 -07:00
|
|
|
case CaseSend:
|
2013-06-10 12:58:04 -06:00
|
|
|
if(raceenabled)
|
2014-02-12 11:21:38 -07:00
|
|
|
runtime·racereadpc(c, cas->pc, chansend);
|
2011-03-11 12:47:26 -07:00
|
|
|
if(c->closed)
|
2009-03-23 19:50:35 -06:00
|
|
|
goto sclose;
|
2010-04-01 12:56:18 -06:00
|
|
|
if(c->dataqsiz > 0) {
|
|
|
|
if(c->qcount < c->dataqsiz)
|
|
|
|
goto asyncsend;
|
|
|
|
} else {
|
2011-07-21 11:57:13 -06:00
|
|
|
sg = dequeue(&c->recvq);
|
2010-04-01 12:56:18 -06:00
|
|
|
if(sg != nil)
|
|
|
|
goto syncsend;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2011-03-11 12:47:26 -07:00
|
|
|
case CaseDefault:
|
2010-04-01 12:56:18 -06:00
|
|
|
dfl = cas;
|
|
|
|
break;
|
2008-07-25 16:55:12 -06:00
|
|
|
}
|
|
|
|
}
|
2008-12-09 17:16:07 -07:00
|
|
|
|
2008-11-05 18:57:18 -07:00
|
|
|
if(dfl != nil) {
|
2011-07-20 09:51:25 -06:00
|
|
|
selunlock(sel);
|
2008-11-05 18:57:18 -07:00
|
|
|
cas = dfl;
|
|
|
|
goto retc;
|
|
|
|
}
|
2008-12-09 17:16:07 -07:00
|
|
|
|
2008-07-25 12:58:26 -06:00
|
|
|
|
2008-07-25 16:55:12 -06:00
|
|
|
// pass 2 - enqueue on all chans
|
2014-02-12 11:21:38 -07:00
|
|
|
done = 0;
|
2008-07-25 16:55:12 -06:00
|
|
|
for(i=0; i<sel->ncase; i++) {
|
2011-08-15 00:51:51 -06:00
|
|
|
o = sel->pollorder[i];
|
|
|
|
cas = &sel->scase[o];
|
2008-07-25 16:55:12 -06:00
|
|
|
c = cas->chan;
|
2011-07-21 11:57:13 -06:00
|
|
|
sg = &cas->sg;
|
|
|
|
sg->g = g;
|
2014-02-12 11:21:38 -07:00
|
|
|
sg->selectdone = &done;
|
2008-07-26 15:21:21 -06:00
|
|
|
|
2011-03-11 12:47:26 -07:00
|
|
|
switch(cas->kind) {
|
|
|
|
case CaseRecv:
|
2008-11-06 18:50:28 -07:00
|
|
|
enqueue(&c->recvq, sg);
|
2010-04-01 12:56:18 -06:00
|
|
|
break;
|
2012-05-29 12:02:29 -06:00
|
|
|
|
2011-03-11 12:47:26 -07:00
|
|
|
case CaseSend:
|
2008-07-25 16:55:12 -06:00
|
|
|
enqueue(&c->sendq, sg);
|
2010-04-01 12:56:18 -06:00
|
|
|
break;
|
2008-11-06 18:50:28 -07:00
|
|
|
}
|
2008-07-24 16:57:30 -06:00
|
|
|
}
|
|
|
|
|
2009-01-24 16:58:44 -07:00
|
|
|
g->param = nil;
|
2014-01-22 00:27:16 -07:00
|
|
|
runtime·park(selparkcommit, sel, "select");
|
2008-07-25 16:55:12 -06:00
|
|
|
|
2009-12-04 11:57:01 -07:00
|
|
|
sellock(sel);
|
2008-07-25 16:55:12 -06:00
|
|
|
sg = g->param;
|
2010-04-01 12:56:18 -06:00
|
|
|
|
|
|
|
// pass 3 - dequeue from unsuccessful chans
|
|
|
|
// otherwise they stack up on quiet channels
|
|
|
|
for(i=0; i<sel->ncase; i++) {
|
2011-07-21 11:57:13 -06:00
|
|
|
cas = &sel->scase[i];
|
|
|
|
if(cas != (Scase*)sg) {
|
2010-04-01 12:56:18 -06:00
|
|
|
c = cas->chan;
|
2011-03-11 12:47:26 -07:00
|
|
|
if(cas->kind == CaseSend)
|
2011-07-21 11:57:13 -06:00
|
|
|
dequeueg(&c->sendq);
|
2010-04-01 12:56:18 -06:00
|
|
|
else
|
2011-07-21 11:57:13 -06:00
|
|
|
dequeueg(&c->recvq);
|
2010-04-01 12:56:18 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-01-24 16:58:44 -07:00
|
|
|
if(sg == nil)
|
|
|
|
goto loop;
|
|
|
|
|
2011-07-21 11:57:13 -06:00
|
|
|
cas = (Scase*)sg;
|
2008-07-25 16:55:12 -06:00
|
|
|
c = cas->chan;
|
|
|
|
|
2011-07-20 09:51:25 -06:00
|
|
|
if(c->dataqsiz > 0)
|
2013-04-23 14:46:14 -06:00
|
|
|
runtime·throw("selectgo: shouldn't happen");
|
2009-01-24 16:58:44 -07:00
|
|
|
|
2010-04-01 12:56:18 -06:00
|
|
|
if(debug)
|
2011-07-21 11:57:13 -06:00
|
|
|
runtime·printf("wait-return: sel=%p c=%p cas=%p kind=%d\n",
|
|
|
|
sel, c, cas, cas->kind);
|
2011-03-11 12:47:26 -07:00
|
|
|
|
|
|
|
if(cas->kind == CaseRecv) {
|
2011-07-21 11:57:13 -06:00
|
|
|
if(cas->receivedp != nil)
|
|
|
|
*cas->receivedp = true;
|
2008-07-26 15:21:21 -06:00
|
|
|
}
|
|
|
|
|
2014-01-21 23:36:17 -07:00
|
|
|
if(raceenabled) {
|
|
|
|
if(cas->kind == CaseRecv && cas->sg.elem != nil)
|
2014-02-12 11:21:38 -07:00
|
|
|
runtime·racewriteobjectpc(cas->sg.elem, c->elemtype, cas->pc, chanrecv);
|
2014-01-21 23:36:17 -07:00
|
|
|
else if(cas->kind == CaseSend)
|
2014-02-12 11:21:38 -07:00
|
|
|
runtime·racereadobjectpc(cas->sg.elem, c->elemtype, cas->pc, chansend);
|
2014-01-21 23:36:17 -07:00
|
|
|
}
|
|
|
|
|
2011-07-20 09:51:25 -06:00
|
|
|
selunlock(sel);
|
2008-07-26 15:21:21 -06:00
|
|
|
goto retc;
|
|
|
|
|
2010-04-01 12:56:18 -06:00
|
|
|
asyncrecv:
|
|
|
|
// can receive from buffer
|
2014-01-21 23:36:17 -07:00
|
|
|
if(raceenabled) {
|
|
|
|
if(cas->sg.elem != nil)
|
2014-02-12 11:21:38 -07:00
|
|
|
runtime·racewriteobjectpc(cas->sg.elem, c->elemtype, cas->pc, chanrecv);
|
2012-10-07 12:05:32 -06:00
|
|
|
runtime·raceacquire(chanbuf(c, c->recvx));
|
2014-03-26 09:05:48 -06:00
|
|
|
if(c->dataqsiz == 1)
|
|
|
|
runtime·racerelease(chanbuf(c, c->recvx));
|
2014-01-21 23:36:17 -07:00
|
|
|
}
|
2011-07-21 11:57:13 -06:00
|
|
|
if(cas->receivedp != nil)
|
|
|
|
*cas->receivedp = true;
|
|
|
|
if(cas->sg.elem != nil)
|
2014-01-21 23:36:17 -07:00
|
|
|
c->elemtype->alg->copy(c->elemsize, cas->sg.elem, chanbuf(c, c->recvx));
|
|
|
|
c->elemtype->alg->copy(c->elemsize, chanbuf(c, c->recvx), nil);
|
2011-04-13 21:42:06 -06:00
|
|
|
if(++c->recvx == c->dataqsiz)
|
|
|
|
c->recvx = 0;
|
2008-09-19 21:43:30 -06:00
|
|
|
c->qcount--;
|
2011-07-21 11:57:13 -06:00
|
|
|
sg = dequeue(&c->sendq);
|
2008-09-19 21:43:30 -06:00
|
|
|
if(sg != nil) {
|
|
|
|
gp = sg->g;
|
2011-07-20 09:51:25 -06:00
|
|
|
selunlock(sel);
|
2013-08-14 03:56:01 -06:00
|
|
|
if(sg->releasetime)
|
|
|
|
sg->releasetime = runtime·cputicks();
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·ready(gp);
|
2011-07-20 09:51:25 -06:00
|
|
|
} else {
|
|
|
|
selunlock(sel);
|
2008-09-19 21:43:30 -06:00
|
|
|
}
|
|
|
|
goto retc;
|
|
|
|
|
2010-04-01 12:56:18 -06:00
|
|
|
asyncsend:
|
|
|
|
// can send to buffer
|
2014-01-21 23:36:17 -07:00
|
|
|
if(raceenabled) {
|
2014-03-26 09:05:48 -06:00
|
|
|
if(c->dataqsiz == 1)
|
|
|
|
runtime·raceacquire(chanbuf(c, c->sendx));
|
2012-10-07 12:05:32 -06:00
|
|
|
runtime·racerelease(chanbuf(c, c->sendx));
|
2014-02-12 11:21:38 -07:00
|
|
|
runtime·racereadobjectpc(cas->sg.elem, c->elemtype, cas->pc, chansend);
|
2014-01-21 23:36:17 -07:00
|
|
|
}
|
|
|
|
c->elemtype->alg->copy(c->elemsize, chanbuf(c, c->sendx), cas->sg.elem);
|
2011-04-13 21:42:06 -06:00
|
|
|
if(++c->sendx == c->dataqsiz)
|
|
|
|
c->sendx = 0;
|
2008-09-19 21:43:30 -06:00
|
|
|
c->qcount++;
|
2011-07-21 11:57:13 -06:00
|
|
|
sg = dequeue(&c->recvq);
|
2008-09-19 21:43:30 -06:00
|
|
|
if(sg != nil) {
|
|
|
|
gp = sg->g;
|
2011-07-20 09:51:25 -06:00
|
|
|
selunlock(sel);
|
2013-08-14 03:56:01 -06:00
|
|
|
if(sg->releasetime)
|
|
|
|
sg->releasetime = runtime·cputicks();
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·ready(gp);
|
2011-07-20 09:51:25 -06:00
|
|
|
} else {
|
|
|
|
selunlock(sel);
|
2008-09-19 21:43:30 -06:00
|
|
|
}
|
|
|
|
goto retc;
|
2008-08-05 15:18:47 -06:00
|
|
|
|
2010-04-01 12:56:18 -06:00
|
|
|
syncrecv:
|
|
|
|
// can receive from sleeping sender (sg)
|
2014-01-21 23:36:17 -07:00
|
|
|
if(raceenabled) {
|
|
|
|
if(cas->sg.elem != nil)
|
2014-02-12 11:21:38 -07:00
|
|
|
runtime·racewriteobjectpc(cas->sg.elem, c->elemtype, cas->pc, chanrecv);
|
2012-10-07 12:05:32 -06:00
|
|
|
racesync(c, sg);
|
2014-01-21 23:36:17 -07:00
|
|
|
}
|
2011-07-20 09:51:25 -06:00
|
|
|
selunlock(sel);
|
2010-04-01 12:56:18 -06:00
|
|
|
if(debug)
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·printf("syncrecv: sel=%p c=%p o=%d\n", sel, c, o);
|
2011-07-21 11:57:13 -06:00
|
|
|
if(cas->receivedp != nil)
|
|
|
|
*cas->receivedp = true;
|
|
|
|
if(cas->sg.elem != nil)
|
2014-01-21 23:36:17 -07:00
|
|
|
c->elemtype->alg->copy(c->elemsize, cas->sg.elem, sg->elem);
|
2008-07-25 16:55:12 -06:00
|
|
|
gp = sg->g;
|
|
|
|
gp->param = sg;
|
2013-08-14 03:56:01 -06:00
|
|
|
if(sg->releasetime)
|
|
|
|
sg->releasetime = runtime·cputicks();
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·ready(gp);
|
2008-07-25 16:55:12 -06:00
|
|
|
goto retc;
|
|
|
|
|
2009-03-23 19:50:35 -06:00
|
|
|
rclose:
|
2010-04-01 12:56:18 -06:00
|
|
|
// read at end of closed channel
|
2011-07-20 09:51:25 -06:00
|
|
|
selunlock(sel);
|
2011-07-21 11:57:13 -06:00
|
|
|
if(cas->receivedp != nil)
|
|
|
|
*cas->receivedp = false;
|
|
|
|
if(cas->sg.elem != nil)
|
2014-01-21 23:36:17 -07:00
|
|
|
c->elemtype->alg->copy(c->elemsize, cas->sg.elem, nil);
|
2012-10-07 12:05:32 -06:00
|
|
|
if(raceenabled)
|
|
|
|
runtime·raceacquire(c);
|
2009-03-23 19:50:35 -06:00
|
|
|
goto retc;
|
|
|
|
|
2010-04-01 12:56:18 -06:00
|
|
|
syncsend:
|
|
|
|
// can send to sleeping receiver (sg)
|
2014-01-21 23:36:17 -07:00
|
|
|
if(raceenabled) {
|
2014-02-12 11:21:38 -07:00
|
|
|
runtime·racereadobjectpc(cas->sg.elem, c->elemtype, cas->pc, chansend);
|
2012-10-07 12:05:32 -06:00
|
|
|
racesync(c, sg);
|
2014-01-21 23:36:17 -07:00
|
|
|
}
|
2011-07-20 09:51:25 -06:00
|
|
|
selunlock(sel);
|
2010-04-01 12:56:18 -06:00
|
|
|
if(debug)
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·printf("syncsend: sel=%p c=%p o=%d\n", sel, c, o);
|
2011-09-26 21:46:37 -06:00
|
|
|
if(sg->elem != nil)
|
2014-01-21 23:36:17 -07:00
|
|
|
c->elemtype->alg->copy(c->elemsize, sg->elem, cas->sg.elem);
|
2008-07-25 16:55:12 -06:00
|
|
|
gp = sg->g;
|
|
|
|
gp->param = sg;
|
2013-08-14 03:56:01 -06:00
|
|
|
if(sg->releasetime)
|
|
|
|
sg->releasetime = runtime·cputicks();
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·ready(gp);
|
2008-07-24 16:57:30 -06:00
|
|
|
|
|
|
|
retc:
|
2012-09-18 12:22:41 -06:00
|
|
|
// return pc corresponding to chosen case.
|
|
|
|
// Set boolean passed during select creation
|
|
|
|
// (at offset selp + cas->so) to true.
|
|
|
|
// If cas->so == 0, this is a reflect-driven select and we
|
|
|
|
// don't need to update the boolean.
|
2011-02-22 19:10:02 -07:00
|
|
|
pc = cas->pc;
|
2012-09-18 12:22:41 -06:00
|
|
|
if(cas->so > 0) {
|
|
|
|
as = (byte*)selp + cas->so;
|
|
|
|
*as = true;
|
|
|
|
}
|
2013-08-14 03:56:01 -06:00
|
|
|
if(cas->sg.releasetime > 0)
|
|
|
|
runtime·blockevent(cas->sg.releasetime - t0, 2);
|
2011-07-21 11:57:13 -06:00
|
|
|
runtime·free(sel);
|
2011-02-22 19:10:02 -07:00
|
|
|
return pc;
|
spec, runtime, tests: send on closed channel panics
Close of closed channel panics.
Receive from closed channel never panics,
even if done repeatedly.
Fixes #1349.
Fixes #1419.
R=gri, iant, ken2, r, gri1, r2, iant2, rog, albert.strasheim, niemeyer, ejsherry
CC=golang-dev
https://golang.org/cl/3989042
2011-01-21 13:07:13 -07:00
|
|
|
|
|
|
|
sclose:
|
|
|
|
// send on closed channel
|
|
|
|
selunlock(sel);
|
|
|
|
runtime·panicstring("send on closed channel");
|
2011-02-22 19:10:02 -07:00
|
|
|
return nil; // not reached
|
2008-07-24 16:57:30 -06:00
|
|
|
}
|
|
|
|
|
2012-09-18 12:22:41 -06:00
|
|
|
// This struct must match ../reflect/value.go:/runtimeSelect.
|
|
|
|
typedef struct runtimeSelect runtimeSelect;
|
|
|
|
struct runtimeSelect
|
|
|
|
{
|
|
|
|
uintptr dir;
|
|
|
|
ChanType *typ;
|
|
|
|
Hchan *ch;
|
2014-01-16 14:35:29 -07:00
|
|
|
byte *val;
|
2012-09-18 12:22:41 -06:00
|
|
|
};
|
|
|
|
|
|
|
|
// This enum must match ../reflect/value.go:/SelectDir.
|
|
|
|
enum SelectDir {
|
|
|
|
SelectSend = 1,
|
|
|
|
SelectRecv,
|
|
|
|
SelectDefault,
|
|
|
|
};
|
|
|
|
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func reflect·rselect(cases Slice) (chosen int, recvOK bool) {
|
2012-09-18 12:22:41 -06:00
|
|
|
int32 i;
|
|
|
|
Select *sel;
|
|
|
|
runtimeSelect* rcase, *rc;
|
|
|
|
|
|
|
|
chosen = -1;
|
|
|
|
recvOK = false;
|
|
|
|
|
|
|
|
rcase = (runtimeSelect*)cases.array;
|
|
|
|
|
2014-01-17 15:48:45 -07:00
|
|
|
sel = newselect(cases.len);
|
2012-09-18 12:22:41 -06:00
|
|
|
for(i=0; i<cases.len; i++) {
|
|
|
|
rc = &rcase[i];
|
|
|
|
switch(rc->dir) {
|
|
|
|
case SelectDefault:
|
|
|
|
selectdefault(sel, (void*)i, 0);
|
|
|
|
break;
|
|
|
|
case SelectSend:
|
|
|
|
if(rc->ch == nil)
|
|
|
|
break;
|
2014-01-16 14:35:29 -07:00
|
|
|
selectsend(sel, rc->ch, (void*)i, rc->val, 0);
|
2012-09-18 12:22:41 -06:00
|
|
|
break;
|
|
|
|
case SelectRecv:
|
|
|
|
if(rc->ch == nil)
|
|
|
|
break;
|
2014-01-16 14:35:29 -07:00
|
|
|
selectrecv(sel, rc->ch, (void*)i, rc->val, &recvOK, 0);
|
2012-09-18 12:22:41 -06:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-24 12:58:34 -06:00
|
|
|
chosen = (intgo)(uintptr)selectgo(&sel);
|
2012-09-18 12:22:41 -06:00
|
|
|
}
|
|
|
|
|
2013-07-22 10:47:39 -06:00
|
|
|
static void closechan(Hchan *c, void *pc);
|
|
|
|
|
2013-08-12 14:47:18 -06:00
|
|
|
#pragma textflag NOSPLIT
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func closechan(c *Hchan) {
|
2013-07-22 10:47:39 -06:00
|
|
|
closechan(c, runtime·getcallerpc(&c));
|
|
|
|
}
|
|
|
|
|
2013-08-12 14:47:18 -06:00
|
|
|
#pragma textflag NOSPLIT
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func reflect·chanclose(c *Hchan) {
|
2013-07-22 10:47:39 -06:00
|
|
|
closechan(c, runtime·getcallerpc(&c));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
closechan(Hchan *c, void *pc)
|
2009-03-12 18:55:11 -06:00
|
|
|
{
|
2009-03-13 17:47:54 -06:00
|
|
|
SudoG *sg;
|
|
|
|
G* gp;
|
2009-03-12 18:55:11 -06:00
|
|
|
|
2011-10-13 14:58:04 -06:00
|
|
|
if(c == nil)
|
|
|
|
runtime·panicstring("close of nil channel");
|
|
|
|
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·lock(c);
|
2011-03-11 12:47:26 -07:00
|
|
|
if(c->closed) {
|
spec, runtime, tests: send on closed channel panics
Close of closed channel panics.
Receive from closed channel never panics,
even if done repeatedly.
Fixes #1349.
Fixes #1419.
R=gri, iant, ken2, r, gri1, r2, iant2, rog, albert.strasheim, niemeyer, ejsherry
CC=golang-dev
https://golang.org/cl/3989042
2011-01-21 13:07:13 -07:00
|
|
|
runtime·unlock(c);
|
|
|
|
runtime·panicstring("close of closed channel");
|
|
|
|
}
|
|
|
|
|
2012-10-07 12:05:32 -06:00
|
|
|
if(raceenabled) {
|
2013-07-22 10:47:39 -06:00
|
|
|
runtime·racewritepc(c, pc, runtime·closechan);
|
2012-10-07 12:05:32 -06:00
|
|
|
runtime·racerelease(c);
|
|
|
|
}
|
|
|
|
|
2011-03-11 12:47:26 -07:00
|
|
|
c->closed = true;
|
2009-03-13 17:47:54 -06:00
|
|
|
|
|
|
|
// release all readers
|
|
|
|
for(;;) {
|
2011-07-21 11:57:13 -06:00
|
|
|
sg = dequeue(&c->recvq);
|
2009-03-13 17:47:54 -06:00
|
|
|
if(sg == nil)
|
|
|
|
break;
|
|
|
|
gp = sg->g;
|
|
|
|
gp->param = nil;
|
2013-08-14 03:56:01 -06:00
|
|
|
if(sg->releasetime)
|
|
|
|
sg->releasetime = runtime·cputicks();
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·ready(gp);
|
2009-03-13 17:47:54 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// release all writers
|
|
|
|
for(;;) {
|
2011-07-21 11:57:13 -06:00
|
|
|
sg = dequeue(&c->sendq);
|
2009-03-13 17:47:54 -06:00
|
|
|
if(sg == nil)
|
|
|
|
break;
|
|
|
|
gp = sg->g;
|
|
|
|
gp->param = nil;
|
2013-08-14 03:56:01 -06:00
|
|
|
if(sg->releasetime)
|
|
|
|
sg->releasetime = runtime·cputicks();
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·ready(gp);
|
2009-03-13 17:47:54 -06:00
|
|
|
}
|
|
|
|
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·unlock(c);
|
2009-03-12 18:55:11 -06:00
|
|
|
}
|
|
|
|
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func reflect·chanlen(c *Hchan) (len int) {
|
reflect: more efficient; cannot Set result of NewValue anymore
* Reduces malloc counts during gob encoder/decoder test from 6/6 to 3/5.
The current reflect uses Set to mean two subtly different things.
(1) If you have a reflect.Value v, it might just represent
itself (as in v = reflect.NewValue(42)), in which case calling
v.Set only changed v, not any other data in the program.
(2) If you have a reflect Value v derived from a pointer
or a slice (as in x := []int{42}; v = reflect.NewValue(x).Index(0)),
v represents the value held there. Changing x[0] affects the
value returned by v.Int(), and calling v.Set affects x[0].
This was not really by design; it just happened that way.
The motivation for the new reflect implementation was
to remove mallocs. The use case (1) has an implicit malloc
inside it. If you can do:
v := reflect.NewValue(0)
v.Set(42)
i := v.Int() // i = 42
then that implies that v is referring to some underlying
chunk of memory in order to remember the 42; that is,
NewValue must have allocated some memory.
Almost all the time you are using reflect the goal is to
inspect or to change other data, not to manipulate data
stored solely inside a reflect.Value.
This CL removes use case (1), so that an assignable
reflect.Value must always refer to some other piece of data
in the program. Put another way, removing this case would
make
v := reflect.NewValue(0)
v.Set(42)
as illegal as
0 = 42.
It would also make this illegal:
x := 0
v := reflect.NewValue(x)
v.Set(42)
for the same reason. (Note that right now, v.Set(42) "succeeds"
but does not change the value of x.)
If you really wanted to make v refer to x, you'd start with &x
and dereference it:
x := 0
v := reflect.NewValue(&x).Elem() // v = *&x
v.Set(42)
It's pretty rare, except in tests, to want to use NewValue and then
call Set to change the Value itself instead of some other piece of
data in the program. I haven't seen it happen once yet while
making the tree build with this change.
For the same reasons, reflect.Zero (formerly reflect.MakeZero)
would also return an unassignable, unaddressable value.
This invalidates the (awkward) idiom:
pv := ... some Ptr Value we have ...
v := reflect.Zero(pv.Type().Elem())
pv.PointTo(v)
which, when the API changed, turned into:
pv := ... some Ptr Value we have ...
v := reflect.Zero(pv.Type().Elem())
pv.Set(v.Addr())
In both, it is far from clear what the code is trying to do. Now that
it is possible, this CL adds reflect.New(Type) Value that does the
obvious thing (same as Go's new), so this code would be replaced by:
pv := ... some Ptr Value we have ...
pv.Set(reflect.New(pv.Type().Elem()))
The changes just described can be confusing to think about,
but I believe it is because the old API was confusing - it was
conflating two different kinds of Values - and that the new API
by itself is pretty simple: you can only Set (or call Addr on)
a Value if it actually addresses some real piece of data; that is,
only if it is the result of dereferencing a Ptr or indexing a Slice.
If you really want the old behavior, you'd get it by translating:
v := reflect.NewValue(x)
into
v := reflect.New(reflect.Typeof(x)).Elem()
v.Set(reflect.NewValue(x))
Gofix will not be able to help with this, because whether
and how to change the code depends on whether the original
code meant use (1) or use (2), so the developer has to read
and think about the code.
You can see the effect on packages in the tree in
https://golang.org/cl/4423043/.
R=r
CC=golang-dev
https://golang.org/cl/4435042
2011-04-18 12:35:33 -06:00
|
|
|
if(c == nil)
|
|
|
|
len = 0;
|
|
|
|
else
|
|
|
|
len = c->qcount;
|
2009-08-26 13:42:22 -06:00
|
|
|
}
|
|
|
|
|
runtime: use goc2c as much as possible
Package runtime's C functions written to be called from Go
started out written in C using carefully constructed argument
lists and the FLUSH macro to write a result back to memory.
For some functions, the appropriate parameter list ended up
being architecture-dependent due to differences in alignment,
so we added 'goc2c', which takes a .goc file containing Go func
declarations but C bodies, rewrites the Go func declaration to
equivalent C declarations for the target architecture, adds the
needed FLUSH statements, and writes out an equivalent C file.
That C file is compiled as part of package runtime.
Native Client's x86-64 support introduces the most complex
alignment rules yet, breaking many functions that could until
now be portably written in C. Using goc2c for those avoids the
breakage.
Separately, Keith's work on emitting stack information from
the C compiler would require the hand-written functions
to add #pragmas specifying how many arguments are result
parameters. Using goc2c for those avoids maintaining #pragmas.
For both reasons, use goc2c for as many Go-called C functions
as possible.
This CL is a replay of the bulk of CL 15400047 and CL 15790043,
both of which were reviewed as part of the NaCl port and are
checked in to the NaCl branch. This CL is part of bringing the
NaCl code into the main tree.
No new code here, just reformatting and occasional movement
into .h files.
LGTM=r
R=dave, alex.brainman, r
CC=golang-codereviews
https://golang.org/cl/65220044
2014-02-20 13:58:47 -07:00
|
|
|
func reflect·chancap(c *Hchan) (cap int) {
|
reflect: more efficient; cannot Set result of NewValue anymore
* Reduces malloc counts during gob encoder/decoder test from 6/6 to 3/5.
The current reflect uses Set to mean two subtly different things.
(1) If you have a reflect.Value v, it might just represent
itself (as in v = reflect.NewValue(42)), in which case calling
v.Set only changed v, not any other data in the program.
(2) If you have a reflect Value v derived from a pointer
or a slice (as in x := []int{42}; v = reflect.NewValue(x).Index(0)),
v represents the value held there. Changing x[0] affects the
value returned by v.Int(), and calling v.Set affects x[0].
This was not really by design; it just happened that way.
The motivation for the new reflect implementation was
to remove mallocs. The use case (1) has an implicit malloc
inside it. If you can do:
v := reflect.NewValue(0)
v.Set(42)
i := v.Int() // i = 42
then that implies that v is referring to some underlying
chunk of memory in order to remember the 42; that is,
NewValue must have allocated some memory.
Almost all the time you are using reflect the goal is to
inspect or to change other data, not to manipulate data
stored solely inside a reflect.Value.
This CL removes use case (1), so that an assignable
reflect.Value must always refer to some other piece of data
in the program. Put another way, removing this case would
make
v := reflect.NewValue(0)
v.Set(42)
as illegal as
0 = 42.
It would also make this illegal:
x := 0
v := reflect.NewValue(x)
v.Set(42)
for the same reason. (Note that right now, v.Set(42) "succeeds"
but does not change the value of x.)
If you really wanted to make v refer to x, you'd start with &x
and dereference it:
x := 0
v := reflect.NewValue(&x).Elem() // v = *&x
v.Set(42)
It's pretty rare, except in tests, to want to use NewValue and then
call Set to change the Value itself instead of some other piece of
data in the program. I haven't seen it happen once yet while
making the tree build with this change.
For the same reasons, reflect.Zero (formerly reflect.MakeZero)
would also return an unassignable, unaddressable value.
This invalidates the (awkward) idiom:
pv := ... some Ptr Value we have ...
v := reflect.Zero(pv.Type().Elem())
pv.PointTo(v)
which, when the API changed, turned into:
pv := ... some Ptr Value we have ...
v := reflect.Zero(pv.Type().Elem())
pv.Set(v.Addr())
In both, it is far from clear what the code is trying to do. Now that
it is possible, this CL adds reflect.New(Type) Value that does the
obvious thing (same as Go's new), so this code would be replaced by:
pv := ... some Ptr Value we have ...
pv.Set(reflect.New(pv.Type().Elem()))
The changes just described can be confusing to think about,
but I believe it is because the old API was confusing - it was
conflating two different kinds of Values - and that the new API
by itself is pretty simple: you can only Set (or call Addr on)
a Value if it actually addresses some real piece of data; that is,
only if it is the result of dereferencing a Ptr or indexing a Slice.
If you really want the old behavior, you'd get it by translating:
v := reflect.NewValue(x)
into
v := reflect.New(reflect.Typeof(x)).Elem()
v.Set(reflect.NewValue(x))
Gofix will not be able to help with this, because whether
and how to change the code depends on whether the original
code meant use (1) or use (2), so the developer has to read
and think about the code.
You can see the effect on packages in the tree in
https://golang.org/cl/4423043/.
R=r
CC=golang-dev
https://golang.org/cl/4435042
2011-04-18 12:35:33 -06:00
|
|
|
if(c == nil)
|
|
|
|
cap = 0;
|
|
|
|
else
|
|
|
|
cap = c->dataqsiz;
|
2009-08-26 13:42:22 -06:00
|
|
|
}
|
|
|
|
|
2008-07-20 21:13:07 -06:00
|
|
|
static SudoG*
|
2011-07-21 11:57:13 -06:00
|
|
|
dequeue(WaitQ *q)
|
2008-07-20 21:13:07 -06:00
|
|
|
{
|
|
|
|
SudoG *sgp;
|
|
|
|
|
|
|
|
loop:
|
|
|
|
sgp = q->first;
|
|
|
|
if(sgp == nil)
|
|
|
|
return nil;
|
|
|
|
q->first = sgp->link;
|
|
|
|
|
2014-02-12 11:21:38 -07:00
|
|
|
// if sgp participates in a select and is already signaled, ignore it
|
|
|
|
if(sgp->selectdone != nil) {
|
|
|
|
// claim the right to signal
|
|
|
|
if(*sgp->selectdone != 0 || !runtime·cas(sgp->selectdone, 0, 1))
|
|
|
|
goto loop;
|
2008-07-20 21:13:07 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
return sgp;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-07-21 11:57:13 -06:00
|
|
|
dequeueg(WaitQ *q)
|
2010-04-01 12:56:18 -06:00
|
|
|
{
|
2011-07-18 14:15:01 -06:00
|
|
|
SudoG **l, *sgp, *prevsgp;
|
|
|
|
|
|
|
|
prevsgp = nil;
|
|
|
|
for(l=&q->first; (sgp=*l) != nil; l=&sgp->link, prevsgp=sgp) {
|
2010-04-01 12:56:18 -06:00
|
|
|
if(sgp->g == g) {
|
|
|
|
*l = sgp->link;
|
2011-07-18 14:15:01 -06:00
|
|
|
if(q->last == sgp)
|
|
|
|
q->last = prevsgp;
|
2010-04-01 12:56:18 -06:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2008-07-20 21:13:07 -06:00
|
|
|
enqueue(WaitQ *q, SudoG *sgp)
|
|
|
|
{
|
|
|
|
sgp->link = nil;
|
|
|
|
if(q->first == nil) {
|
|
|
|
q->first = sgp;
|
|
|
|
q->last = sgp;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
q->last->link = sgp;
|
|
|
|
q->last = sgp;
|
|
|
|
}
|
2012-10-07 12:05:32 -06:00
|
|
|
|
|
|
|
static void
|
|
|
|
racesync(Hchan *c, SudoG *sg)
|
|
|
|
{
|
|
|
|
runtime·racerelease(chanbuf(c, 0));
|
|
|
|
runtime·raceacquireg(sg->g, chanbuf(c, 0));
|
|
|
|
runtime·racereleaseg(sg->g, chanbuf(c, 0));
|
|
|
|
runtime·raceacquire(chanbuf(c, 0));
|
|
|
|
}
|