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/>.
27 #ifdef RWLOCK_IMPLEMENTED
29 struct rwlock_per_thread_allocated
{
30 struct rwlock_per_thread pt
;
31 struct rwlock_per_thread
*thread1
;
32 void (*set_tls
)(struct rwlock_per_thread
*);
33 tls_destructor_t destructor
;
36 static void rwlock_per_thread_destructor(tls_destructor_t
*destr
)
38 struct rwlock_per_thread_allocated
*pta
= get_struct(destr
, struct rwlock_per_thread_allocated
, destructor
);
39 struct rwlock_per_thread
*thread1
= pta
->thread1
;
40 pta
->set_tls(thread1
);
41 obj_registry_start_recursion();
42 mutex_lock(&thread1
->mutex
);
43 list_del(&pta
->pt
.entry
);
44 mutex_unlock(&thread1
->mutex
);
45 obj_registry_end_recursion();
46 mutex_done(&pta
->pt
.mutex
);
47 mem_free_aligned(pta
);
50 struct rwlock_per_thread
*rwlock_per_thread_alloc(struct rwlock_per_thread
*thread1
, void (*set_tls
)(struct rwlock_per_thread
*))
52 struct rwlock_per_thread_allocated
*pta
;
55 pta
= mem_align_mayfail(struct rwlock_per_thread_allocated
*, round_up(sizeof(struct rwlock_per_thread_allocated
), SMP_ALIAS_ALIGNMENT
), SMP_ALIAS_ALIGNMENT
, &sink
);
58 mutex_init(&pta
->pt
.mutex
);
59 pta
->thread1
= thread1
;
60 pta
->set_tls
= set_tls
;
61 mutex_lock(&thread1
->mutex
);
62 list_add(&thread1
->entry
, &pta
->pt
.entry
);
63 mutex_unlock(&thread1
->mutex
);
64 tls_destructor(&pta
->destructor
, rwlock_per_thread_destructor
);
69 void attr_fastcall
rwlock_lock_write(struct rwlock_per_thread
*thread1
)
72 mutex_lock(&thread1
->mutex
);
73 list_for_each(l
, &thread1
->entry
) {
74 struct rwlock_per_thread
*pt
= get_struct(l
, struct rwlock_per_thread
, entry
);
75 mutex_lock(&pt
->mutex
);
79 void attr_fastcall
rwlock_unlock_write(struct rwlock_per_thread
*thread1
)
82 list_for_each(l
, &thread1
->entry
) {
83 struct rwlock_per_thread
*pt
= get_struct(l
, struct rwlock_per_thread
, entry
);
84 mutex_unlock(&pt
->mutex
);
86 mutex_unlock(&thread1
->mutex
);