summaryrefslogtreecommitdiff
path: root/src/atomic.h
blob: fc0078871ff917a7d73ae86ac8bab58588d7b46e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/* SPDX-License-Identifier: GPL-3.0-only */
#ifndef _ATOMIC_H_
#define _ATOMIC_H_

#include <stdlib.h>
#include <assert.h>
#include <pthread.h>

#include <message.h>

typedef int refcnt;

static inline void refcnt_inc(refcnt *cnt)
{
	__sync_add_and_fetch(cnt, 1);
}

static inline refcnt refcnt_dec(refcnt *cnt)
{
	return __sync_sub_and_fetch(cnt, 1);
}


/* mutex */

typedef pthread_mutex_t lock;

static inline void lock_init(lock *l)
{
	pthread_mutex_init(l, NULL);
}

static inline void lock_acquire(lock *l)
{
	int ret = pthread_mutex_lock(l);
	assert(ret == 0);
}

static inline void lock_release(lock *l)
{
	int ret = pthread_mutex_unlock(l);
	assert(ret == 0);
}

static inline void lock_release_via_cleanup(void *l)
{
	lock_release(l);
}

#define LOCK_ACQUIRE(l)						\
	lock_acquire(l);					\
	pthread_cleanup_push(lock_release_via_cleanup, l)

#define LOCK_RELEASE()				\
	pthread_cleanup_pop(1)



/* read/write lock */
typedef pthread_rwlock_t rwlock;

static inline void rwlock_init(rwlock *rw)
{
	pthread_rwlock_init(rw, NULL);
}

static inline void rwlock_read_acquire(rwlock *rw)
{
	int ret = pthread_rwlock_rdlock(rw);
	assert(ret == 0);
}

static inline void rwlock_write_acquire(rwlock *rw)
{
	int ret = pthread_rwlock_wrlock(rw);
	assert(ret == 0);
}

static inline void rwlock_release(rwlock *rw)
{
	int ret = pthread_rwlock_unlock(rw);
	assert(ret == 0);
}

static inline void rwlock_release_via_cleanup(void *rw)
{
	rwlock_release(rw);
}

#define RWLOCK_READ_ACQUIRE(rw)						\
	rwlock_read_acquire(rw);					\
	pthread_cleanup_push(rwlock_release_via_cleanup, rw)

#define RWLOCK_WRITE_ACQUIRE(rw)					\
	rwlock_write_acquire(rw);					\
	pthread_cleanup_push(rwlock_release_via_cleanup, rw)


#define RWLOCK_RELEASE()			\
	pthread_cleanup_pop(1)



#endif /* _ATOMIC_H_ */