1 // Copyright 2018 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef LIB_SYNC_MUTEX_H_ 6 #define LIB_SYNC_MUTEX_H_ 7 8 #include <zircon/compiler.h> 9 #include <zircon/types.h> 10 11 __BEGIN_CDECLS 12 13 // An optimal, non-recursive mutex on Fuchsia. 14 // 15 // The |mutex_t| mutex in the standard library has several quirks in its design 16 // that prevent it from being optimal. For example, the |mutex_t| interface 17 // supports recursion, which adds a branch to |mutex_init| to check that the 18 // client has not asked for recusion, and |mutex_timedlock| operates in 19 // |struct timespec| rather than |zx_time_t|. 20 // 21 // |sync_mutex| resolves these issues. 22 typedef struct __TA_CAPABILITY("mutex") sync_mutex { 23 zx_futex_t futex; 24 25 #ifdef __cplusplus sync_mutexsync_mutex26 sync_mutex() 27 : futex(0) {} 28 #endif 29 } sync_mutex_t; 30 31 #if !defined(__cplusplus) 32 #define SYNC_MUTEX_INIT ((sync_mutex_t){0}) 33 #endif 34 35 // Locks the mutex. 36 // 37 // The current thread will block until the mutex is acquired. The mutex is 38 // non-recursive, which means attempting to lock a mutex that is already held by 39 // this thread will deadlock. 40 void sync_mutex_lock(sync_mutex_t* mutex) __TA_ACQUIRE(mutex); 41 42 // Locks the mutex and mark the mutex as having a waiter. 43 // 44 // Similar to |sync_mutex_lock| but markes the mutex as having a waiter. Intended 45 // to be used by the condition variable implementation. 46 void sync_mutex_lock_with_waiter(sync_mutex_t* mutex) __TA_ACQUIRE(mutex); 47 48 // Attempt to lock the mutex until |deadline|. 49 // 50 // The current thread will block until either the mutex is acquired or 51 // |deadline| passes. 52 // 53 // |deadline| is expressed as an absolute time in the ZX_CLOCK_MONOTONIC 54 // timebase. 55 // 56 // Returns |ZX_OK| if the lock is acquired, and |ZX_ERR_TIMED_OUT| if the 57 // deadline passes. 58 zx_status_t sync_mutex_timedlock(sync_mutex_t* mutex, zx_time_t deadline); 59 60 // Attempts to lock the mutex without blocking. 61 // 62 // Returns |ZX_OK| if the lock is obtained, and |ZX_ERR_BAD_STATE| if not. 63 zx_status_t sync_mutex_trylock(sync_mutex_t* mutex); 64 65 // Unlocks the mutex. 66 // 67 // Does nothing if the mutex is already unlocked. 68 void sync_mutex_unlock(sync_mutex_t* mutex) __TA_RELEASE(mutex); 69 70 __END_CDECLS 71 72 #endif // LIB_SYNC_MUTEX_H_ 73