Replaced the hown-grown recursive lock implementation by a shared lazy

recursive lock. I haven't investigated it closer, but the previous
implementation was even broken -- "strace /bin/true" showed two
release_sem() calls, but no acquire_sem().


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34342 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-11-29 11:17:53 +00:00
parent 8bef23107e
commit ea77094b24
+12 -28
View File
@@ -16,6 +16,7 @@
#include <signal.h> #include <signal.h>
#include <libroot_private.h> #include <libroot_private.h>
#include <locks.h>
#include <runtime_loader.h> #include <runtime_loader.h>
#include <syscalls.h> #include <syscalls.h>
@@ -24,44 +25,26 @@ extern void _IO_cleanup(void);
extern void _thread_do_exit_notification(void); extern void _thread_do_exit_notification(void);
struct exit_stack_info { struct exit_stack_info {
void (*exit_stack[ATEXIT_MAX])(void); void (*exit_stack[ATEXIT_MAX])(void);
int32 stack_size; int32 stack_size;
sem_id lock; lazy_recursive_lock lock;
vint32 lock_count;
thread_id lock_owner;
size_t recursion_count;
}; };
static struct exit_stack_info sExitStackInfo = { {}, 0, -1, 0, -1, 0 }; static struct exit_stack_info sExitStackInfo = { {}, 0, {} };
static void static void inline
_exit_stack_lock() _exit_stack_lock()
{ {
thread_id self = find_thread(NULL); lazy_recursive_lock_lock(&sExitStackInfo.lock);
if (self != sExitStackInfo.lock_owner) {
if (atomic_add(&sExitStackInfo.lock_count, 1) > 0) {
while (acquire_sem(sExitStackInfo.lock) != B_OK)
;
}
sExitStackInfo.lock_owner = self;
}
sExitStackInfo.recursion_count++;
} }
static void static void inline
_exit_stack_unlock() _exit_stack_unlock()
{ {
if (sExitStackInfo.lock_owner != find_thread(NULL)) lazy_recursive_lock_unlock(&sExitStackInfo.lock);
debugger("exit stack lock not owned");
if (sExitStackInfo.recursion_count-- == 1) {
sExitStackInfo.lock_owner = -1;
if (atomic_add(&sExitStackInfo.lock_count, -1) == 1)
release_sem(sExitStackInfo.lock);
}
} }
@@ -103,8 +86,9 @@ _call_atexit_hooks_for_range(addr_t start, addr_t size)
void void
__init_exit_stack_lock(void) __init_exit_stack_lock(void)
{ {
sExitStackInfo.lock = create_sem(0, "exit stack lock"); status_t error = lazy_recursive_lock_init(&sExitStackInfo.lock,
if (sExitStackInfo.lock < 0) "exit stack lock");
if (error != B_OK)
debugger("failed to create exit stack lock"); debugger("failed to create exit stack lock");
} }