OSDN Git Service

Avoid always splitting the stack when calling append and copy.
[pf3gnuchains/gcc-fork.git] / libgo / runtime / channel.h
1 /* channel.h -- the channel type 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 <stdint.h>
8 #include <pthread.h>
9
10 /* This structure is used when a select is waiting for a synchronous
11    channel.  */
12
13 struct __go_channel_select
14 {
15   /* A pointer to the next select waiting for this channel.  */
16   struct __go_channel_select *next;
17   /* A pointer to the channel which this select will use.  This starts
18      out as NULL and is set to the first channel which synchs up with
19      this one.  This variable to which this points may only be
20      accessed when __go_select_data_mutex is held.  */
21   struct __go_channel **selected;
22   /* A pointer to a variable which must be set to true if the
23      goroutine which sets *SELECTED wants to read from the channel,
24      false if it wants to write to it.  */
25   _Bool *is_read;
26 };
27
28 /* A channel is a pointer to this structure.  */
29
30 struct __go_channel
31 {
32   /* A mutex to control access to the channel.  */
33   pthread_mutex_t lock;
34   /* A condition variable.  This is signalled when data is added to
35      the channel and when data is removed from the channel.  */
36   pthread_cond_t cond;
37   /* The size of elements on this channel.  */
38   size_t element_size;
39   /* Number of operations on closed channel.  */
40   unsigned short closed_op_count;
41   /* True if a goroutine is waiting to send on a synchronous
42      channel.  */
43   _Bool waiting_to_send;
44   /* True if a goroutine is waiting to receive on a synchronous
45      channel.  */
46   _Bool waiting_to_receive;
47   /* True if this channel was selected for send in a select statement.
48      This looks out all other sends.  */
49   _Bool selected_for_send;
50   /* True if this channel was selected for receive in a select
51      statement.  This locks out all other receives.  */
52   _Bool selected_for_receive;
53   /* True if this channel has been closed.  */
54   _Bool is_closed;
55   /* True if at least one null value has been read from a closed
56      channel.  */
57   _Bool saw_close;
58   /* The list of select statements waiting to send on a synchronous
59      channel.  */
60   struct __go_channel_select *select_send_queue;
61   /* The list of select statements waiting to receive on a synchronous
62      channel.  */
63   struct __go_channel_select *select_receive_queue;
64   /* If a select statement is waiting for this channel, it sets these
65      pointers.  When something happens on the channel, the channel
66      locks the mutex, signals the condition, and unlocks the
67      mutex.  */
68   pthread_mutex_t *select_mutex;
69   pthread_cond_t *select_cond;
70   /* The number of entries in the circular buffer.  */
71   unsigned int num_entries;
72   /* Where to store the next value.  */
73   unsigned int next_store;
74   /* Where to fetch the next value.  If next_fetch == next_store, the
75      buffer is empty.  If next_store + 1 == next_fetch, the buffer is
76      full.  */
77   unsigned int next_fetch;
78   /* The circular buffer.  */
79   uint64_t data[];
80 };
81
82 /* The mutex used to control access to the value pointed to by the
83    __go_channel_select selected field.  No additional mutexes may be
84    acquired while this mutex is held.  */
85 extern pthread_mutex_t __go_select_data_mutex;
86
87 /* Maximum permitted number of operations on a closed channel.  */
88 #define MAX_CLOSED_OPERATIONS (0x100)
89
90 extern struct __go_channel *__go_new_channel (size_t, size_t);
91
92 extern _Bool __go_synch_with_select (struct __go_channel *, _Bool);
93
94 extern void __go_broadcast_to_select (struct __go_channel *);
95
96 extern _Bool __go_send_acquire (struct __go_channel *, _Bool);
97
98 #define SEND_NONBLOCKING_ACQUIRE_SPACE 0
99 #define SEND_NONBLOCKING_ACQUIRE_NOSPACE 1
100 #define SEND_NONBLOCKING_ACQUIRE_CLOSED 2
101
102 extern int __go_send_nonblocking_acquire (struct __go_channel *);
103
104 extern void __go_send_release (struct __go_channel *);
105
106 extern void __go_send_small (struct __go_channel *, uint64_t, _Bool);
107
108 extern _Bool __go_send_nonblocking_small (struct __go_channel *, uint64_t);
109
110 extern void __go_send_big (struct __go_channel *, const void *, _Bool);
111
112 extern _Bool __go_send_nonblocking_big (struct __go_channel *, const void *);
113
114 extern _Bool __go_receive_acquire (struct __go_channel *, _Bool);
115
116 #define RECEIVE_NONBLOCKING_ACQUIRE_DATA 0
117 #define RECEIVE_NONBLOCKING_ACQUIRE_NODATA 1
118 #define RECEIVE_NONBLOCKING_ACQUIRE_CLOSED 2
119
120 extern int __go_receive_nonblocking_acquire (struct __go_channel *);
121
122 extern uint64_t __go_receive_small (struct __go_channel *, _Bool);
123
124 extern void __go_receive_release (struct __go_channel *);
125
126 struct __go_receive_nonblocking_small
127 {
128   uint64_t __val;
129   _Bool __success;
130 };
131
132 extern struct __go_receive_nonblocking_small
133 __go_receive_nonblocking_small (struct __go_channel *);
134
135 extern void __go_receive_big (struct __go_channel *, void *, _Bool);
136
137 extern _Bool __go_receive_nonblocking_big (struct __go_channel *, void *);
138
139 extern void __go_unlock_and_notify_selects (struct __go_channel *);
140
141 extern _Bool __go_builtin_closed (struct __go_channel *);
142
143 extern void __go_builtin_close (struct __go_channel *);
144
145 extern size_t __go_chan_len (struct __go_channel *);
146
147 extern size_t __go_chan_cap (struct __go_channel *);