libroot: Add adaptive mutex implementation
This commit is contained in:
parent
03fb2d8868
commit
7e1c4534df
@ -18,6 +18,7 @@ typedef struct mutex {
|
||||
} mutex;
|
||||
|
||||
#define MUTEX_FLAG_CLONE_NAME 0x1
|
||||
#define MUTEX_FLAG_ADAPTIVE 0x2
|
||||
#define MUTEX_INITIALIZER(name) { name, 0, 0 }
|
||||
|
||||
void mutex_init(mutex *lock, const char *name);
|
||||
|
@ -32,6 +32,7 @@ int __libc_argc;
|
||||
char **__libc_argv;
|
||||
|
||||
int __gABIVersion;
|
||||
int32 __gCPUCount;
|
||||
|
||||
char _single_threaded = true;
|
||||
// determines if I/O locking needed; needed for BeOS compatibility
|
||||
@ -48,6 +49,7 @@ int _data_offset_main_;
|
||||
void
|
||||
initialize_before(image_id imageID)
|
||||
{
|
||||
system_info info;
|
||||
char *programPath = __gRuntimeLoader->program_args->args[0];
|
||||
__gCommPageAddress = __gRuntimeLoader->commpage_address;
|
||||
__gABIVersion = __gRuntimeLoader->abi_version;
|
||||
@ -70,6 +72,9 @@ initialize_before(image_id imageID)
|
||||
|
||||
pthread_self()->id = find_thread(NULL);
|
||||
|
||||
get_system_info(&info);
|
||||
__gCPUCount = info.cpu_count;
|
||||
|
||||
__init_time((addr_t)__gCommPageAddress);
|
||||
__init_heap();
|
||||
__init_env(__gRuntimeLoader->program_args);
|
||||
|
@ -18,6 +18,12 @@
|
||||
#include <user_mutex_defs.h>
|
||||
|
||||
|
||||
#define MAX_UNSUCCESSFUL_SPINS 100
|
||||
|
||||
|
||||
extern int32 __gCPUCount;
|
||||
|
||||
|
||||
// #pragma mark - mutex
|
||||
|
||||
|
||||
@ -36,6 +42,9 @@ mutex_init_etc(mutex *lock, const char *name, uint32 flags)
|
||||
lock->name = (flags & MUTEX_FLAG_CLONE_NAME) != 0 ? strdup(name) : name;
|
||||
lock->lock = 0;
|
||||
lock->flags = flags;
|
||||
|
||||
if (__gCPUCount < 2)
|
||||
lock->flags &= ~uint32(MUTEX_FLAG_ADAPTIVE);
|
||||
}
|
||||
|
||||
|
||||
@ -50,15 +59,22 @@ mutex_destroy(mutex *lock)
|
||||
status_t
|
||||
mutex_lock(mutex *lock)
|
||||
{
|
||||
// set the locked flag
|
||||
int32 oldValue = atomic_or(&lock->lock, B_USER_MUTEX_LOCKED);
|
||||
uint32 count;
|
||||
const uint32 kMaxCount
|
||||
= (lock->flags & MUTEX_FLAG_ADAPTIVE) != 0 ? MAX_UNSUCCESSFUL_SPINS : 1;
|
||||
|
||||
if ((oldValue & (B_USER_MUTEX_LOCKED | B_USER_MUTEX_WAITING)) == 0
|
||||
|| (oldValue & B_USER_MUTEX_DISABLED) != 0) {
|
||||
// No one has the lock or is waiting for it, or the mutex has been
|
||||
// disabled.
|
||||
return B_OK;
|
||||
}
|
||||
int32 oldValue;
|
||||
do {
|
||||
// set the locked flag
|
||||
oldValue = atomic_or(&lock->lock, B_USER_MUTEX_LOCKED);
|
||||
|
||||
if ((oldValue & (B_USER_MUTEX_LOCKED | B_USER_MUTEX_WAITING)) == 0
|
||||
|| (oldValue & B_USER_MUTEX_DISABLED) != 0) {
|
||||
// No one has the lock or is waiting for it, or the mutex has been
|
||||
// disabled.
|
||||
return B_OK;
|
||||
}
|
||||
} while (count++ < kMaxCount && (oldValue & B_USER_MUTEX_WAITING) != 0);
|
||||
|
||||
// we have to call the kernel
|
||||
status_t error;
|
||||
|
@ -362,7 +362,7 @@ hoardUnsbrk(void *ptr, long size)
|
||||
void
|
||||
hoardLockInit(hoardLockType &lock, const char *name)
|
||||
{
|
||||
mutex_init(&lock, name);
|
||||
mutex_init_etc(&lock, name, MUTEX_FLAG_ADAPTIVE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,6 +24,8 @@
|
||||
struct user_space_program_args *gProgramArgs;
|
||||
void *__gCommPageAddress;
|
||||
|
||||
int32 __gCPUCount = 1;
|
||||
|
||||
|
||||
static const char *
|
||||
search_path_for_type(image_type type)
|
||||
|
Loading…
Reference in New Issue
Block a user