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