libmetal
lib
system
linux
mutex.h
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
3
*
4
* SPDX-License-Identifier: BSD-3-Clause
5
*/
6
7
/*
8
* @file linux/mutex.h
9
* @brief Linux mutex primitives for libmetal.
10
*/
11
12
#ifndef __METAL_MUTEX__H__
13
#error "Include metal/mutex.h instead of metal/linux/mutex.h"
14
#endif
15
16
#ifndef __METAL_LINUX_MUTEX__H__
17
#define __METAL_LINUX_MUTEX__H__
18
19
#include <unistd.h>
20
#include <sys/syscall.h>
21
#include <linux/futex.h>
22
23
#include <metal/atomic.h>
24
25
#ifdef __cplusplus
26
extern
"C"
{
27
#endif
28
29
typedef
struct
{
30
atomic_int
v;
31
}
metal_mutex_t
;
32
33
/*
34
* METAL_MUTEX_INIT - used for initializing an mutex elmenet in a static struct
35
* or global
36
*/
37
#define METAL_MUTEX_INIT(m) { ATOMIC_VAR_INIT(0) }
38
/*
39
* METAL_MUTEX_DEFINE - used for defining and initializing a global or
40
* static singleton mutex
41
*/
42
#define METAL_MUTEX_DEFINE(m) metal_mutex_t m = METAL_MUTEX_INIT(m)
43
44
static
inline
int
__metal_mutex_cmpxchg
(
metal_mutex_t
*mutex,
45
int
exp,
int
val)
46
{
47
atomic_compare_exchange_strong
(&mutex->
v
, (
int
*)&exp, val);
48
return
exp;
49
}
50
51
static
inline
void
__metal_mutex_init
(
metal_mutex_t
*mutex)
52
{
53
atomic_store
(&mutex->
v
, 0);
54
}
55
56
static
inline
void
__metal_mutex_deinit
(
metal_mutex_t
*mutex)
57
{
58
(void)mutex;
59
}
60
61
static
inline
int
__metal_mutex_try_acquire
(
metal_mutex_t
*mutex)
62
{
63
int
val = 0;
64
65
return
atomic_compare_exchange_strong
(&mutex->
v
, &val, 1);
66
}
67
68
static
inline
void
__metal_mutex_acquire
(
metal_mutex_t
*mutex)
69
{
70
int
c = 0;
71
72
if
(
atomic_compare_exchange_strong
(&mutex->
v
, &c, 1))
73
return
;
74
if
(c != 2)
75
c =
atomic_exchange
(&mutex->
v
, 2);
76
while
(c != 0) {
77
syscall(SYS_futex, &mutex->
v
, FUTEX_WAIT, 2, NULL, NULL, 0);
78
c =
atomic_exchange
(&mutex->
v
, 2);
79
}
80
}
81
82
static
inline
void
__metal_mutex_release
(
metal_mutex_t
*mutex)
83
{
84
if
(
atomic_fetch_sub
(&mutex->
v
, 1) != 1) {
85
atomic_store
(&mutex->
v
, 0);
86
syscall(SYS_futex, &mutex->
v
, FUTEX_WAKE, 1, NULL, NULL, 0);
87
}
88
}
89
90
static
inline
int
__metal_mutex_is_acquired
(
metal_mutex_t
*mutex)
91
{
92
return
atomic_load
(&mutex->
v
);
93
}
94
95
#ifdef __cplusplus
96
}
97
#endif
98
99
#endif
/* __METAL_LINUX_MUTEX__H__ */
__metal_mutex_is_acquired
static int __metal_mutex_is_acquired(metal_mutex_t *mutex)
Definition:
mutex.h:90
atomic_compare_exchange_strong
#define atomic_compare_exchange_strong(OBJ, EXP, DES)
Definition:
atomic.h:79
__metal_mutex_release
static void __metal_mutex_release(metal_mutex_t *mutex)
Definition:
mutex.h:82
__metal_mutex_cmpxchg
static int __metal_mutex_cmpxchg(metal_mutex_t *mutex, int exp, int val)
Definition:
mutex.h:44
__metal_mutex_try_acquire
static int __metal_mutex_try_acquire(metal_mutex_t *mutex)
Definition:
mutex.h:61
atomic_store
#define atomic_store(OBJ, VAL)
Definition:
atomic.h:56
__metal_mutex_init
static void __metal_mutex_init(metal_mutex_t *mutex)
Definition:
mutex.h:51
__metal_mutex_acquire
static void __metal_mutex_acquire(metal_mutex_t *mutex)
Definition:
mutex.h:68
atomic_fetch_sub
#define atomic_fetch_sub(OBJ, VAL)
Definition:
atomic.h:99
__metal_mutex_deinit
static void __metal_mutex_deinit(metal_mutex_t *mutex)
Definition:
mutex.h:56
metal_mutex_t
mutex_t metal_mutex_t
Definition:
mutex.h:25
atomic_exchange
#define atomic_exchange(OBJ, DES)
Definition:
atomic.h:64
atomic_int
int atomic_int
Definition:
atomic.h:24
atomic_load
#define atomic_load(OBJ)
Definition:
atomic.h:60
metal_mutex_t::v
atomic_int v
Definition:
mutex.h:27
metal_mutex_t
Definition:
mutex.h:26
Generated on Sat Aug 1 2020 00:00:00 for libmetal by
1.8.18