blob: 9f33d994a44a3f72e2446654ad063220390b0851 [file] [log] [blame]
// Copyright 2019 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_INTERNAL_MUTEX_INTERNAL_H_
#define LIB_SYNC_INTERNAL_MUTEX_INTERNAL_H_
#include <assert.h>
#include <lib/sync/mutex.h>
#include <zircon/process.h>
#include <zircon/types.h>
// The value of LIB_SYNC_MUTEX_UNLOCKED must be 0 to match C11's mtx.h and so
// that mutexes can be allocated in BSS segments (zero-initialized data).
//
// Note that we use bit zero as the storage for our contested vs. unconstested
// state, but the sense of the bit is negative instead of positive. IOW - a
// contested mutex's state is encoded as the handle of the owning thread with
// the LSB cleared (not set).
#define LIB_SYNC_MUTEX_UNLOCKED ((zx_futex_storage_t)0)
#define CONTESTED_BIT ((zx_futex_storage_t)1)
static_assert(sizeof(zx_handle_t) <= sizeof(zx_futex_storage_t),
"mutex implementation requires futex storage to be "
"large enough to hold a zircon handle");
static_assert((CONTESTED_BIT & ZX_HANDLE_FIXED_BITS_MASK) == CONTESTED_BIT,
"mutex implementation requires that it's contested state storage "
"bit be one of the zx_handle_t's guaranteed-to-be-one bits.");
static_assert((~CONTESTED_BIT & ZX_HANDLE_FIXED_BITS_MASK) != 0,
"mutex implementation requires at least two guaranteed-to-be-one "
"bits in zx_handle_t's");
static inline zx_futex_storage_t libsync_mutex_locked_and_uncontested(void) {
return ((zx_futex_storage_t)_zx_thread_self());
}
static inline bool libsync_mutex_is_contested(zx_futex_storage_t val) {
return ((val & CONTESTED_BIT) == 0);
}
static inline zx_futex_storage_t libsync_mutex_make_contested(zx_futex_storage_t val) {
return (val & ~CONTESTED_BIT);
}
static inline zx_handle_t libsync_mutex_make_owner_from_state(zx_futex_storage_t val) {
return (val != LIB_SYNC_MUTEX_UNLOCKED) ? (zx_handle_t)(val | CONTESTED_BIT) : ZX_HANDLE_INVALID;
}
#undef CONTESTED_BIT
#endif // LIB_SYNC_INTERNAL_MUTEX_INTERNAL_H_