Ajla 0.1.4
[ajla.git] / rwlock.c
blob1ac5a51b4554940e58ba914c5070808e022ffe2d
1 /*
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
9 * version.
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/>.
19 #include "ajla.h"
21 #include "mem_al.h"
22 #include "thread.h"
23 #include "obj_reg.h"
25 #include "rwlock.h"
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;
53 ajla_error_t sink;
54 set_tls(thread1);
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);
56 if (unlikely(!pta))
57 return thread1;
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);
65 set_tls(&pta->pt);
66 return &pta->pt;
69 void attr_fastcall rwlock_lock_write(struct rwlock_per_thread *thread1)
71 struct list *l;
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)
81 struct list *l;
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);
89 #endif