summaryrefslogtreecommitdiff
path: root/libgo/runtime
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2011-03-24 23:46:17 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2011-03-24 23:46:17 +0000
commitf97228863f84f4d7d87959ea40df40130f2ec912 (patch)
tree9319bca77115a32f6a0b5e8bcd651465b14c76da /libgo/runtime
parentd304b9e1af728d54ec16155c3d2116dc398c33c6 (diff)
downloadgcc-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.h7
-rw-r--r--libgo/runtime/go-rec-big.c3
-rw-r--r--libgo/runtime/go-rec-nb-big.c15
-rw-r--r--libgo/runtime/go-rec-nb-small.c4
-rw-r--r--libgo/runtime/go-rec-small.c3
-rw-r--r--libgo/runtime/go-reflect-chan.c45
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;
+ }
}
}