OSDN Git Service

Block forever on send/receive to/from nil channel.
[pf3gnuchains/gcc-fork.git] / libgo / runtime / go-rec-big.c
1 /* go-rec-big.c -- receive something larger than 64 bits on a channel.
2
3    Copyright 2009 The Go Authors. All rights reserved.
4    Use of this source code is governed by a BSD-style
5    license that can be found in the LICENSE file.  */
6
7 #include <stdint.h>
8
9 #include "go-panic.h"
10 #include "channel.h"
11
12 /* Returns true if a value was received, false if the channel is
13    closed.  */
14
15 _Bool
16 __go_receive_big (struct __go_channel *channel, void *val, _Bool for_select)
17 {
18   uintptr_t element_size;
19   size_t alloc_size;
20   size_t offset;
21
22   if (channel == NULL)
23     {
24       /* Block forever.  */
25       __go_select (0, 0, NULL, NULL);
26     }
27
28   element_size = channel->element_type->__size;
29   alloc_size = (element_size + sizeof (uint64_t) - 1) / sizeof (uint64_t);
30
31   if (!__go_receive_acquire (channel, for_select))
32     {
33       __builtin_memset (val, 0, element_size);
34       return 0;
35     }
36
37   offset = channel->next_fetch * alloc_size;
38   __builtin_memcpy (val, &channel->data[offset], element_size);
39
40   __go_receive_release (channel);
41
42   return 1;
43 }