2 * Copyright (C) 2024 Mikulas Patocka
4 * This file is part of Ajla.
6 * Ajla is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software
8 * Foundation, either version 3 of the License, or (at your option) any later
11 * Ajla is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along with
16 * Ajla. If not, see <https://www.gnu.org/licenses/>.
26 #define RWLOCK_IMPLEMENTED
29 #ifndef RWLOCK_IMPLEMENTED
31 #define rwlock_decl(name) static mutex_t name
32 #define rwlock_init mutex_init
33 #define rwlock_done mutex_done
34 #define rwlock_lock_read mutex_lock
35 #define rwlock_unlock_read mutex_unlock
36 #define rwlock_lock_write mutex_lock
37 #define rwlock_unlock_write mutex_unlock
41 struct rwlock_per_thread
{
46 #define rwlock_decl(name) \
47 static tls_decl(struct rwlock_per_thread *, name##_per_thread); \
48 static void name##_set_tls(struct rwlock_per_thread *pt) \
50 tls_set(struct rwlock_per_thread *, name##_per_thread, pt); \
52 static struct rwlock_per_thread name
54 #define rwlock_init(name) \
56 mutex_init(name.mutex); \
57 list_init(name.entry); \
58 tls_init(struct rwlock_per_thread *, *name##_per_thread); \
59 /*tls_set(struct rwlock_per_thread *, *name##_per_thread, name);*/\
60 (*name##_set_tls)(name); \
63 #define rwlock_done(name) \
65 tls_done(struct rwlock_per_thread *, *name##_per_thread); \
66 ajla_assert_lo(list_is_empty(name.entry), (file_line, "rwlock list is not empty"));\
67 mutex_done(name.mutex); \
70 struct rwlock_per_thread
*rwlock_per_thread_alloc(struct rwlock_per_thread
*thread1
, void (*set_tls
)(struct rwlock_per_thread
*));
72 #define rwlock_lock_read(name) \
74 struct rwlock_per_thread *pt_ = tls_get(struct rwlock_per_thread *, *name##_per_thread);\
75 if (unlikely(!pt_)) { \
76 pt_ = rwlock_per_thread_alloc(name, name##_set_tls); \
78 mutex_lock(&pt_->mutex); \
81 #define rwlock_unlock_read(name) \
83 struct rwlock_per_thread *pt_ = tls_get(struct rwlock_per_thread *, *name##_per_thread);\
84 mutex_unlock(&pt_->mutex); \
87 void attr_fastcall
rwlock_lock_write(struct rwlock_per_thread
*thread1
);
88 void attr_fastcall
rwlock_unlock_write(struct rwlock_per_thread
*thread1
);