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:
@@ -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>
|
||||||
|
|
||||||
@@ -26,42 +27,24 @@ 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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user