OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [runtime/] [thread-sema.c] - Blame information for rev 747

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2009 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
#include "config.h"
6
#include "runtime.h"
7
 
8
#include <errno.h>
9
#include <stdlib.h>
10
#include <time.h>
11
#include <semaphore.h>
12
 
13
/* If we don't have sem_timedwait, use pthread_cond_timedwait instead.
14
   We don't always use condition variables because on some systems
15
   pthread_mutex_lock and pthread_mutex_unlock must be called by the
16
   same thread.  That is never true of semaphores.  */
17
 
18
struct go_sem
19
{
20
  sem_t sem;
21
 
22
#ifndef HAVE_SEM_TIMEDWAIT
23
  int timedwait;
24
  pthread_mutex_t mutex;
25
  pthread_cond_t cond;
26
#endif
27
};
28
 
29
/* Create a semaphore.  */
30
 
31
uintptr
32
runtime_semacreate(void)
33
{
34
  struct go_sem *p;
35
 
36
  /* Call malloc rather than runtime_malloc.  This will allocate space
37
     on the C heap.  We can't call runtime_malloc here because it
38
     could cause a deadlock.  */
39
  p = malloc (sizeof (struct go_sem));
40
  if (sem_init (&p->sem, 0, 0) != 0)
41
    runtime_throw ("sem_init");
42
 
43
#ifndef HAVE_SEM_TIMEDWAIT
44
  if (pthread_mutex_init (&p->mutex, NULL) != 0)
45
    runtime_throw ("pthread_mutex_init");
46
  if (pthread_cond_init (&p->cond, NULL) != 0)
47
    runtime_throw ("pthread_cond_init");
48
#endif
49
 
50
  return (uintptr) p;
51
}
52
 
53
/* Acquire m->waitsema.  */
54
 
55
int32
56
runtime_semasleep (int64 ns)
57
{
58
  M *m;
59
  struct go_sem *sem;
60
  int r;
61
 
62
  m = runtime_m ();
63
  sem = (struct go_sem *) m->waitsema;
64
  if (ns >= 0)
65
    {
66
      int64 abs;
67
      struct timespec ts;
68
      int err;
69
 
70
      abs = ns + runtime_nanotime ();
71
      ts.tv_sec = abs / 1000000000LL;
72
      ts.tv_nsec = abs % 1000000000LL;
73
 
74
      err = 0;
75
 
76
#ifdef HAVE_SEM_TIMEDWAIT
77
      r = sem_timedwait (&sem->sem, &ts);
78
      if (r != 0)
79
        err = errno;
80
#else
81
      if (pthread_mutex_lock (&sem->mutex) != 0)
82
        runtime_throw ("pthread_mutex_lock");
83
 
84
      while ((r = sem_trywait (&sem->sem)) != 0)
85
        {
86
          r = pthread_cond_timedwait (&sem->cond, &sem->mutex, &ts);
87
          if (r != 0)
88
            {
89
              err = r;
90
              break;
91
            }
92
        }
93
 
94
      if (pthread_mutex_unlock (&sem->mutex) != 0)
95
        runtime_throw ("pthread_mutex_unlock");
96
#endif
97
 
98
      if (err != 0)
99
        {
100
          if (err == ETIMEDOUT || err == EAGAIN || err == EINTR)
101
            return -1;
102
          runtime_throw ("sema_timedwait");
103
        }
104
      return 0;
105
    }
106
 
107
  while (sem_wait (&sem->sem) != 0)
108
    {
109
      if (errno == EINTR)
110
        continue;
111
      runtime_throw ("sem_wait");
112
    }
113
 
114
  return 0;
115
}
116
 
117
/* Wake up mp->waitsema.  */
118
 
119
void
120
runtime_semawakeup (M *mp)
121
{
122
  struct go_sem *sem;
123
 
124
  sem = (struct go_sem *) mp->waitsema;
125
  if (sem_post (&sem->sem) != 0)
126
    runtime_throw ("sem_post");
127
 
128
#ifndef HAVE_SEM_TIMEDWAIT
129
  if (pthread_mutex_lock (&sem->mutex) != 0)
130
    runtime_throw ("pthread_mutex_lock");
131
  if (pthread_cond_broadcast (&sem->cond) != 0)
132
    runtime_throw ("pthread_cond_broadcast");
133
  if (pthread_mutex_unlock (&sem->mutex) != 0)
134
    runtime_throw ("pthread_mutex_unlock");
135
#endif
136
}
137
 
138
void
139
runtime_osinit (void)
140
{
141
}
142
 
143
void
144
runtime_goenvs (void)
145
{
146
  runtime_goenvs_unix ();
147
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.