OSDN Git Service

Add runtime profiling infrastructure, not yet working.
[pf3gnuchains/gcc-fork.git] / libgo / runtime / go-new-channel.c
1 /* go-new-channel.c -- allocate a new 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 <stddef.h>
8
9 #include "go-alloc.h"
10 #include "go-assert.h"
11 #include "go-panic.h"
12 #include "channel.h"
13
14 struct __go_channel*
15 __go_new_channel (size_t element_size, size_t entries)
16 {
17   struct __go_channel* ret;
18   size_t alloc_size;
19   int i;
20
21   if ((size_t) (int) entries != entries || entries > (size_t) -1 / element_size)
22     __go_panic_msg ("chan size out of range");
23
24   alloc_size = (element_size + sizeof (uint64_t) - 1) / sizeof (uint64_t);
25
26   /* We use a circular buffer which means that when next_fetch ==
27      next_store we don't know whether the buffer is empty or full.  So
28      we allocate an extra space, and always leave a space open.
29      FIXME.  */
30   if (entries != 0)
31     ++entries;
32
33   ret = (struct __go_channel*) __go_alloc (sizeof (struct __go_channel)
34                                            + ((entries == 0 ? 1 : entries)
35                                               * alloc_size
36                                               * sizeof (uint64_t)));
37   i = pthread_mutex_init (&ret->lock, NULL);
38   __go_assert (i == 0);
39   i = pthread_cond_init (&ret->cond, NULL);
40   __go_assert (i == 0);
41   ret->element_size = element_size;
42   ret->waiting_to_send = 0;
43   ret->waiting_to_receive = 0;
44   ret->selected_for_send = 0;
45   ret->selected_for_receive = 0;
46   ret->is_closed = 0;
47   ret->select_send_queue = NULL;
48   ret->select_receive_queue = NULL;
49   ret->select_mutex = NULL;
50   ret->select_cond = NULL;
51   ret->num_entries = entries;
52   ret->next_store = 0;
53   ret->next_fetch = 0;
54   return ret;
55 }