1 // 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.
11 #include <semaphore.h>
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. */
22 #ifndef HAVE_SEM_TIMEDWAIT
24 pthread_mutex_t mutex
;
29 /* Create a semaphore. */
32 runtime_semacreate(void)
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");
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");
53 /* Acquire m->waitsema. */
56 runtime_semasleep (int64 ns
)
63 sem
= (struct go_sem
*) m
->waitsema
;
70 abs
= ns
+ runtime_nanotime ();
71 ts
.tv_sec
= abs
/ 1000000000LL;
72 ts
.tv_nsec
= abs
% 1000000000LL;
76 #ifdef HAVE_SEM_TIMEDWAIT
77 r
= sem_timedwait (&sem
->sem
, &ts
);
81 if (pthread_mutex_lock (&sem
->mutex
) != 0)
82 runtime_throw ("pthread_mutex_lock");
84 while ((r
= sem_trywait (&sem
->sem
)) != 0)
86 r
= pthread_cond_timedwait (&sem
->cond
, &sem
->mutex
, &ts
);
94 if (pthread_mutex_unlock (&sem
->mutex
) != 0)
95 runtime_throw ("pthread_mutex_unlock");
100 if (err
== ETIMEDOUT
|| err
== EAGAIN
|| err
== EINTR
)
102 runtime_throw ("sema_timedwait");
107 while (sem_wait (&sem
->sem
) != 0)
111 runtime_throw ("sem_wait");
117 /* Wake up mp->waitsema. */
120 runtime_semawakeup (M
*mp
)
124 sem
= (struct go_sem
*) mp
->waitsema
;
125 if (sem_post (&sem
->sem
) != 0)
126 runtime_throw ("sem_post");
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");
139 runtime_osinit (void)
141 runtime_ncpu
= getproccount();
145 runtime_goenvs (void)
147 runtime_goenvs_unix ();