diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-03-24 23:46:17 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-03-24 23:46:17 +0000 |
commit | f97228863f84f4d7d87959ea40df40130f2ec912 (patch) | |
tree | 9319bca77115a32f6a0b5e8bcd651465b14c76da /libgo/runtime | |
parent | d304b9e1af728d54ec16155c3d2116dc398c33c6 (diff) | |
download | gcc-f97228863f84f4d7d87959ea40df40130f2ec912.tar.gz |
Update to current version of Go library.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@171427 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/runtime')
-rw-r--r-- | libgo/runtime/channel.h | 7 | ||||
-rw-r--r-- | libgo/runtime/go-rec-big.c | 3 | ||||
-rw-r--r-- | libgo/runtime/go-rec-nb-big.c | 15 | ||||
-rw-r--r-- | libgo/runtime/go-rec-nb-small.c | 4 | ||||
-rw-r--r-- | libgo/runtime/go-rec-small.c | 3 | ||||
-rw-r--r-- | libgo/runtime/go-reflect-chan.c | 45 |
6 files changed, 51 insertions, 26 deletions
diff --git a/libgo/runtime/channel.h b/libgo/runtime/channel.h index ea108289bf3..743af8bee9a 100644 --- a/libgo/runtime/channel.h +++ b/libgo/runtime/channel.h @@ -119,8 +119,12 @@ extern void __go_receive_release (struct __go_channel *); struct __go_receive_nonblocking_small { + /* Value read from channel, or 0. */ uint64_t __val; + /* True if value was read from channel. */ _Bool __success; + /* True if channel is closed. */ + _Bool __closed; }; extern struct __go_receive_nonblocking_small @@ -128,7 +132,8 @@ __go_receive_nonblocking_small (struct __go_channel *); extern _Bool __go_receive_big (struct __go_channel *, void *, _Bool); -extern _Bool __go_receive_nonblocking_big (struct __go_channel *, void *); +extern _Bool __go_receive_nonblocking_big (struct __go_channel *, void *, + _Bool *); extern void __go_unlock_and_notify_selects (struct __go_channel *); diff --git a/libgo/runtime/go-rec-big.c b/libgo/runtime/go-rec-big.c index a584fe7a273..fd3923ce272 100644 --- a/libgo/runtime/go-rec-big.c +++ b/libgo/runtime/go-rec-big.c @@ -9,6 +9,9 @@ #include "go-panic.h" #include "channel.h" +/* Returns true if a value was received, false if the channel is + closed. */ + _Bool __go_receive_big (struct __go_channel *channel, void *val, _Bool for_select) { diff --git a/libgo/runtime/go-rec-nb-big.c b/libgo/runtime/go-rec-nb-big.c index 53ffe48ab97..78db587345f 100644 --- a/libgo/runtime/go-rec-nb-big.c +++ b/libgo/runtime/go-rec-nb-big.c @@ -8,8 +8,11 @@ #include "channel.h" +/* Return true if a value was received, false if not. */ + _Bool -__go_receive_nonblocking_big (struct __go_channel* channel, void *val) +__go_receive_nonblocking_big (struct __go_channel* channel, void *val, + _Bool *closed) { size_t alloc_size; size_t offset; @@ -21,13 +24,9 @@ __go_receive_nonblocking_big (struct __go_channel* channel, void *val) if (data != RECEIVE_NONBLOCKING_ACQUIRE_DATA) { __builtin_memset (val, 0, channel->element_size); - if (data == RECEIVE_NONBLOCKING_ACQUIRE_NODATA) - return 0; - else - { - /* Channel is closed. */ - return 1; - } + if (closed != NULL) + *closed = data == RECEIVE_NONBLOCKING_ACQUIRE_CLOSED; + return 0; } offset = channel->next_fetch * alloc_size; diff --git a/libgo/runtime/go-rec-nb-small.c b/libgo/runtime/go-rec-nb-small.c index d77a2ace432..d09901b0c88 100644 --- a/libgo/runtime/go-rec-nb-small.c +++ b/libgo/runtime/go-rec-nb-small.c @@ -103,7 +103,8 @@ __go_receive_nonblocking_small (struct __go_channel *channel) if (data != RECEIVE_NONBLOCKING_ACQUIRE_DATA) { ret.__val = 0; - ret.__success = data == RECEIVE_NONBLOCKING_ACQUIRE_CLOSED; + ret.__success = 0; + ret.__closed = data == RECEIVE_NONBLOCKING_ACQUIRE_CLOSED; return ret; } @@ -112,6 +113,7 @@ __go_receive_nonblocking_small (struct __go_channel *channel) __go_receive_release (channel); ret.__success = 1; + ret.__closed = 0; return ret; } diff --git a/libgo/runtime/go-rec-small.c b/libgo/runtime/go-rec-small.c index 87aed3cd552..ee85cde566b 100644 --- a/libgo/runtime/go-rec-small.c +++ b/libgo/runtime/go-rec-small.c @@ -96,7 +96,8 @@ __go_broadcast_to_select (struct __go_channel *channel) } /* Prepare to receive something on a channel. Return true if the - channel is acquired, false if it is closed. */ + channel is acquired (which implies that there is data available), + false if it is closed. */ _Bool __go_receive_acquire (struct __go_channel *channel, _Bool for_select) diff --git a/libgo/runtime/go-reflect-chan.c b/libgo/runtime/go-reflect-chan.c index 412cfeedfe3..6ec1b9a2dc7 100644 --- a/libgo/runtime/go-reflect-chan.c +++ b/libgo/runtime/go-reflect-chan.c @@ -27,7 +27,7 @@ extern void chansend (unsigned char *, unsigned char *, _Bool *) asm ("libgo_reflect.reflect.chansend"); void -chansend (unsigned char *ch, unsigned char *val, _Bool *pres) +chansend (unsigned char *ch, unsigned char *val, _Bool *selected) { struct __go_channel *channel = (struct __go_channel *) ch; @@ -46,25 +46,26 @@ chansend (unsigned char *ch, unsigned char *val, _Bool *pres) __builtin_memcpy (u.b + sizeof (uint64_t) - channel->element_size, val, channel->element_size); #endif - if (pres == NULL) + if (selected == NULL) __go_send_small (channel, u.v, 0); else - *pres = __go_send_nonblocking_small (channel, u.v); + *selected = __go_send_nonblocking_small (channel, u.v); } else { - if (pres == NULL) + if (selected == NULL) __go_send_big (channel, val, 0); else - *pres = __go_send_nonblocking_big (channel, val); + *selected = __go_send_nonblocking_big (channel, val); } } -extern void chanrecv (unsigned char *, unsigned char *, _Bool *) +extern void chanrecv (unsigned char *, unsigned char *, _Bool *, _Bool *) asm ("libgo_reflect.reflect.chanrecv"); void -chanrecv (unsigned char *ch, unsigned char *val, _Bool *pres) +chanrecv (unsigned char *ch, unsigned char *val, _Bool *selected, + _Bool *received) { struct __go_channel *channel = (struct __go_channel *) ch; @@ -76,16 +77,16 @@ chanrecv (unsigned char *ch, unsigned char *val, _Bool *pres) uint64_t v; } u; - if (pres == NULL) - u.v = __go_receive_small (channel, 0); + if (selected == NULL) + u.v = __go_receive_small_closed (channel, 0, received); else { struct __go_receive_nonblocking_small s; s = __go_receive_nonblocking_small (channel); - *pres = s.__success; - if (!s.__success) - return; + *selected = s.__success || s.__closed; + if (received != NULL) + *received = s.__success; u.v = s.__val; } @@ -98,10 +99,24 @@ chanrecv (unsigned char *ch, unsigned char *val, _Bool *pres) } else { - if (pres == NULL) - __go_receive_big (channel, val, 0); + if (selected == NULL) + { + _Bool success; + + success = __go_receive_big (channel, val, 0); + if (received != NULL) + *received = success; + } else - *pres = __go_receive_nonblocking_big (channel, val); + { + _Bool got; + _Bool closed; + + got = __go_receive_nonblocking_big (channel, val, &closed); + *selected = got || closed; + if (received != NULL) + *received = got; + } } } |