diff options
Diffstat (limited to 'libgo/runtime')
-rw-r--r-- | libgo/runtime/channel.h | 13 | ||||
-rw-r--r-- | libgo/runtime/go-close.c | 8 | ||||
-rw-r--r-- | libgo/runtime/go-new-channel.c | 1 | ||||
-rw-r--r-- | libgo/runtime/go-rec-nb-small.c | 10 | ||||
-rw-r--r-- | libgo/runtime/go-rec-small.c | 6 | ||||
-rw-r--r-- | libgo/runtime/go-send-big.c | 3 | ||||
-rw-r--r-- | libgo/runtime/go-send-nb-big.c | 5 | ||||
-rw-r--r-- | libgo/runtime/go-send-nb-small.c | 24 | ||||
-rw-r--r-- | libgo/runtime/go-send-small.c | 28 |
9 files changed, 32 insertions, 66 deletions
diff --git a/libgo/runtime/channel.h b/libgo/runtime/channel.h index b0d13477a1c..5d2f49f1ee8 100644 --- a/libgo/runtime/channel.h +++ b/libgo/runtime/channel.h @@ -36,8 +36,6 @@ struct __go_channel pthread_cond_t cond; /* The size of elements on this channel. */ size_t element_size; - /* Number of operations on closed channel. */ - unsigned short closed_op_count; /* True if a goroutine is waiting to send on a synchronous channel. */ _Bool waiting_to_send; @@ -84,22 +82,15 @@ struct __go_channel acquired while this mutex is held. */ extern pthread_mutex_t __go_select_data_mutex; -/* Maximum permitted number of operations on a closed channel. */ -#define MAX_CLOSED_OPERATIONS (0x100) - extern struct __go_channel *__go_new_channel (size_t, size_t); extern _Bool __go_synch_with_select (struct __go_channel *, _Bool); extern void __go_broadcast_to_select (struct __go_channel *); -extern _Bool __go_send_acquire (struct __go_channel *, _Bool); - -#define SEND_NONBLOCKING_ACQUIRE_SPACE 0 -#define SEND_NONBLOCKING_ACQUIRE_NOSPACE 1 -#define SEND_NONBLOCKING_ACQUIRE_CLOSED 2 +extern void __go_send_acquire (struct __go_channel *, _Bool); -extern int __go_send_nonblocking_acquire (struct __go_channel *); +extern _Bool __go_send_nonblocking_acquire (struct __go_channel *); extern void __go_send_release (struct __go_channel *); diff --git a/libgo/runtime/go-close.c b/libgo/runtime/go-close.c index ced742985f6..44533ebe4c7 100644 --- a/libgo/runtime/go-close.c +++ b/libgo/runtime/go-close.c @@ -5,6 +5,7 @@ license that can be found in the LICENSE file. */ #include "go-assert.h" +#include "go-panic.h" #include "channel.h" /* Close a channel. After a channel is closed, sends are no longer @@ -24,6 +25,13 @@ __go_builtin_close (struct __go_channel *channel) __go_assert (i == 0); } + if (channel->is_closed) + { + i = pthread_mutex_unlock (&channel->lock); + __go_assert (i == 0); + __go_panic_msg ("close of closed channel"); + } + channel->is_closed = 1; i = pthread_cond_broadcast (&channel->cond); diff --git a/libgo/runtime/go-new-channel.c b/libgo/runtime/go-new-channel.c index d57f52c6c15..d16bde62d75 100644 --- a/libgo/runtime/go-new-channel.c +++ b/libgo/runtime/go-new-channel.c @@ -39,7 +39,6 @@ __go_new_channel (size_t element_size, size_t entries) i = pthread_cond_init (&ret->cond, NULL); __go_assert (i == 0); ret->element_size = element_size; - ret->closed_op_count = 0; ret->waiting_to_send = 0; ret->waiting_to_receive = 0; ret->selected_for_send = 0; diff --git a/libgo/runtime/go-rec-nb-small.c b/libgo/runtime/go-rec-nb-small.c index 9983d34644d..d77a2ace432 100644 --- a/libgo/runtime/go-rec-nb-small.c +++ b/libgo/runtime/go-rec-nb-small.c @@ -32,16 +32,6 @@ __go_receive_nonblocking_acquire (struct __go_channel *channel) ? channel->next_store == 0 : channel->next_fetch == channel->next_store)) { - if (channel->saw_close) - { - ++channel->closed_op_count; - if (channel->closed_op_count >= MAX_CLOSED_OPERATIONS) - { - i = pthread_mutex_unlock (&channel->lock); - __go_assert (i == 0); - __go_panic_msg ("too many operations on closed channel"); - } - } channel->saw_close = 1; __go_unlock_and_notify_selects (channel); return RECEIVE_NONBLOCKING_ACQUIRE_CLOSED; diff --git a/libgo/runtime/go-rec-small.c b/libgo/runtime/go-rec-small.c index 765e8d310de..c4dc8b6e892 100644 --- a/libgo/runtime/go-rec-small.c +++ b/libgo/runtime/go-rec-small.c @@ -123,12 +123,6 @@ __go_receive_acquire (struct __go_channel *channel, _Bool for_select) ? channel->next_store == 0 : channel->next_fetch == channel->next_store)) { - if (channel->saw_close) - { - ++channel->closed_op_count; - if (channel->closed_op_count >= MAX_CLOSED_OPERATIONS) - __go_panic_msg ("too many operations on closed channel"); - } channel->saw_close = 1; channel->selected_for_receive = 0; __go_unlock_and_notify_selects (channel); diff --git a/libgo/runtime/go-send-big.c b/libgo/runtime/go-send-big.c index f58ffb6c82d..c2732639536 100644 --- a/libgo/runtime/go-send-big.c +++ b/libgo/runtime/go-send-big.c @@ -21,8 +21,7 @@ __go_send_big (struct __go_channel* channel, const void *val, _Bool for_select) alloc_size = ((channel->element_size + sizeof (uint64_t) - 1) / sizeof (uint64_t)); - if (!__go_send_acquire (channel, for_select)) - return; + __go_send_acquire (channel, for_select); offset = channel->next_store * alloc_size; __builtin_memcpy (&channel->data[offset], val, channel->element_size); diff --git a/libgo/runtime/go-send-nb-big.c b/libgo/runtime/go-send-nb-big.c index 288ce7f4419..1d33dd6207b 100644 --- a/libgo/runtime/go-send-nb-big.c +++ b/libgo/runtime/go-send-nb-big.c @@ -17,9 +17,8 @@ __go_send_nonblocking_big (struct __go_channel* channel, const void *val) alloc_size = ((channel->element_size + sizeof (uint64_t) - 1) / sizeof (uint64_t)); - int data = __go_send_nonblocking_acquire (channel); - if (data != SEND_NONBLOCKING_ACQUIRE_SPACE) - return data == SEND_NONBLOCKING_ACQUIRE_CLOSED; + if (!__go_send_nonblocking_acquire (channel)) + return 0; offset = channel->next_store * alloc_size; __builtin_memcpy (&channel->data[offset], val, channel->element_size); diff --git a/libgo/runtime/go-send-nb-small.c b/libgo/runtime/go-send-nb-small.c index f23ae016433..5c49a67ffb4 100644 --- a/libgo/runtime/go-send-nb-small.c +++ b/libgo/runtime/go-send-nb-small.c @@ -10,9 +10,11 @@ #include "go-panic.h" #include "channel.h" -/* Prepare to send something on a nonblocking channel. */ +/* Prepare to send something on a nonblocking channel. Return true if + we acquired the channel, false if we did not acquire it because + there is no space to send a value. */ -int +_Bool __go_send_nonblocking_acquire (struct __go_channel *channel) { int i; @@ -29,16 +31,9 @@ __go_send_nonblocking_acquire (struct __go_channel *channel) if (channel->is_closed) { - ++channel->closed_op_count; - if (channel->closed_op_count >= MAX_CLOSED_OPERATIONS) - { - i = pthread_mutex_unlock (&channel->lock); - __go_assert (i == 0); - __go_panic_msg ("too many operations on closed channel"); - } i = pthread_mutex_unlock (&channel->lock); __go_assert (i == 0); - return SEND_NONBLOCKING_ACQUIRE_CLOSED; + __go_panic_msg ("send on closed channel"); } if (channel->num_entries > 0) @@ -87,10 +82,10 @@ __go_send_nonblocking_acquire (struct __go_channel *channel) i = pthread_mutex_unlock (&channel->lock); __go_assert (i == 0); - return SEND_NONBLOCKING_ACQUIRE_NOSPACE; + return 0; } - return SEND_NONBLOCKING_ACQUIRE_SPACE; + return 1; } /* Send something 64 bits or smaller on a channel. */ @@ -100,9 +95,8 @@ __go_send_nonblocking_small (struct __go_channel *channel, uint64_t val) { __go_assert (channel->element_size <= sizeof (uint64_t)); - int data = __go_send_nonblocking_acquire (channel); - if (data != SEND_NONBLOCKING_ACQUIRE_SPACE) - return data == SEND_NONBLOCKING_ACQUIRE_CLOSED; + if (!__go_send_nonblocking_acquire (channel)) + return 0; channel->data[channel->next_store] = val; diff --git a/libgo/runtime/go-send-small.c b/libgo/runtime/go-send-small.c index 506c90e648d..56f9470911f 100644 --- a/libgo/runtime/go-send-small.c +++ b/libgo/runtime/go-send-small.c @@ -10,12 +10,11 @@ #include "go-panic.h" #include "channel.h" -/* Prepare to send something on a channel. Return true if the channel - is acquired, false, if it is closed. FOR_SELECT is true if this +/* Prepare to send something on a channel. FOR_SELECT is true if this call is being made after a select statement returned with this channel selected. */ -_Bool +void __go_send_acquire (struct __go_channel *channel, _Bool for_select) { int i; @@ -25,19 +24,13 @@ __go_send_acquire (struct __go_channel *channel, _Bool for_select) while (1) { - /* Check whether the channel is closed. */ if (channel->is_closed) { - ++channel->closed_op_count; - if (channel->closed_op_count >= MAX_CLOSED_OPERATIONS) - { - i = pthread_mutex_unlock (&channel->lock); - __go_assert (i == 0); - __go_panic_msg ("too many operations on closed channel"); - } - channel->selected_for_send = 0; - __go_unlock_and_notify_selects (channel); - return 0; + if (for_select) + channel->selected_for_send = 0; + i = pthread_mutex_unlock (&channel->lock); + __go_assert (i == 0); + __go_panic_msg ("send on closed channel"); } /* If somebody else has the channel locked for sending, we have @@ -54,7 +47,7 @@ __go_send_acquire (struct __go_channel *channel, _Bool for_select) if (!channel->waiting_to_send) { __go_assert (channel->next_store == 0); - return 1; + return; } } else @@ -62,7 +55,7 @@ __go_send_acquire (struct __go_channel *channel, _Bool for_select) /* If there is room on the channel, we are OK. */ if ((channel->next_store + 1) % channel->num_entries != channel->next_fetch) - return 1; + return; } } @@ -156,8 +149,7 @@ __go_send_small (struct __go_channel *channel, uint64_t val, _Bool for_select) __go_assert (channel->element_size <= sizeof (uint64_t)); - if (!__go_send_acquire (channel, for_select)) - return; + __go_send_acquire (channel, for_select); channel->data[channel->next_store] = val; |