1 /* go-new-channel.c -- allocate a new channel.
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. */
11 #include "go-assert.h"
16 __go_new_channel (const struct __go_type_descriptor
*channel_type
,
19 const struct __go_channel_type
*ctd
;
20 const struct __go_type_descriptor
*element_type
;
21 uintptr_t element_size
;
23 struct __go_channel
* ret
;
27 __go_assert (channel_type
->__code
== GO_CHAN
);
28 ctd
= (const struct __go_channel_type
*) channel_type
;
29 element_type
= ctd
->__element_type
;
31 element_size
= element_type
->__size
;
33 ientries
= (int) entries
;
35 || (uintptr_t) ientries
!= entries
36 || (element_size
> 0 && entries
> (uintptr_t) -1 / element_size
))
37 __go_panic_msg ("chan size out of range");
39 alloc_size
= (element_size
+ sizeof (uint64_t) - 1) / sizeof (uint64_t);
41 /* We use a circular buffer which means that when next_fetch ==
42 next_store we don't know whether the buffer is empty or full. So
43 we allocate an extra space, and always leave a space open.
48 ret
= (struct __go_channel
*) __go_alloc (sizeof (struct __go_channel
)
49 + ((entries
== 0 ? 1 : entries
)
51 * sizeof (uint64_t)));
52 i
= pthread_mutex_init (&ret
->lock
, NULL
);
54 i
= pthread_cond_init (&ret
->cond
, NULL
);
56 ret
->element_type
= element_type
;
57 ret
->waiting_to_send
= 0;
58 ret
->waiting_to_receive
= 0;
59 ret
->selected_for_send
= 0;
60 ret
->selected_for_receive
= 0;
62 ret
->select_send_queue
= NULL
;
63 ret
->select_receive_queue
= NULL
;
64 ret
->select_mutex
= NULL
;
65 ret
->select_cond
= NULL
;
66 ret
->num_entries
= entries
;