blob: b7c020b6bfaf6a93cbd541a1aa54e85d672d9d9d [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LIB_SYNC_MUTEX_H_
#define LIB_SYNC_MUTEX_H_
#include <zircon/compiler.h>
#include <zircon/types.h>
__BEGIN_CDECLS
// An optimal, non-recursive mutex on Fuchsia.
//
// The |mutex_t| mutex in the standard library has several quirks in its design
// that prevent it from being optimal. For example, the |mutex_t| interface
// supports recursion, which adds a branch to |mutex_init| to check that the
// client has not asked for recursion, and |mutex_timedlock| operates in
// |struct timespec| rather than |zx_time_t|.
//
// |sync_mutex| resolves these issues.
typedef struct __TA_CAPABILITY("mutex") sync_mutex {
zx_futex_t futex;
#ifdef __cplusplus
sync_mutex() : futex(0) {}
#endif
} sync_mutex_t;
#if !defined(__cplusplus)
#define SYNC_MUTEX_INIT ((sync_mutex_t){0})
#endif
// Locks the mutex.
//
// The current thread will block until the mutex is acquired. The mutex is
// non-recursive, which means attempting to lock a mutex that is already held by
// this thread will deadlock.
void sync_mutex_lock(sync_mutex_t* mutex) __TA_ACQUIRE(mutex);
// Locks the mutex and mark the mutex as having a waiter.
//
// Similar to |sync_mutex_lock| but marks the mutex as having a waiter. Intended
// to be used by the condition variable implementation.
void sync_mutex_lock_with_waiter(sync_mutex_t* mutex) __TA_ACQUIRE(mutex);
// Attempt to lock the mutex until |deadline|.
//
// The current thread will block until either the mutex is acquired or
// |deadline| passes.
//
// |deadline| is expressed as an absolute time in the ZX_CLOCK_MONOTONIC
// timebase.
//
// Returns |ZX_OK| if the lock is acquired, and |ZX_ERR_TIMED_OUT| if the
// deadline passes.
zx_status_t sync_mutex_timedlock(sync_mutex_t* mutex, zx_time_t deadline);
// Attempts to lock the mutex without blocking.
//
// Returns |ZX_OK| if the lock is obtained, and |ZX_ERR_BAD_STATE| if not.
zx_status_t sync_mutex_trylock(sync_mutex_t* mutex);
// Unlocks the mutex.
//
// Does nothing if the mutex is already unlocked.
void sync_mutex_unlock(sync_mutex_t* mutex) __TA_RELEASE(mutex);
__END_CDECLS
#endif // LIB_SYNC_MUTEX_H_