OSDN Git Service

Remove closed function. Fix tuple receive in select.
[pf3gnuchains/gcc-fork.git] / libgo / runtime / go-reflect-chan.c
1 /* go-reflect-chan.c -- channel reflection support for Go.
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 <stdlib.h>
8 #include <stdint.h>
9
10 #include "config.h"
11 #include "go-type.h"
12 #include "channel.h"
13
14 /* This file implements support for reflection on channels.  These
15    functions are called from reflect/value.go.  */
16
17 extern unsigned char *makechan (const struct __go_type_descriptor *, uint32_t)
18   asm ("libgo_reflect.reflect.makechan");
19
20 unsigned char *
21 makechan (const struct __go_type_descriptor *typ, uint32_t size)
22 {
23   return (unsigned char *) __go_new_channel (typ->__size, size);
24 }
25
26 extern void chansend (unsigned char *, unsigned char *, _Bool *)
27   asm ("libgo_reflect.reflect.chansend");
28
29 void
30 chansend (unsigned char *ch, unsigned char *val, _Bool *selected)
31 {
32   struct __go_channel *channel = (struct __go_channel *) ch;
33
34   if (channel->element_size <= sizeof (uint64_t))
35     {
36       union
37       {
38         char b[sizeof (uint64_t)];
39         uint64_t v;
40       } u;
41
42       __builtin_memset (u.b, 0, sizeof (uint64_t));
43 #ifndef WORDS_BIGENDIAN
44       __builtin_memcpy (u.b, val, channel->element_size);
45 #else
46       __builtin_memcpy (u.b + sizeof (uint64_t) - channel->element_size, val,
47                         channel->element_size);
48 #endif
49       if (selected == NULL)
50         __go_send_small (channel, u.v, 0);
51       else
52         *selected = __go_send_nonblocking_small (channel, u.v);
53     }
54   else
55     {
56       if (selected == NULL)
57         __go_send_big (channel, val, 0);
58       else
59         *selected = __go_send_nonblocking_big (channel, val);
60     }
61 }
62
63 extern void chanrecv (unsigned char *, unsigned char *, _Bool *, _Bool *)
64   asm ("libgo_reflect.reflect.chanrecv");
65
66 void
67 chanrecv (unsigned char *ch, unsigned char *val, _Bool *selected,
68           _Bool *received)
69 {
70   struct __go_channel *channel = (struct __go_channel *) ch;
71
72   if (channel->element_size <= sizeof (uint64_t))
73     {
74       union
75       {
76         char b[sizeof (uint64_t)];
77         uint64_t v;
78       } u;
79
80       if (selected == NULL)
81         u.v = __go_receive_small_closed (channel, 0, received);
82       else
83         {
84           struct __go_receive_nonblocking_small s;
85
86           s = __go_receive_nonblocking_small (channel);
87           *selected = s.__success || s.__closed;
88           if (received != NULL)
89             *received = s.__success;
90           u.v = s.__val;
91         }
92
93 #ifndef WORDS_BIGENDIAN
94       __builtin_memcpy (val, u.b, channel->element_size);
95 #else
96       __builtin_memcpy (val, u.b + sizeof (uint64_t) - channel->element_size,
97                         channel->element_size);
98 #endif
99     }
100   else
101     {
102       if (selected == NULL)
103         {
104           _Bool success;
105
106           success = __go_receive_big (channel, val, 0);
107           if (received != NULL)
108             *received = success;
109         }
110       else
111         {
112           _Bool got;
113           _Bool closed;
114
115           got = __go_receive_nonblocking_big (channel, val, &closed);
116           *selected = got || closed;
117           if (received != NULL)
118             *received = got;
119         }
120     }
121 }
122
123 extern _Bool chanclosed (unsigned char *)
124   asm ("libgo_reflect.reflect.chanclosed");
125
126 _Bool
127 chanclosed (unsigned char *ch)
128 {
129   struct __go_channel *channel = (struct __go_channel *) ch;
130
131   return __go_builtin_closed (channel);
132 }
133
134 extern void chanclose (unsigned char *)
135   asm ("libgo_reflect.reflect.chanclose");
136
137 void
138 chanclose (unsigned char *ch)
139 {
140   struct __go_channel *channel = (struct __go_channel *) ch;
141
142   __go_builtin_close (channel);
143 }
144
145 extern int32_t chanlen (unsigned char *) asm ("libgo_reflect.reflect.chanlen");
146
147 int32_t
148 chanlen (unsigned char *ch)
149 {
150   struct __go_channel *channel = (struct __go_channel *) ch;
151
152   return (int32_t) __go_chan_len (channel);
153 }
154
155 extern int32_t chancap (unsigned char *) asm ("libgo_reflect.reflect.chancap");
156
157 int32_t
158 chancap (unsigned char *ch)
159 {
160   struct __go_channel *channel = (struct __go_channel *) ch;
161
162   return (int32_t) __go_chan_cap (channel);
163 }