/* go-note.c -- implement notesleep, notewakeup and noteclear. Copyright 2009 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. */ /* A note is a one-time notification. noteclear clears the note. notesleep waits for a call to notewakeup. notewakeup wakes up every thread waiting on the note. */ #include "go-assert.h" #include "runtime.h" /* We use a single global lock and condition variable. It would be better to use a futex on Linux. */ static pthread_mutex_t note_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t note_cond = PTHREAD_COND_INITIALIZER; /* noteclear is called before any calls to notesleep or notewakeup. */ void noteclear (Note* n) { int32 i; i = pthread_mutex_lock (¬e_lock); __go_assert (i == 0); n->woken = 0; i = pthread_mutex_unlock (¬e_lock); __go_assert (i == 0); } /* Wait until notewakeup is called. */ void notesleep (Note* n) { int32 i; i = pthread_mutex_lock (¬e_lock); __go_assert (i == 0); while (!n->woken) { i = pthread_cond_wait (¬e_cond, ¬e_lock); __go_assert (i == 0); } i = pthread_mutex_unlock (¬e_lock); __go_assert (i == 0); } /* Wake up every thread sleeping on the note. */ void notewakeup (Note *n) { int32 i; i = pthread_mutex_lock (¬e_lock); __go_assert (i == 0); n->woken = 1; i = pthread_cond_broadcast (¬e_cond); __go_assert (i == 0); i = pthread_mutex_unlock (¬e_lock); __go_assert (i == 0); }