* Removed old mutex implementation and renamed cutex to mutex.
* Trivial adjustments of code using mutexes. Mostly removing the mutex_init() return value check. * Added mutex_lock_threads_locked(), which is called with the threads spinlock being held. The spinlock is released while waiting, of course. This function is useful in cases where the existence of the mutex object is ensured by holding the threads spinlock. * Changed the two instances in the VFS code where an IO context of another team needs to be locked to use mutex_lock_threads_locked(). Before it required a semaphore-based mutex implementation. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25283 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright 2008, Ingo Weinhold, [email protected].
|
||||||
* Copyright 2002-2008, Axel Dörfler, [email protected].
|
* Copyright 2002-2008, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
@@ -18,11 +19,6 @@ typedef struct recursive_lock {
|
|||||||
int recursion;
|
int recursion;
|
||||||
} recursive_lock;
|
} recursive_lock;
|
||||||
|
|
||||||
typedef struct mutex {
|
|
||||||
sem_id sem;
|
|
||||||
thread_id holder;
|
|
||||||
} mutex;
|
|
||||||
|
|
||||||
typedef struct benaphore {
|
typedef struct benaphore {
|
||||||
sem_id sem;
|
sem_id sem;
|
||||||
int32 count;
|
int32 count;
|
||||||
@@ -39,31 +35,29 @@ typedef struct rw_lock {
|
|||||||
|
|
||||||
#define RW_MAX_READERS 1000000
|
#define RW_MAX_READERS 1000000
|
||||||
|
|
||||||
struct cutex_waiter;
|
struct mutex_waiter;
|
||||||
|
|
||||||
typedef struct cutex {
|
typedef struct mutex {
|
||||||
const char* name;
|
const char* name;
|
||||||
struct cutex_waiter* waiters;
|
struct mutex_waiter* waiters;
|
||||||
#ifdef KDEBUG
|
#ifdef KDEBUG
|
||||||
thread_id holder;
|
thread_id holder;
|
||||||
#else
|
#else
|
||||||
int32 count;
|
int32 count;
|
||||||
#endif
|
#endif
|
||||||
uint8 flags;
|
uint8 flags;
|
||||||
} cutex;
|
} mutex;
|
||||||
|
|
||||||
#define CUTEX_FLAG_CLONE_NAME 0x1
|
#define MUTEX_FLAG_CLONE_NAME 0x1
|
||||||
|
|
||||||
|
|
||||||
#if 0 && KDEBUG // XXX disable this for now, it causes problems when including thread.h here
|
#if 0 && KDEBUG // XXX disable this for now, it causes problems when including thread.h here
|
||||||
# include <thread.h>
|
# include <thread.h>
|
||||||
#define ASSERT_LOCKED_RECURSIVE(r) { ASSERT(thread_get_current_thread_id() == (r)->holder); }
|
#define ASSERT_LOCKED_RECURSIVE(r) { ASSERT(thread_get_current_thread_id() == (r)->holder); }
|
||||||
#define ASSERT_LOCKED_MUTEX(m) { ASSERT(thread_get_current_thread_id() == (m)->holder); }
|
#define ASSERT_LOCKED_MUTEX(m) { ASSERT(thread_get_current_thread_id() == (m)->holder); }
|
||||||
#define ASSERT_LOCKED_CUTEX(m) { ASSERT(thread_get_current_thread_id() == (m)->holder); }
|
|
||||||
#else
|
#else
|
||||||
#define ASSERT_LOCKED_RECURSIVE(r)
|
#define ASSERT_LOCKED_RECURSIVE(r)
|
||||||
#define ASSERT_LOCKED_MUTEX(m)
|
#define ASSERT_LOCKED_MUTEX(m)
|
||||||
#define ASSERT_LOCKED_CUTEX(m)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -77,12 +71,6 @@ extern status_t recursive_lock_lock(recursive_lock *lock);
|
|||||||
extern void recursive_lock_unlock(recursive_lock *lock);
|
extern void recursive_lock_unlock(recursive_lock *lock);
|
||||||
extern int32 recursive_lock_get_recursion(recursive_lock *lock);
|
extern int32 recursive_lock_get_recursion(recursive_lock *lock);
|
||||||
|
|
||||||
extern status_t mutex_init(mutex *m, const char *name);
|
|
||||||
extern void mutex_destroy(mutex *m);
|
|
||||||
extern status_t mutex_trylock(mutex *mutex);
|
|
||||||
extern status_t mutex_lock(mutex *m);
|
|
||||||
extern void mutex_unlock(mutex *m);
|
|
||||||
|
|
||||||
extern status_t benaphore_init(benaphore *ben, const char *name);
|
extern status_t benaphore_init(benaphore *ben, const char *name);
|
||||||
extern void benaphore_destroy(benaphore *ben);
|
extern void benaphore_destroy(benaphore *ben);
|
||||||
|
|
||||||
@@ -121,35 +109,48 @@ extern status_t rw_lock_read_unlock(rw_lock *lock);
|
|||||||
extern status_t rw_lock_write_lock(rw_lock *lock);
|
extern status_t rw_lock_write_lock(rw_lock *lock);
|
||||||
extern status_t rw_lock_write_unlock(rw_lock *lock);
|
extern status_t rw_lock_write_unlock(rw_lock *lock);
|
||||||
|
|
||||||
extern void cutex_init(cutex* lock, const char *name);
|
extern void mutex_init(mutex* lock, const char *name);
|
||||||
// name is *not* cloned nor freed in cutex_destroy()
|
// name is *not* cloned nor freed in mutex_destroy()
|
||||||
extern void cutex_init_etc(cutex* lock, const char *name, uint32 flags);
|
extern void mutex_init_etc(mutex* lock, const char *name, uint32 flags);
|
||||||
extern void cutex_destroy(cutex* lock);
|
extern void mutex_destroy(mutex* lock);
|
||||||
|
|
||||||
// implementation private:
|
// implementation private:
|
||||||
extern status_t _cutex_lock(cutex* lock);
|
extern status_t _mutex_lock(mutex* lock, bool threadsLocked);
|
||||||
extern void _cutex_unlock(cutex* lock);
|
extern void _mutex_unlock(mutex* lock);
|
||||||
extern status_t _cutex_trylock(cutex* lock);
|
extern status_t _mutex_trylock(mutex* lock);
|
||||||
|
|
||||||
|
|
||||||
static inline status_t
|
static inline status_t
|
||||||
cutex_lock(cutex* lock)
|
mutex_lock(mutex* lock)
|
||||||
{
|
{
|
||||||
#ifdef KDEBUG
|
#ifdef KDEBUG
|
||||||
return _cutex_lock(lock);
|
return _mutex_lock(lock, false);
|
||||||
#else
|
#else
|
||||||
if (atomic_add(&lock->count, -1) < 0)
|
if (atomic_add(&lock->count, -1) < 0)
|
||||||
return _cutex_lock(lock);
|
return _mutex_lock(lock, false);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline status_t
|
static inline status_t
|
||||||
cutex_trylock(cutex* lock)
|
mutex_lock_threads_locked(mutex* lock)
|
||||||
{
|
{
|
||||||
#ifdef KDEBUG
|
#ifdef KDEBUG
|
||||||
return _cutex_trylock(lock);
|
return _mutex_lock(lock, true);
|
||||||
|
#else
|
||||||
|
if (atomic_add(&lock->count, -1) < 0)
|
||||||
|
return _mutex_lock(lock, true);
|
||||||
|
return B_OK;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline status_t
|
||||||
|
mutex_trylock(mutex* lock)
|
||||||
|
{
|
||||||
|
#ifdef KDEBUG
|
||||||
|
return _mutex_trylock(lock);
|
||||||
#else
|
#else
|
||||||
if (atomic_test_and_set(&lock->count, -1, 0) != 0)
|
if (atomic_test_and_set(&lock->count, -1, 0) != 0)
|
||||||
return B_WOULD_BLOCK;
|
return B_WOULD_BLOCK;
|
||||||
@@ -159,13 +160,13 @@ cutex_trylock(cutex* lock)
|
|||||||
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
cutex_unlock(cutex* lock)
|
mutex_unlock(mutex* lock)
|
||||||
{
|
{
|
||||||
#ifdef KDEBUG
|
#ifdef KDEBUG
|
||||||
_cutex_unlock(lock);
|
_mutex_unlock(lock);
|
||||||
#else
|
#else
|
||||||
if (atomic_add(&lock->count, 1) < -1)
|
if (atomic_add(&lock->count, 1) < -1)
|
||||||
_cutex_unlock(lock);
|
_mutex_unlock(lock);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ enum {
|
|||||||
THREAD_BLOCK_TYPE_CONDITION_VARIABLE = 1,
|
THREAD_BLOCK_TYPE_CONDITION_VARIABLE = 1,
|
||||||
THREAD_BLOCK_TYPE_SNOOZE = 2,
|
THREAD_BLOCK_TYPE_SNOOZE = 2,
|
||||||
THREAD_BLOCK_TYPE_SIGNAL = 3,
|
THREAD_BLOCK_TYPE_SIGNAL = 3,
|
||||||
THREAD_BLOCK_TYPE_CUTEX = 4,
|
THREAD_BLOCK_TYPE_MUTEX = 4,
|
||||||
|
|
||||||
THREAD_BLOCK_TYPE_OTHER = 9999,
|
THREAD_BLOCK_TYPE_OTHER = 9999,
|
||||||
THREAD_BLOCK_TYPE_USER_BASE = 10000
|
THREAD_BLOCK_TYPE_USER_BASE = 10000
|
||||||
|
|||||||
@@ -67,24 +67,6 @@ public:
|
|||||||
// BenaphoreLocker
|
// BenaphoreLocker
|
||||||
typedef AutoLocker<benaphore, BenaphoreLocking> BenaphoreLocker;
|
typedef AutoLocker<benaphore, BenaphoreLocking> BenaphoreLocker;
|
||||||
|
|
||||||
// CutexLocking
|
|
||||||
class CutexLocking {
|
|
||||||
public:
|
|
||||||
inline bool Lock(cutex *lockable)
|
|
||||||
{
|
|
||||||
cutex_lock(lockable);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Unlock(cutex *lockable)
|
|
||||||
{
|
|
||||||
cutex_unlock(lockable);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// CutexLocker
|
|
||||||
typedef AutoLocker<cutex, CutexLocking> CutexLocker;
|
|
||||||
|
|
||||||
// InterruptsLocking
|
// InterruptsLocking
|
||||||
class InterruptsLocking {
|
class InterruptsLocking {
|
||||||
public:
|
public:
|
||||||
@@ -171,7 +153,6 @@ using BPrivate::AutoLocker;
|
|||||||
using BPrivate::MutexLocker;
|
using BPrivate::MutexLocker;
|
||||||
using BPrivate::RecursiveLocker;
|
using BPrivate::RecursiveLocker;
|
||||||
using BPrivate::BenaphoreLocker;
|
using BPrivate::BenaphoreLocker;
|
||||||
using BPrivate::CutexLocker;
|
|
||||||
using BPrivate::InterruptsLocker;
|
using BPrivate::InterruptsLocker;
|
||||||
using BPrivate::SpinLocker;
|
using BPrivate::SpinLocker;
|
||||||
using BPrivate::InterruptsSpinLocker;
|
using BPrivate::InterruptsSpinLocker;
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ struct vm_dummy_page : vm_page {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct vm_cache {
|
struct vm_cache {
|
||||||
cutex lock;
|
mutex lock;
|
||||||
struct vm_area *areas;
|
struct vm_area *areas;
|
||||||
vint32 ref_count;
|
vint32 ref_count;
|
||||||
struct list_link consumer_link;
|
struct list_link consumer_link;
|
||||||
|
|||||||
@@ -265,8 +265,7 @@ keyboard_open(const char *name, uint32 flags, void **cookie)
|
|||||||
if (keyboard_sem < 0)
|
if (keyboard_sem < 0)
|
||||||
panic("could not create keyboard sem!\n");
|
panic("could not create keyboard sem!\n");
|
||||||
|
|
||||||
if (mutex_init(&keyboard_read_mutex, "keyboard_read_mutex") < 0)
|
mutex_init(&keyboard_read_mutex, "keyboard_read_mutex");
|
||||||
panic("could not create keyboard read mutex!\n");
|
|
||||||
|
|
||||||
shift = false;
|
shift = false;
|
||||||
sControl = false;
|
sControl = false;
|
||||||
|
|||||||
@@ -51,25 +51,16 @@ init_driver(void)
|
|||||||
|
|
||||||
memset(gDeviceNames, 0, sizeof(gDeviceNames));
|
memset(gDeviceNames, 0, sizeof(gDeviceNames));
|
||||||
|
|
||||||
// create the global mutex
|
// create the request mutex
|
||||||
status_t error = mutex_init(&gGlobalTTYLock, "tty global");
|
status_t error = recursive_lock_init(&gTTYRequestLock, "tty requests");
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
// create the cookie mutex
|
// create the global mutex
|
||||||
error = mutex_init(&gTTYCookieLock, "tty cookies");
|
mutex_init(&gGlobalTTYLock, "tty global");
|
||||||
if (error != B_OK) {
|
|
||||||
mutex_destroy(&gGlobalTTYLock);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the request mutex
|
// create the cookie mutex
|
||||||
error = recursive_lock_init(&gTTYRequestLock, "tty requests");
|
mutex_init(&gTTYCookieLock, "tty cookies");
|
||||||
if (error != B_OK) {
|
|
||||||
mutex_destroy(&gTTYCookieLock);
|
|
||||||
mutex_destroy(&gGlobalTTYLock);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// create driver name array and initialize basic TTY structures
|
// create driver name array and initialize basic TTY structures
|
||||||
|
|
||||||
|
|||||||
@@ -42,13 +42,9 @@ create_master_cookie(master_cookie *&cookie, struct tty *master,
|
|||||||
if (cookie == NULL)
|
if (cookie == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
status_t error = mutex_init(&cookie->lock, "tty lock");
|
mutex_init(&cookie->lock, "tty lock");
|
||||||
if (error != B_OK) {
|
|
||||||
free(cookie);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = init_tty_cookie(cookie, master, slave, openMode);
|
status_t error = init_tty_cookie(cookie, master, slave, openMode);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
mutex_destroy(&cookie->lock);
|
mutex_destroy(&cookie->lock);
|
||||||
free(cookie);
|
free(cookie);
|
||||||
|
|||||||
@@ -1866,7 +1866,7 @@ dump_tty_struct(struct tty& tty)
|
|||||||
kprintf(" open_count: %ld\n", tty.open_count);
|
kprintf(" open_count: %ld\n", tty.open_count);
|
||||||
kprintf(" select_pool: %p\n", tty.select_pool);
|
kprintf(" select_pool: %p\n", tty.select_pool);
|
||||||
kprintf(" pending_eof: %lu\n", tty.pending_eof);
|
kprintf(" pending_eof: %lu\n", tty.pending_eof);
|
||||||
kprintf(" lock.sem: %ld\n", tty.lock->sem);
|
kprintf(" lock: %ld\n", &tty.lock);
|
||||||
|
|
||||||
kprintf(" input_buffer:\n");
|
kprintf(" input_buffer:\n");
|
||||||
kprintf(" first: %ld\n", tty.input_buffer.first);
|
kprintf(" first: %ld\n", tty.input_buffer.first);
|
||||||
|
|||||||
@@ -386,15 +386,13 @@ init_log(void)
|
|||||||
|
|
||||||
sLogEntrySem = create_sem(kNumLogEntries, "cache log entries");
|
sLogEntrySem = create_sem(kNumLogEntries, "cache log entries");
|
||||||
if (sLogEntrySem >= B_OK) {
|
if (sLogEntrySem >= B_OK) {
|
||||||
if (mutex_init(&sLock, "log cache module") >= B_OK) {
|
mutex_init(&sLock, "log cache module");
|
||||||
register_kernel_daemon(log_writer_daemon, NULL, kLogWriterFrequency);
|
register_kernel_daemon(log_writer_daemon, NULL, kLogWriterFrequency);
|
||||||
register_generic_syscall(CACHE_LOG_SYSCALLS, log_control, 1, 0);
|
register_generic_syscall(CACHE_LOG_SYSCALLS, log_control, 1, 0);
|
||||||
|
|
||||||
TRACE(("** - log init\n"));
|
TRACE(("** - log init\n"));
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
delete_sem(sLogEntrySem);
|
|
||||||
}
|
|
||||||
|
|
||||||
close(sLogFile);
|
close(sLogFile);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|||||||
@@ -429,9 +429,6 @@ TCPEndpoint::~TCPEndpoint()
|
|||||||
status_t
|
status_t
|
||||||
TCPEndpoint::InitCheck() const
|
TCPEndpoint::InitCheck() const
|
||||||
{
|
{
|
||||||
if (fLock.sem < B_OK)
|
|
||||||
return fLock.sem;
|
|
||||||
|
|
||||||
if (fReceiveList.InitCheck() < B_OK)
|
if (fReceiveList.InitCheck() < B_OK)
|
||||||
return fReceiveList.InitCheck();
|
return fReceiveList.InitCheck();
|
||||||
|
|
||||||
@@ -2175,7 +2172,9 @@ TCPEndpoint::Dump() const
|
|||||||
kprintf("TCP endpoint %p\n", this);
|
kprintf("TCP endpoint %p\n", this);
|
||||||
kprintf(" state: %s\n", name_for_state(fState));
|
kprintf(" state: %s\n", name_for_state(fState));
|
||||||
kprintf(" flags: 0x%lx\n", fFlags);
|
kprintf(" flags: 0x%lx\n", fFlags);
|
||||||
kprintf(" lock: { sem: %ld, holder: %ld }\n", fLock.sem, fLock.holder);
|
#ifdef KDEBUG
|
||||||
|
kprintf(" lock: { %p, holder: %ld }\n", &fLock, fLock.holder);
|
||||||
|
#endif
|
||||||
kprintf(" accept sem: %ld\n", fAcceptSemaphore);
|
kprintf(" accept sem: %ld\n", fAcceptSemaphore);
|
||||||
kprintf(" options: 0x%lx\n", (uint32)fOptions);
|
kprintf(" options: 0x%lx\n", (uint32)fOptions);
|
||||||
kprintf(" send\n");
|
kprintf(" send\n");
|
||||||
|
|||||||
@@ -721,13 +721,10 @@ tcp_error_reply(net_protocol* protocol, net_buffer* causedError, uint32 code,
|
|||||||
static status_t
|
static status_t
|
||||||
tcp_init()
|
tcp_init()
|
||||||
{
|
{
|
||||||
status_t status = mutex_init(&sEndpointManagersLock,
|
mutex_init(&sEndpointManagersLock, "endpoint managers lock");
|
||||||
"endpoint managers lock");
|
|
||||||
|
|
||||||
if (status < B_OK)
|
status_t status = gStackModule->register_domain_protocols(AF_INET,
|
||||||
return status;
|
SOCK_STREAM, 0,
|
||||||
|
|
||||||
status = gStackModule->register_domain_protocols(AF_INET, SOCK_STREAM, 0,
|
|
||||||
"network/protocols/tcp/v1",
|
"network/protocols/tcp/v1",
|
||||||
"network/protocols/ipv4/v1",
|
"network/protocols/ipv4/v1",
|
||||||
NULL);
|
NULL);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include <Drivers.h>
|
#include <Drivers.h>
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
|
|
||||||
#include <lock.h>
|
#include <kernel/lock.h>
|
||||||
#include <net_stack.h>
|
#include <net_stack.h>
|
||||||
|
|
||||||
#undef ASSERT
|
#undef ASSERT
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ void
|
|||||||
mtx_init(struct mtx *m, const char *name, const char *type, int opts)
|
mtx_init(struct mtx *m, const char *name, const char *type, int opts)
|
||||||
{
|
{
|
||||||
if (opts == MTX_DEF) {
|
if (opts == MTX_DEF) {
|
||||||
if (mutex_init(&m->u.mutex, name) < B_OK)
|
mutex_init_etc(&m->u.mutex, name, MUTEX_FLAG_CLONE_NAME);
|
||||||
panic("Panic! Dance like it's 1979, we ran out of semaphores");
|
|
||||||
} else if (opts == MTX_RECURSE) {
|
} else if (opts == MTX_RECURSE) {
|
||||||
if (recursive_lock_init(&m->u.recursive, name) < B_OK)
|
if (recursive_lock_init(&m->u.recursive, name) < B_OK)
|
||||||
panic("Hell just froze as someone was trying to init a recursive mutex.");
|
panic("Hell just froze as someone was trying to init a recursive mutex.");
|
||||||
|
|||||||
@@ -45,10 +45,7 @@ _taskqueue_create(const char *name, int mflags, int fast,
|
|||||||
if (fast) {
|
if (fast) {
|
||||||
tq->tq_spinlock = 0;
|
tq->tq_spinlock = 0;
|
||||||
} else {
|
} else {
|
||||||
if (mutex_init(&tq->tq_mutex, name) < B_OK) {
|
mutex_init_etc(&tq->tq_mutex, name, MUTEX_FLAG_CLONE_NAME);
|
||||||
free(tq);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
strlcpy(tq->tq_name, name, sizeof(tq->tq_name));
|
strlcpy(tq->tq_name, name, sizeof(tq->tq_name));
|
||||||
|
|||||||
@@ -154,9 +154,7 @@ NotificationManager::~NotificationManager()
|
|||||||
status_t
|
status_t
|
||||||
NotificationManager::_Init()
|
NotificationManager::_Init()
|
||||||
{
|
{
|
||||||
status_t status = mutex_init(&fLock, "notification manager");
|
mutex_init(&fLock, "notification manager");
|
||||||
if (status < B_OK)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
return fServiceHash.InitCheck();
|
return fServiceHash.InitCheck();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -282,8 +282,7 @@ generic_vm_physical_page_mapper_init(kernel_args *args,
|
|||||||
memset(virtual_pmappings, 0, sizeof(paddr_chunk_desc *) * num_virtual_chunks);
|
memset(virtual_pmappings, 0, sizeof(paddr_chunk_desc *) * num_virtual_chunks);
|
||||||
first_free_vmapping = 0;
|
first_free_vmapping = 0;
|
||||||
queue_init(&mapped_paddr_lru);
|
queue_init(&mapped_paddr_lru);
|
||||||
sMutex.sem = -1;
|
mutex_init(&sMutex, "iospace_mutex");
|
||||||
sMutex.holder = -1;
|
|
||||||
sChunkAvailableSem = -1;
|
sChunkAvailableSem = -1;
|
||||||
|
|
||||||
TRACE(("generic_vm_physical_page_mapper_init: done\n"));
|
TRACE(("generic_vm_physical_page_mapper_init: done\n"));
|
||||||
@@ -332,7 +331,6 @@ generic_vm_physical_page_mapper_init_post_area(kernel_args *args)
|
|||||||
status_t
|
status_t
|
||||||
generic_vm_physical_page_mapper_init_post_sem(kernel_args *args)
|
generic_vm_physical_page_mapper_init_post_sem(kernel_args *args)
|
||||||
{
|
{
|
||||||
mutex_init(&sMutex, "iospace_mutex");
|
|
||||||
sChunkAvailableSem = create_sem(1, "iospace chunk available");
|
sChunkAvailableSem = create_sem(1, "iospace chunk available");
|
||||||
|
|
||||||
return sChunkAvailableSem >= B_OK ? B_OK : sChunkAvailableSem;
|
return sChunkAvailableSem >= B_OK ? B_OK : sChunkAvailableSem;
|
||||||
|
|||||||
+17
-17
@@ -119,7 +119,7 @@ reserve_pages(file_cache_ref *ref, size_t reservePages, bool isWrite)
|
|||||||
{
|
{
|
||||||
if (vm_low_memory_state() != B_NO_LOW_MEMORY) {
|
if (vm_low_memory_state() != B_NO_LOW_MEMORY) {
|
||||||
vm_cache *cache = ref->cache;
|
vm_cache *cache = ref->cache;
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
|
|
||||||
if (list_is_empty(&cache->consumers) && cache->areas == NULL
|
if (list_is_empty(&cache->consumers) && cache->areas == NULL
|
||||||
&& access_is_sequential(ref)) {
|
&& access_is_sequential(ref)) {
|
||||||
@@ -153,7 +153,7 @@ reserve_pages(file_cache_ref *ref, size_t reservePages, bool isWrite)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
vm_page_reserve_pages(reservePages);
|
vm_page_reserve_pages(reservePages);
|
||||||
@@ -208,7 +208,7 @@ read_into_cache(file_cache_ref *ref, void *cookie, off_t offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
push_access(ref, offset, bufferSize, false);
|
push_access(ref, offset, bufferSize, false);
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
vm_page_unreserve_pages(lastReservedPages);
|
vm_page_unreserve_pages(lastReservedPages);
|
||||||
|
|
||||||
// read file into reserved pages
|
// read file into reserved pages
|
||||||
@@ -229,7 +229,7 @@ read_into_cache(file_cache_ref *ref, void *cookie, off_t offset,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
|
|
||||||
for (int32 i = 0; i < pageIndex; i++) {
|
for (int32 i = 0; i < pageIndex; i++) {
|
||||||
busyConditions[i].Unpublish();
|
busyConditions[i].Unpublish();
|
||||||
@@ -263,7 +263,7 @@ read_into_cache(file_cache_ref *ref, void *cookie, off_t offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
reserve_pages(ref, reservePages, false);
|
reserve_pages(ref, reservePages, false);
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
|
|
||||||
// make the pages accessible in the cache
|
// make the pages accessible in the cache
|
||||||
for (int32 i = pageIndex; i-- > 0;) {
|
for (int32 i = pageIndex; i-- > 0;) {
|
||||||
@@ -292,7 +292,7 @@ read_from_file(file_cache_ref *ref, void *cookie, off_t offset,
|
|||||||
vec.iov_len = bufferSize;
|
vec.iov_len = bufferSize;
|
||||||
|
|
||||||
push_access(ref, offset, bufferSize, false);
|
push_access(ref, offset, bufferSize, false);
|
||||||
cutex_unlock(&ref->cache->lock);
|
mutex_unlock(&ref->cache->lock);
|
||||||
vm_page_unreserve_pages(lastReservedPages);
|
vm_page_unreserve_pages(lastReservedPages);
|
||||||
|
|
||||||
status_t status = vfs_read_pages(ref->vnode, cookie, offset + pageOffset,
|
status_t status = vfs_read_pages(ref->vnode, cookie, offset + pageOffset,
|
||||||
@@ -300,7 +300,7 @@ read_from_file(file_cache_ref *ref, void *cookie, off_t offset,
|
|||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
reserve_pages(ref, reservePages, false);
|
reserve_pages(ref, reservePages, false);
|
||||||
|
|
||||||
cutex_lock(&ref->cache->lock);
|
mutex_lock(&ref->cache->lock);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -351,7 +351,7 @@ write_to_cache(file_cache_ref *ref, void *cookie, off_t offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
push_access(ref, offset, bufferSize, true);
|
push_access(ref, offset, bufferSize, true);
|
||||||
cutex_unlock(&ref->cache->lock);
|
mutex_unlock(&ref->cache->lock);
|
||||||
vm_page_unreserve_pages(lastReservedPages);
|
vm_page_unreserve_pages(lastReservedPages);
|
||||||
|
|
||||||
// copy contents (and read in partially written pages first)
|
// copy contents (and read in partially written pages first)
|
||||||
@@ -433,7 +433,7 @@ write_to_cache(file_cache_ref *ref, void *cookie, off_t offset,
|
|||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
reserve_pages(ref, reservePages, true);
|
reserve_pages(ref, reservePages, true);
|
||||||
|
|
||||||
cutex_lock(&ref->cache->lock);
|
mutex_lock(&ref->cache->lock);
|
||||||
|
|
||||||
// unmap the pages again
|
// unmap the pages again
|
||||||
|
|
||||||
@@ -482,7 +482,7 @@ write_to_file(file_cache_ref *ref, void *cookie, off_t offset, int32 pageOffset,
|
|||||||
vec.iov_len = bufferSize;
|
vec.iov_len = bufferSize;
|
||||||
|
|
||||||
push_access(ref, offset, bufferSize, true);
|
push_access(ref, offset, bufferSize, true);
|
||||||
cutex_unlock(&ref->cache->lock);
|
mutex_unlock(&ref->cache->lock);
|
||||||
vm_page_unreserve_pages(lastReservedPages);
|
vm_page_unreserve_pages(lastReservedPages);
|
||||||
|
|
||||||
status_t status = B_OK;
|
status_t status = B_OK;
|
||||||
@@ -508,7 +508,7 @@ write_to_file(file_cache_ref *ref, void *cookie, off_t offset, int32 pageOffset,
|
|||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
reserve_pages(ref, reservePages, true);
|
reserve_pages(ref, reservePages, true);
|
||||||
|
|
||||||
cutex_lock(&ref->cache->lock);
|
mutex_lock(&ref->cache->lock);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -604,7 +604,7 @@ cache_io(void *_cacheRef, void *cookie, off_t offset, addr_t buffer,
|
|||||||
size_t reservePages = 0;
|
size_t reservePages = 0;
|
||||||
|
|
||||||
reserve_pages(ref, lastReservedPages, doWrite);
|
reserve_pages(ref, lastReservedPages, doWrite);
|
||||||
CutexLocker locker(cache->lock);
|
MutexLocker locker(cache->lock);
|
||||||
|
|
||||||
while (bytesLeft > 0) {
|
while (bytesLeft > 0) {
|
||||||
// check if this page is already in memory
|
// check if this page is already in memory
|
||||||
@@ -780,7 +780,7 @@ cache_prefetch_vnode(struct vnode *vnode, off_t offset, size_t size)
|
|||||||
off_t lastOffset = offset;
|
off_t lastOffset = offset;
|
||||||
size_t lastSize = 0;
|
size_t lastSize = 0;
|
||||||
|
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
|
|
||||||
for (; bytesLeft > 0; offset += B_PAGE_SIZE) {
|
for (; bytesLeft > 0; offset += B_PAGE_SIZE) {
|
||||||
// check if this page is already in memory
|
// check if this page is already in memory
|
||||||
@@ -792,9 +792,9 @@ cache_prefetch_vnode(struct vnode *vnode, off_t offset, size_t size)
|
|||||||
// if busy retry again later
|
// if busy retry again later
|
||||||
ConditionVariableEntry entry;
|
ConditionVariableEntry entry;
|
||||||
entry.Add(page);
|
entry.Add(page);
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
entry.Wait();
|
entry.Wait();
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
|
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
@@ -825,7 +825,7 @@ cache_prefetch_vnode(struct vnode *vnode, off_t offset, size_t size)
|
|||||||
read_into_cache(ref, lastOffset, lastLeft, NULL, 0);
|
read_into_cache(ref, lastOffset, lastLeft, NULL, 0);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -985,7 +985,7 @@ file_cache_set_size(void *_cacheRef, off_t newSize)
|
|||||||
if (ref == NULL)
|
if (ref == NULL)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
CutexLocker _(ref->cache->lock);
|
MutexLocker _(ref->cache->lock);
|
||||||
|
|
||||||
off_t offset = ref->cache->virtual_size;
|
off_t offset = ref->cache->virtual_size;
|
||||||
off_t size = newSize;
|
off_t size = newSize;
|
||||||
|
|||||||
@@ -66,9 +66,6 @@ IOScheduler::~IOScheduler()
|
|||||||
status_t
|
status_t
|
||||||
IOScheduler::InitCheck() const
|
IOScheduler::InitCheck() const
|
||||||
{
|
{
|
||||||
if (fLock.sem < B_OK)
|
|
||||||
return fLock.sem;
|
|
||||||
|
|
||||||
if (fThread < B_OK)
|
if (fThread < B_OK)
|
||||||
return fThread;
|
return fThread;
|
||||||
|
|
||||||
|
|||||||
@@ -357,9 +357,7 @@ rootfs_mount(fs_volume *volume, const char *device, uint32 flags,
|
|||||||
fs->id = volume->id;
|
fs->id = volume->id;
|
||||||
fs->next_vnode_id = 1;
|
fs->next_vnode_id = 1;
|
||||||
|
|
||||||
err = mutex_init(&fs->lock, "rootfs_mutex");
|
mutex_init(&fs->lock, "rootfs_mutex");
|
||||||
if (err < B_OK)
|
|
||||||
goto err1;
|
|
||||||
|
|
||||||
fs->vnode_list_hash = hash_init(ROOTFS_HASH_SIZE, (addr_t)&vnode->all_next - (addr_t)vnode,
|
fs->vnode_list_hash = hash_init(ROOTFS_HASH_SIZE, (addr_t)&vnode->all_next - (addr_t)vnode,
|
||||||
&rootfs_vnode_compare_func, &rootfs_vnode_hash_func);
|
&rootfs_vnode_compare_func, &rootfs_vnode_hash_func);
|
||||||
@@ -388,7 +386,6 @@ err3:
|
|||||||
hash_uninit(fs->vnode_list_hash);
|
hash_uninit(fs->vnode_list_hash);
|
||||||
err2:
|
err2:
|
||||||
mutex_destroy(&fs->lock);
|
mutex_destroy(&fs->lock);
|
||||||
err1:
|
|
||||||
free(fs);
|
free(fs);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
@@ -1514,12 +1514,12 @@ disconnect_mount_or_vnode_fds(struct fs_mount *mount,
|
|||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
struct io_context *context = NULL;
|
struct io_context *context = NULL;
|
||||||
sem_id contextMutex = -1;
|
bool contextLocked = false;
|
||||||
struct team *team = NULL;
|
struct team *team = NULL;
|
||||||
team_id lastTeamID;
|
team_id lastTeamID;
|
||||||
|
|
||||||
cpu_status state = disable_interrupts();
|
cpu_status state = disable_interrupts();
|
||||||
GRAB_TEAM_LOCK();
|
SpinLocker teamsLock(team_spinlock);
|
||||||
|
|
||||||
lastTeamID = peek_next_thread_id();
|
lastTeamID = peek_next_thread_id();
|
||||||
if (nextTeamID < lastTeamID) {
|
if (nextTeamID < lastTeamID) {
|
||||||
@@ -1531,12 +1531,20 @@ disconnect_mount_or_vnode_fds(struct fs_mount *mount,
|
|||||||
|
|
||||||
if (team) {
|
if (team) {
|
||||||
context = (io_context *)team->io_context;
|
context = (io_context *)team->io_context;
|
||||||
contextMutex = context->io_mutex.sem;
|
|
||||||
|
// Some acrobatics to lock the context in a safe way
|
||||||
|
// (cf. _kern_get_next_fd_info() for details).
|
||||||
|
GRAB_THREAD_LOCK();
|
||||||
|
teamsLock.Unlock();
|
||||||
|
contextLocked = mutex_lock_threads_locked(&context->io_mutex)
|
||||||
|
== B_OK;
|
||||||
|
RELEASE_THREAD_LOCK();
|
||||||
|
|
||||||
nextTeamID++;
|
nextTeamID++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RELEASE_TEAM_LOCK();
|
teamsLock.Unlock();
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
|
|
||||||
if (context == NULL)
|
if (context == NULL)
|
||||||
@@ -1546,7 +1554,7 @@ disconnect_mount_or_vnode_fds(struct fs_mount *mount,
|
|||||||
// safe access to the team structure, we now need to lock the mutex
|
// safe access to the team structure, we now need to lock the mutex
|
||||||
// manually
|
// manually
|
||||||
|
|
||||||
if (acquire_sem(contextMutex) != B_OK) {
|
if (!contextLocked) {
|
||||||
// team seems to be gone, go over to the next team
|
// team seems to be gone, go over to the next team
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1554,8 +1562,6 @@ disconnect_mount_or_vnode_fds(struct fs_mount *mount,
|
|||||||
// the team cannot be deleted completely while we're owning its
|
// the team cannot be deleted completely while we're owning its
|
||||||
// io_context mutex, so we can safely play with it now
|
// io_context mutex, so we can safely play with it now
|
||||||
|
|
||||||
context->io_mutex.holder = thread_get_current_thread_id();
|
|
||||||
|
|
||||||
replace_vnode_if_disconnected(mount, vnodeToDisconnect, context->root,
|
replace_vnode_if_disconnected(mount, vnodeToDisconnect, context->root,
|
||||||
sRoot, true);
|
sRoot, true);
|
||||||
replace_vnode_if_disconnected(mount, vnodeToDisconnect, context->cwd,
|
replace_vnode_if_disconnected(mount, vnodeToDisconnect, context->cwd,
|
||||||
@@ -4141,11 +4147,7 @@ vfs_new_io_context(void *_parentContext)
|
|||||||
+ sizeof(struct select_sync*) * tableSize
|
+ sizeof(struct select_sync*) * tableSize
|
||||||
+ (tableSize + 7) / 8);
|
+ (tableSize + 7) / 8);
|
||||||
|
|
||||||
if (mutex_init(&context->io_mutex, "I/O context") < 0) {
|
mutex_init(&context->io_mutex, "I/O context");
|
||||||
free(context->fds);
|
|
||||||
free(context);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy all parent file descriptors
|
// Copy all parent file descriptors
|
||||||
|
|
||||||
@@ -4403,20 +4405,14 @@ vfs_init(kernel_args *args)
|
|||||||
|
|
||||||
sRoot = NULL;
|
sRoot = NULL;
|
||||||
|
|
||||||
if (mutex_init(&sFileSystemsMutex, "vfs_lock") < 0)
|
mutex_init(&sFileSystemsMutex, "vfs_lock");
|
||||||
panic("vfs_init: error allocating file systems lock\n");
|
|
||||||
|
|
||||||
if (recursive_lock_init(&sMountOpLock, "vfs_mount_op_lock") < 0)
|
if (recursive_lock_init(&sMountOpLock, "vfs_mount_op_lock") < 0)
|
||||||
panic("vfs_init: error allocating mount op lock\n");
|
panic("vfs_init: error allocating mount op lock\n");
|
||||||
|
|
||||||
if (mutex_init(&sMountMutex, "vfs_mount_lock") < 0)
|
mutex_init(&sMountMutex, "vfs_mount_lock");
|
||||||
panic("vfs_init: error allocating mount lock\n");
|
mutex_init(&sVnodeCoveredByMutex, "vfs_vnode_covered_by_lock");
|
||||||
|
mutex_init(&sVnodeMutex, "vfs_vnode_lock");
|
||||||
if (mutex_init(&sVnodeCoveredByMutex, "vfs_vnode_covered_by_lock") < 0)
|
|
||||||
panic("vfs_init: error allocating vnode::covered_by lock\n");
|
|
||||||
|
|
||||||
if (mutex_init(&sVnodeMutex, "vfs_vnode_lock") < 0)
|
|
||||||
panic("vfs_init: error allocating vnode lock\n");
|
|
||||||
|
|
||||||
if (benaphore_init(&sIOContextRootLock, "io_context::root lock") < 0)
|
if (benaphore_init(&sIOContextRootLock, "io_context::root lock") < 0)
|
||||||
panic("vfs_init: error allocating io_context::root lock\n");
|
panic("vfs_init: error allocating io_context::root lock\n");
|
||||||
@@ -7000,26 +6996,31 @@ _kern_get_next_fd_info(team_id teamID, uint32 *_cookie, fd_info *info,
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
struct io_context *context = NULL;
|
struct io_context *context = NULL;
|
||||||
sem_id contextMutex = -1;
|
|
||||||
struct team *team = NULL;
|
struct team *team = NULL;
|
||||||
|
|
||||||
cpu_status state = disable_interrupts();
|
cpu_status state = disable_interrupts();
|
||||||
GRAB_TEAM_LOCK();
|
GRAB_TEAM_LOCK();
|
||||||
|
|
||||||
|
bool contextLocked = false;
|
||||||
team = team_get_team_struct_locked(teamID);
|
team = team_get_team_struct_locked(teamID);
|
||||||
if (team) {
|
if (team) {
|
||||||
|
// We cannot lock the IO context while holding the team lock, nor can
|
||||||
|
// we just drop the team lock, since it might be deleted in the
|
||||||
|
// meantime. team_remove_team() acquires the thread lock when removing
|
||||||
|
// the team from the team hash table, though. Hence we switch to the
|
||||||
|
// thread lock and use mutex_lock_threads_locked().
|
||||||
context = (io_context *)team->io_context;
|
context = (io_context *)team->io_context;
|
||||||
contextMutex = context->io_mutex.sem;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
GRAB_THREAD_LOCK();
|
||||||
RELEASE_TEAM_LOCK();
|
RELEASE_TEAM_LOCK();
|
||||||
|
contextLocked = mutex_lock_threads_locked(&context->io_mutex) == B_OK;
|
||||||
|
RELEASE_THREAD_LOCK();
|
||||||
|
} else
|
||||||
|
RELEASE_TEAM_LOCK();
|
||||||
|
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
|
|
||||||
// we now have a context - since we couldn't lock it while having
|
if (!contextLocked) {
|
||||||
// safe access to the team structure, we now need to lock the mutex
|
|
||||||
// manually
|
|
||||||
|
|
||||||
if (context == NULL || acquire_sem(contextMutex) != B_OK) {
|
|
||||||
// team doesn't exit or seems to be gone
|
// team doesn't exit or seems to be gone
|
||||||
return B_BAD_TEAM_ID;
|
return B_BAD_TEAM_ID;
|
||||||
}
|
}
|
||||||
@@ -7027,8 +7028,6 @@ _kern_get_next_fd_info(team_id teamID, uint32 *_cookie, fd_info *info,
|
|||||||
// the team cannot be deleted completely while we're owning its
|
// the team cannot be deleted completely while we're owning its
|
||||||
// io_context mutex, so we can safely play with it now
|
// io_context mutex, so we can safely play with it now
|
||||||
|
|
||||||
context->io_mutex.holder = thread_get_current_thread_id();
|
|
||||||
|
|
||||||
uint32 slot = *_cookie;
|
uint32 slot = *_cookie;
|
||||||
|
|
||||||
struct file_descriptor *descriptor;
|
struct file_descriptor *descriptor;
|
||||||
|
|||||||
@@ -469,8 +469,8 @@ heap_validate_heap(heap_allocator *heap)
|
|||||||
// #pragma mark - Heap functions
|
// #pragma mark - Heap functions
|
||||||
|
|
||||||
|
|
||||||
heap_allocator *
|
static heap_allocator *
|
||||||
heap_attach(addr_t base, size_t size, bool postSem)
|
heap_attach(addr_t base, size_t size)
|
||||||
{
|
{
|
||||||
heap_allocator *heap = (heap_allocator *)base;
|
heap_allocator *heap = (heap_allocator *)base;
|
||||||
base += sizeof(heap_allocator);
|
base += sizeof(heap_allocator);
|
||||||
@@ -517,16 +517,7 @@ heap_attach(addr_t base, size_t size, bool postSem)
|
|||||||
heap->free_pages = &heap->page_table[0];
|
heap->free_pages = &heap->page_table[0];
|
||||||
heap->page_table[0].prev = NULL;
|
heap->page_table[0].prev = NULL;
|
||||||
|
|
||||||
if (postSem) {
|
mutex_init(&heap->lock, "heap_mutex");
|
||||||
if (mutex_init(&heap->lock, "heap_mutex") < 0) {
|
|
||||||
panic("heap_attach(): error creating heap mutex\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// pre-init the mutex to at least fall through any semaphore calls
|
|
||||||
heap->lock.sem = -1;
|
|
||||||
heap->lock.holder = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
heap->next = NULL;
|
heap->next = NULL;
|
||||||
dprintf("heap_attach: attached to %p - usable range 0x%08lx - 0x%08lx\n",
|
dprintf("heap_attach: attached to %p - usable range 0x%08lx - 0x%08lx\n",
|
||||||
@@ -1014,7 +1005,7 @@ heap_grow_thread(void *)
|
|||||||
}
|
}
|
||||||
|
|
||||||
heap_allocator *newHeap = heap_attach((addr_t)heapAddress,
|
heap_allocator *newHeap = heap_attach((addr_t)heapAddress,
|
||||||
HEAP_GROW_SIZE, true);
|
HEAP_GROW_SIZE);
|
||||||
if (newHeap == NULL) {
|
if (newHeap == NULL) {
|
||||||
panic("heap_grower: could not attach additional heap!\n");
|
panic("heap_grower: could not attach additional heap!\n");
|
||||||
delete_area(heapArea);
|
delete_area(heapArea);
|
||||||
@@ -1038,7 +1029,7 @@ heap_grow_thread(void *)
|
|||||||
status_t
|
status_t
|
||||||
heap_init(addr_t base, size_t size)
|
heap_init(addr_t base, size_t size)
|
||||||
{
|
{
|
||||||
sHeapList = heap_attach(base, size, false);
|
sHeapList = heap_attach(base, size);
|
||||||
|
|
||||||
// set up some debug commands
|
// set up some debug commands
|
||||||
add_debugger_command_etc("heap", &dump_heap_list,
|
add_debugger_command_etc("heap", &dump_heap_list,
|
||||||
@@ -1063,12 +1054,6 @@ heap_init(addr_t base, size_t size)
|
|||||||
status_t
|
status_t
|
||||||
heap_init_post_sem()
|
heap_init_post_sem()
|
||||||
{
|
{
|
||||||
// create the lock for the initial heap
|
|
||||||
if (mutex_init(&sHeapList->lock, "heap_mutex") < B_OK) {
|
|
||||||
panic("heap_init_post_sem(): error creating heap mutex\n");
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
sHeapGrowSem = create_sem(0, "heap_grow_sem");
|
sHeapGrowSem = create_sem(0, "heap_grow_sem");
|
||||||
if (sHeapGrowSem < 0) {
|
if (sHeapGrowSem < 0) {
|
||||||
panic("heap_init_post_sem(): failed to create heap grow sem\n");
|
panic("heap_init_post_sem(): failed to create heap grow sem\n");
|
||||||
@@ -1097,7 +1082,7 @@ heap_init_post_thread()
|
|||||||
return area;
|
return area;
|
||||||
}
|
}
|
||||||
|
|
||||||
sGrowHeap = heap_attach((addr_t)dedicated, HEAP_DEDICATED_GROW_SIZE, true);
|
sGrowHeap = heap_attach((addr_t)dedicated, HEAP_DEDICATED_GROW_SIZE);
|
||||||
if (sGrowHeap == NULL) {
|
if (sGrowHeap == NULL) {
|
||||||
panic("heap_init_post_thread(): failed to attach dedicated grow heap\n");
|
panic("heap_init_post_thread(): failed to attach dedicated grow heap\n");
|
||||||
delete_area(area);
|
delete_area(area);
|
||||||
|
|||||||
@@ -274,7 +274,8 @@ image_init(void)
|
|||||||
add_debugger_command("team_images", &dump_images_list, "Dump all registered images from the current team");
|
add_debugger_command("team_images", &dump_images_list, "Dump all registered images from the current team");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return mutex_init(&sImageMutex, "image");
|
mutex_init(&sImageMutex, "image");
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -127,8 +127,7 @@ kernel_daemon_init(void)
|
|||||||
{
|
{
|
||||||
thread_id thread;
|
thread_id thread;
|
||||||
|
|
||||||
if (mutex_init(&sDaemonMutex, "kernel daemon") < B_OK)
|
mutex_init(&sDaemonMutex, "kernel daemon");
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
list_init(&sDaemons);
|
list_init(&sDaemons);
|
||||||
|
|
||||||
|
|||||||
+38
-139
@@ -23,14 +23,14 @@
|
|||||||
#include <util/AutoLock.h>
|
#include <util/AutoLock.h>
|
||||||
|
|
||||||
|
|
||||||
struct cutex_waiter {
|
struct mutex_waiter {
|
||||||
struct thread* thread;
|
struct thread* thread;
|
||||||
cutex_waiter* next; // next in queue
|
mutex_waiter* next; // next in queue
|
||||||
cutex_waiter* last; // last in queue (valid for the first in queue)
|
mutex_waiter* last; // last in queue (valid for the first in queue)
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CUTEX_FLAG_OWNS_NAME CUTEX_FLAG_CLONE_NAME
|
#define MUTEX_FLAG_OWNS_NAME MUTEX_FLAG_CLONE_NAME
|
||||||
#define CUTEX_FLAG_RELEASED 0x2
|
#define MUTEX_FLAG_RELEASED 0x2
|
||||||
|
|
||||||
|
|
||||||
int32
|
int32
|
||||||
@@ -110,106 +110,6 @@ recursive_lock_unlock(recursive_lock *lock)
|
|||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
mutex_init(mutex *m, const char *name)
|
|
||||||
{
|
|
||||||
if (m == NULL)
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
if (name == NULL)
|
|
||||||
name = "mutex_sem";
|
|
||||||
|
|
||||||
m->holder = -1;
|
|
||||||
|
|
||||||
m->sem = create_sem(1, name);
|
|
||||||
if (m->sem >= B_OK)
|
|
||||||
return B_OK;
|
|
||||||
|
|
||||||
return m->sem;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
mutex_destroy(mutex *mutex)
|
|
||||||
{
|
|
||||||
if (mutex == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (mutex->sem >= 0) {
|
|
||||||
delete_sem(mutex->sem);
|
|
||||||
mutex->sem = -1;
|
|
||||||
}
|
|
||||||
mutex->holder = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
mutex_trylock(mutex *mutex)
|
|
||||||
{
|
|
||||||
thread_id me = thread_get_current_thread_id();
|
|
||||||
status_t status;
|
|
||||||
|
|
||||||
if (kernel_startup)
|
|
||||||
return B_OK;
|
|
||||||
|
|
||||||
status = acquire_sem_etc(mutex->sem, 1, B_RELATIVE_TIMEOUT, 0);
|
|
||||||
if (status < B_OK)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
if (me == mutex->holder) {
|
|
||||||
panic("mutex_trylock failure: mutex %p (sem = 0x%lx) acquired twice by"
|
|
||||||
" thread 0x%lx\n", mutex, mutex->sem, me);
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex->holder = me;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
mutex_lock(mutex *mutex)
|
|
||||||
{
|
|
||||||
thread_id me = thread_get_current_thread_id();
|
|
||||||
status_t status;
|
|
||||||
|
|
||||||
if (kernel_startup)
|
|
||||||
return B_OK;
|
|
||||||
|
|
||||||
status = acquire_sem(mutex->sem);
|
|
||||||
if (status < B_OK)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
if (me == mutex->holder) {
|
|
||||||
panic("mutex_lock failure: mutex %p (sem = 0x%lx) acquired twice by"
|
|
||||||
" thread 0x%lx\n", mutex, mutex->sem, me);
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex->holder = me;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
mutex_unlock(mutex *mutex)
|
|
||||||
{
|
|
||||||
thread_id me = thread_get_current_thread_id();
|
|
||||||
|
|
||||||
if (kernel_startup)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (me != mutex->holder) {
|
|
||||||
panic("mutex_unlock failure: thread 0x%lx is trying to release mutex %p"
|
|
||||||
" (current holder 0x%lx)\n", me, mutex, mutex->holder);
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex->holder = -1;
|
|
||||||
release_sem_etc(mutex->sem, 1, 0/*B_DO_NOT_RESCHEDULE*/);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
benaphore_init(benaphore *ben, const char *name)
|
benaphore_init(benaphore *ben, const char *name)
|
||||||
{
|
{
|
||||||
@@ -299,7 +199,7 @@ rw_lock_write_unlock(rw_lock *lock)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
cutex_init(cutex* lock, const char *name)
|
mutex_init(mutex* lock, const char *name)
|
||||||
{
|
{
|
||||||
lock->name = name;
|
lock->name = name;
|
||||||
lock->waiters = NULL;
|
lock->waiters = NULL;
|
||||||
@@ -313,23 +213,23 @@ cutex_init(cutex* lock, const char *name)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
cutex_init_etc(cutex* lock, const char *name, uint32 flags)
|
mutex_init_etc(mutex* lock, const char *name, uint32 flags)
|
||||||
{
|
{
|
||||||
lock->name = (flags & CUTEX_FLAG_CLONE_NAME) != 0 ? strdup(name) : name;
|
lock->name = (flags & MUTEX_FLAG_CLONE_NAME) != 0 ? strdup(name) : name;
|
||||||
lock->waiters = NULL;
|
lock->waiters = NULL;
|
||||||
#ifdef KDEBUG
|
#ifdef KDEBUG
|
||||||
lock->holder = -1;
|
lock->holder = -1;
|
||||||
#else
|
#else
|
||||||
lock->count = 0;
|
lock->count = 0;
|
||||||
#endif
|
#endif
|
||||||
lock->flags = flags & CUTEX_FLAG_CLONE_NAME;
|
lock->flags = flags & MUTEX_FLAG_CLONE_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
cutex_destroy(cutex* lock)
|
mutex_destroy(mutex* lock)
|
||||||
{
|
{
|
||||||
char* name = (lock->flags & CUTEX_FLAG_CLONE_NAME) != 0
|
char* name = (lock->flags & MUTEX_FLAG_CLONE_NAME) != 0
|
||||||
? (char*)lock->name : NULL;
|
? (char*)lock->name : NULL;
|
||||||
|
|
||||||
// unblock all waiters
|
// unblock all waiters
|
||||||
@@ -338,16 +238,14 @@ cutex_destroy(cutex* lock)
|
|||||||
#ifdef KDEBUG
|
#ifdef KDEBUG
|
||||||
if (lock->waiters != NULL && thread_get_current_thread_id()
|
if (lock->waiters != NULL && thread_get_current_thread_id()
|
||||||
!= lock->holder) {
|
!= lock->holder) {
|
||||||
panic("cutex_destroy(): there are blocking threads, but caller doesn't "
|
panic("mutex_destroy(): there are blocking threads, but caller doesn't "
|
||||||
"hold the lock (%p)", lock);
|
"hold the lock (%p)", lock);
|
||||||
locker.Unlock();
|
if (_mutex_lock(lock, true) != B_OK)
|
||||||
if (_cutex_lock(lock) != B_OK)
|
|
||||||
return;
|
return;
|
||||||
locker.Lock();
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while (cutex_waiter* waiter = lock->waiters) {
|
while (mutex_waiter* waiter = lock->waiters) {
|
||||||
// dequeue
|
// dequeue
|
||||||
lock->waiters = waiter->next;
|
lock->waiters = waiter->next;
|
||||||
|
|
||||||
@@ -364,16 +262,17 @@ cutex_destroy(cutex* lock)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_cutex_lock(cutex* lock)
|
_mutex_lock(mutex* lock, bool threadsLocked)
|
||||||
{
|
{
|
||||||
#ifdef KDEBUG
|
#ifdef KDEBUG
|
||||||
if (!kernel_startup && !are_interrupts_enabled()) {
|
if (!kernel_startup && !threadsLocked && !are_interrupts_enabled()) {
|
||||||
panic("_cutex_unlock(): called with interrupts disabled for lock %p",
|
panic("_mutex_unlock(): called with interrupts disabled for lock %p",
|
||||||
lock);
|
lock);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
InterruptsSpinLocker _(thread_spinlock);
|
// lock only, if !threadsLocked
|
||||||
|
InterruptsSpinLocker locker(thread_spinlock, false, !threadsLocked);
|
||||||
|
|
||||||
// Might have been released after we decremented the count, but before
|
// Might have been released after we decremented the count, but before
|
||||||
// we acquired the spinlock.
|
// we acquired the spinlock.
|
||||||
@@ -383,14 +282,14 @@ _cutex_lock(cutex* lock)
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if ((lock->flags & CUTEX_FLAG_RELEASED) != 0) {
|
if ((lock->flags & MUTEX_FLAG_RELEASED) != 0) {
|
||||||
lock->flags &= ~CUTEX_FLAG_RELEASED;
|
lock->flags &= ~MUTEX_FLAG_RELEASED;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// enqueue in waiter list
|
// enqueue in waiter list
|
||||||
cutex_waiter waiter;
|
mutex_waiter waiter;
|
||||||
waiter.thread = thread_get_current_thread();
|
waiter.thread = thread_get_current_thread();
|
||||||
waiter.next = NULL;
|
waiter.next = NULL;
|
||||||
|
|
||||||
@@ -402,7 +301,7 @@ _cutex_lock(cutex* lock)
|
|||||||
lock->waiters->last = &waiter;
|
lock->waiters->last = &waiter;
|
||||||
|
|
||||||
// block
|
// block
|
||||||
thread_prepare_to_block(waiter.thread, 0, THREAD_BLOCK_TYPE_CUTEX, lock);
|
thread_prepare_to_block(waiter.thread, 0, THREAD_BLOCK_TYPE_MUTEX, lock);
|
||||||
status_t error = thread_block_locked(waiter.thread);
|
status_t error = thread_block_locked(waiter.thread);
|
||||||
|
|
||||||
#ifdef KDEBUG
|
#ifdef KDEBUG
|
||||||
@@ -415,20 +314,20 @@ _cutex_lock(cutex* lock)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_cutex_unlock(cutex* lock)
|
_mutex_unlock(mutex* lock)
|
||||||
{
|
{
|
||||||
InterruptsSpinLocker _(thread_spinlock);
|
InterruptsSpinLocker _(thread_spinlock);
|
||||||
|
|
||||||
#ifdef KDEBUG
|
#ifdef KDEBUG
|
||||||
if (thread_get_current_thread_id() != lock->holder) {
|
if (thread_get_current_thread_id() != lock->holder) {
|
||||||
panic("_cutex_unlock() failure: thread %ld is trying to release "
|
panic("_mutex_unlock() failure: thread %ld is trying to release "
|
||||||
"cutex %p (current holder %ld)\n", thread_get_current_thread_id(),
|
"mutex %p (current holder %ld)\n", thread_get_current_thread_id(),
|
||||||
lock, lock->holder);
|
lock, lock->holder);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cutex_waiter* waiter = lock->waiters;
|
mutex_waiter* waiter = lock->waiters;
|
||||||
if (waiter != NULL) {
|
if (waiter != NULL) {
|
||||||
// dequeue the first waiter
|
// dequeue the first waiter
|
||||||
lock->waiters = waiter->next;
|
lock->waiters = waiter->next;
|
||||||
@@ -451,14 +350,14 @@ _cutex_unlock(cutex* lock)
|
|||||||
#ifdef KDEBUG
|
#ifdef KDEBUG
|
||||||
lock->holder = -1;
|
lock->holder = -1;
|
||||||
#else
|
#else
|
||||||
lock->flags |= CUTEX_FLAG_RELEASED;
|
lock->flags |= MUTEX_FLAG_RELEASED;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
_cutex_trylock(cutex* lock)
|
_mutex_trylock(mutex* lock)
|
||||||
{
|
{
|
||||||
#ifdef KDEBUG
|
#ifdef KDEBUG
|
||||||
InterruptsSpinLocker _(thread_spinlock);
|
InterruptsSpinLocker _(thread_spinlock);
|
||||||
@@ -473,21 +372,21 @@ _cutex_trylock(cutex* lock)
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dump_cutex_info(int argc, char** argv)
|
dump_mutex_info(int argc, char** argv)
|
||||||
{
|
{
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
print_debugger_command_usage(argv[0]);
|
print_debugger_command_usage(argv[0]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cutex* lock = (cutex*)strtoul(argv[1], NULL, 0);
|
mutex* lock = (mutex*)strtoul(argv[1], NULL, 0);
|
||||||
|
|
||||||
if (!IS_KERNEL_ADDRESS(lock)) {
|
if (!IS_KERNEL_ADDRESS(lock)) {
|
||||||
kprintf("invalid address: %p\n", lock);
|
kprintf("invalid address: %p\n", lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
kprintf("cutex %p:\n", lock);
|
kprintf("mutex %p:\n", lock);
|
||||||
kprintf(" name: %s\n", lock->name);
|
kprintf(" name: %s\n", lock->name);
|
||||||
kprintf(" flags: 0x%x\n", lock->flags);
|
kprintf(" flags: 0x%x\n", lock->flags);
|
||||||
#ifdef KDEBUG
|
#ifdef KDEBUG
|
||||||
@@ -497,7 +396,7 @@ dump_cutex_info(int argc, char** argv)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
kprintf(" waiting threads:");
|
kprintf(" waiting threads:");
|
||||||
cutex_waiter* waiter = lock->waiters;
|
mutex_waiter* waiter = lock->waiters;
|
||||||
while (waiter != NULL) {
|
while (waiter != NULL) {
|
||||||
kprintf(" %ld", waiter->thread->id);
|
kprintf(" %ld", waiter->thread->id);
|
||||||
waiter = waiter->next;
|
waiter = waiter->next;
|
||||||
@@ -514,9 +413,9 @@ dump_cutex_info(int argc, char** argv)
|
|||||||
void
|
void
|
||||||
lock_debug_init()
|
lock_debug_init()
|
||||||
{
|
{
|
||||||
add_debugger_command_etc("cutex", &dump_cutex_info,
|
add_debugger_command_etc("mutex", &dump_mutex_info,
|
||||||
"Dump info about a cutex",
|
"Dump info about a mutex",
|
||||||
"<cutex>\n"
|
"<mutex>\n"
|
||||||
"Prints info about the specified cutex.\n"
|
"Prints info about the specified mutex.\n"
|
||||||
" <cutex> - pointer to the cutex to print the info for.\n", 0);
|
" <mutex> - pointer to the mutex to print the info for.\n", 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -211,10 +211,7 @@ status_t
|
|||||||
generic_syscall_init(void)
|
generic_syscall_init(void)
|
||||||
{
|
{
|
||||||
list_init(&sGenericSyscalls);
|
list_init(&sGenericSyscalls);
|
||||||
if (mutex_init(&sGenericSyscallLock, "generic syscall") != B_OK) {
|
mutex_init(&sGenericSyscallLock, "generic syscall");
|
||||||
panic("generic_syscall_init(): mutex init failed");
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if SYSCALL_TRACING
|
#if SYSCALL_TRACING
|
||||||
add_debugger_command_etc("straced", &dump_syscall_tracing,
|
add_debugger_command_etc("straced", &dump_syscall_tracing,
|
||||||
|
|||||||
@@ -1145,8 +1145,8 @@ _dump_thread_info(struct thread *thread)
|
|||||||
kprintf("signal\n");
|
kprintf("signal\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case THREAD_BLOCK_TYPE_CUTEX:
|
case THREAD_BLOCK_TYPE_MUTEX:
|
||||||
kprintf("cutex %p\n", thread->wait.object);
|
kprintf("mutex %p\n", thread->wait.object);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case THREAD_BLOCK_TYPE_OTHER:
|
case THREAD_BLOCK_TYPE_OTHER:
|
||||||
@@ -1320,8 +1320,8 @@ dump_thread_list(int argc, char **argv)
|
|||||||
kprintf("signal ");
|
kprintf("signal ");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case THREAD_BLOCK_TYPE_CUTEX:
|
case THREAD_BLOCK_TYPE_MUTEX:
|
||||||
kprintf("cutex %p ", thread->wait.object);
|
kprintf("mutex %p ", thread->wait.object);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case THREAD_BLOCK_TYPE_OTHER:
|
case THREAD_BLOCK_TYPE_OTHER:
|
||||||
|
|||||||
@@ -950,10 +950,7 @@ cbuf_init(void)
|
|||||||
// add the debug command
|
// add the debug command
|
||||||
add_debugger_command("cbuf_freelist", &dbg_dump_cbuf_freelists, "Dumps the cbuf free lists");
|
add_debugger_command("cbuf_freelist", &dbg_dump_cbuf_freelists, "Dumps the cbuf free lists");
|
||||||
|
|
||||||
if (mutex_init(&sFreeBufferListMutex, "cbuf_free_list") < B_OK) {
|
mutex_init(&sFreeBufferListMutex, "cbuf_free_list");
|
||||||
panic("cbuf_init: error creating cbuf_free_list mutex\n");
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
// errors are fatal, that's why we don't clean up here
|
// errors are fatal, that's why we don't clean up here
|
||||||
|
|
||||||
|
|||||||
+52
-52
@@ -1236,7 +1236,7 @@ map_backing_store(vm_address_space *addressSpace, vm_cache *cache,
|
|||||||
TRACE(("map_backing_store: aspace %p, cache %p, *vaddr %p, offset 0x%Lx, size %lu, addressSpec %ld, wiring %d, protection %d, _area %p, area_name '%s'\n",
|
TRACE(("map_backing_store: aspace %p, cache %p, *vaddr %p, offset 0x%Lx, size %lu, addressSpec %ld, wiring %d, protection %d, _area %p, area_name '%s'\n",
|
||||||
addressSpace, cache, *_virtualAddress, offset, size, addressSpec,
|
addressSpace, cache, *_virtualAddress, offset, size, addressSpec,
|
||||||
wiring, protection, _area, areaName));
|
wiring, protection, _area, areaName));
|
||||||
ASSERT_LOCKED_CUTEX(&cache->lock);
|
ASSERT_LOCKED_MUTEX(&cache->lock);
|
||||||
|
|
||||||
vm_area *area = create_area_struct(addressSpace, areaName, wiring,
|
vm_area *area = create_area_struct(addressSpace, areaName, wiring,
|
||||||
protection);
|
protection);
|
||||||
@@ -1267,7 +1267,7 @@ map_backing_store(vm_address_space *addressSpace, vm_cache *cache,
|
|||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cutex_lock(&newCache->lock);
|
mutex_lock(&newCache->lock);
|
||||||
newCache->type = CACHE_TYPE_RAM;
|
newCache->type = CACHE_TYPE_RAM;
|
||||||
newCache->temporary = 1;
|
newCache->temporary = 1;
|
||||||
newCache->scan_skip = cache->scan_skip;
|
newCache->scan_skip = cache->scan_skip;
|
||||||
@@ -1310,7 +1310,7 @@ map_backing_store(vm_address_space *addressSpace, vm_cache *cache,
|
|||||||
// point the cache back to the area
|
// point the cache back to the area
|
||||||
vm_cache_insert_area_locked(cache, area);
|
vm_cache_insert_area_locked(cache, area);
|
||||||
if (mapping == REGION_PRIVATE_MAP)
|
if (mapping == REGION_PRIVATE_MAP)
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
|
|
||||||
// insert the area in the global area hash table
|
// insert the area in the global area hash table
|
||||||
acquire_sem_etc(sAreaHashLock, WRITE_COUNT, 0 ,0);
|
acquire_sem_etc(sAreaHashLock, WRITE_COUNT, 0 ,0);
|
||||||
@@ -1328,10 +1328,10 @@ err2:
|
|||||||
// We created this cache, so we must delete it again. Note, that we
|
// We created this cache, so we must delete it again. Note, that we
|
||||||
// need to temporarily unlock the source cache or we'll otherwise
|
// need to temporarily unlock the source cache or we'll otherwise
|
||||||
// deadlock, since vm_cache_remove_consumer will try to lock it too.
|
// deadlock, since vm_cache_remove_consumer will try to lock it too.
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
cutex_unlock(&sourceCache->lock);
|
mutex_unlock(&sourceCache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
cutex_lock(&sourceCache->lock);
|
mutex_lock(&sourceCache->lock);
|
||||||
}
|
}
|
||||||
err1:
|
err1:
|
||||||
free(area->name);
|
free(area->name);
|
||||||
@@ -1525,13 +1525,13 @@ vm_create_anonymous_area(team_id team, const char *name, void **address,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
|
|
||||||
status = map_backing_store(addressSpace, cache, address, 0, size,
|
status = map_backing_store(addressSpace, cache, address, 0, size,
|
||||||
addressSpec, wiring, protection, REGION_NO_PRIVATE_MAP, &area, name,
|
addressSpec, wiring, protection, REGION_NO_PRIVATE_MAP, &area, name,
|
||||||
unmapAddressRange);
|
unmapAddressRange);
|
||||||
|
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
|
|
||||||
if (status < B_OK) {
|
if (status < B_OK) {
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
@@ -1554,7 +1554,7 @@ vm_create_anonymous_area(team_id team, const char *name, void **address,
|
|||||||
vm_page_reserve_pages(reservePages);
|
vm_page_reserve_pages(reservePages);
|
||||||
|
|
||||||
// Allocate and map all pages for this area
|
// Allocate and map all pages for this area
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
|
|
||||||
off_t offset = 0;
|
off_t offset = 0;
|
||||||
for (addr_t address = area->base; address < area->base + (area->size - 1);
|
for (addr_t address = area->base; address < area->base + (area->size - 1);
|
||||||
@@ -1579,7 +1579,7 @@ vm_create_anonymous_area(team_id team, const char *name, void **address,
|
|||||||
vm_map_page(area, page, address, protection);
|
vm_map_page(area, page, address, protection);
|
||||||
}
|
}
|
||||||
|
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
vm_page_unreserve_pages(reservePages);
|
vm_page_unreserve_pages(reservePages);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1595,7 +1595,7 @@ vm_create_anonymous_area(team_id team, const char *name, void **address,
|
|||||||
if (!kernel_startup)
|
if (!kernel_startup)
|
||||||
panic("ALREADY_WIRED flag used outside kernel startup\n");
|
panic("ALREADY_WIRED flag used outside kernel startup\n");
|
||||||
|
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
map->ops->lock(map);
|
map->ops->lock(map);
|
||||||
|
|
||||||
for (addr_t virtualAddress = area->base; virtualAddress < area->base
|
for (addr_t virtualAddress = area->base; virtualAddress < area->base
|
||||||
@@ -1622,7 +1622,7 @@ vm_create_anonymous_area(team_id team, const char *name, void **address,
|
|||||||
}
|
}
|
||||||
|
|
||||||
map->ops->unlock(map);
|
map->ops->unlock(map);
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1638,7 +1638,7 @@ vm_create_anonymous_area(team_id team, const char *name, void **address,
|
|||||||
off_t offset = 0;
|
off_t offset = 0;
|
||||||
|
|
||||||
vm_page_reserve_pages(reservePages);
|
vm_page_reserve_pages(reservePages);
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
map->ops->lock(map);
|
map->ops->lock(map);
|
||||||
|
|
||||||
for (virtualAddress = area->base; virtualAddress < area->base
|
for (virtualAddress = area->base; virtualAddress < area->base
|
||||||
@@ -1660,7 +1660,7 @@ vm_create_anonymous_area(team_id team, const char *name, void **address,
|
|||||||
}
|
}
|
||||||
|
|
||||||
map->ops->unlock(map);
|
map->ops->unlock(map);
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
vm_page_unreserve_pages(reservePages);
|
vm_page_unreserve_pages(reservePages);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1739,13 +1739,13 @@ vm_map_physical_memory(team_id team, const char *name, void **_address,
|
|||||||
cache->type = CACHE_TYPE_DEVICE;
|
cache->type = CACHE_TYPE_DEVICE;
|
||||||
cache->virtual_size = size;
|
cache->virtual_size = size;
|
||||||
|
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
|
|
||||||
status_t status = map_backing_store(locker.AddressSpace(), cache, _address,
|
status_t status = map_backing_store(locker.AddressSpace(), cache, _address,
|
||||||
0, size, addressSpec & ~B_MTR_MASK, B_FULL_LOCK, protection,
|
0, size, addressSpec & ~B_MTR_MASK, B_FULL_LOCK, protection,
|
||||||
REGION_NO_PRIVATE_MAP, &area, name, false);
|
REGION_NO_PRIVATE_MAP, &area, name, false);
|
||||||
|
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
|
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
@@ -1821,13 +1821,13 @@ vm_create_null_area(team_id team, const char *name, void **address,
|
|||||||
cache->type = CACHE_TYPE_NULL;
|
cache->type = CACHE_TYPE_NULL;
|
||||||
cache->virtual_size = size;
|
cache->virtual_size = size;
|
||||||
|
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
|
|
||||||
status = map_backing_store(locker.AddressSpace(), cache, address, 0, size,
|
status = map_backing_store(locker.AddressSpace(), cache, address, 0, size,
|
||||||
addressSpec, 0, B_KERNEL_READ_AREA, REGION_NO_PRIVATE_MAP, &area, name,
|
addressSpec, 0, B_KERNEL_READ_AREA, REGION_NO_PRIVATE_MAP, &area, name,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
|
|
||||||
if (status < B_OK) {
|
if (status < B_OK) {
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
@@ -1929,14 +1929,14 @@ _vm_map_file(team_id team, const char *name, void **_address, uint32 addressSpec
|
|||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
|
|
||||||
vm_area *area;
|
vm_area *area;
|
||||||
status = map_backing_store(locker.AddressSpace(), cache, _address,
|
status = map_backing_store(locker.AddressSpace(), cache, _address,
|
||||||
offset, size, addressSpec, 0, protection, mapping, &area, name,
|
offset, size, addressSpec, 0, protection, mapping, &area, name,
|
||||||
addressSpec == B_EXACT_ADDRESS);
|
addressSpec == B_EXACT_ADDRESS);
|
||||||
|
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
|
|
||||||
if (status < B_OK || mapping == REGION_PRIVATE_MAP) {
|
if (status < B_OK || mapping == REGION_PRIVATE_MAP) {
|
||||||
// map_backing_store() cannot know we no longer need the ref
|
// map_backing_store() cannot know we no longer need the ref
|
||||||
@@ -1971,14 +1971,14 @@ vm_area_get_locked_cache(vm_area *area)
|
|||||||
vm_cache_acquire_ref(cache);
|
vm_cache_acquire_ref(cache);
|
||||||
locker.Unlock();
|
locker.Unlock();
|
||||||
|
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
|
|
||||||
locker.Lock();
|
locker.Lock();
|
||||||
if (cache == area->cache)
|
if (cache == area->cache)
|
||||||
return cache;
|
return cache;
|
||||||
|
|
||||||
// the cache changed in the meantime
|
// the cache changed in the meantime
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1987,7 +1987,7 @@ vm_area_get_locked_cache(vm_area *area)
|
|||||||
void
|
void
|
||||||
vm_area_put_locked_cache(vm_cache *cache)
|
vm_area_put_locked_cache(vm_cache *cache)
|
||||||
{
|
{
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2207,7 +2207,7 @@ vm_copy_on_write_area(vm_cache* lowerCache)
|
|||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
cutex_lock(&upperCache->lock);
|
mutex_lock(&upperCache->lock);
|
||||||
|
|
||||||
upperCache->type = CACHE_TYPE_RAM;
|
upperCache->type = CACHE_TYPE_RAM;
|
||||||
upperCache->temporary = 1;
|
upperCache->temporary = 1;
|
||||||
@@ -3852,10 +3852,10 @@ retry:
|
|||||||
|
|
||||||
vm_cache_acquire_ref(source);
|
vm_cache_acquire_ref(source);
|
||||||
|
|
||||||
cutex_lock(&source->lock);
|
mutex_lock(&source->lock);
|
||||||
|
|
||||||
if (source->busy) {
|
if (source->busy) {
|
||||||
cutex_unlock(&source->lock);
|
mutex_unlock(&source->lock);
|
||||||
vm_cache_release_ref(source);
|
vm_cache_release_ref(source);
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
@@ -3889,7 +3889,7 @@ fault_remove_dummy_page(vm_dummy_page &dummyPage, bool isLocked)
|
|||||||
{
|
{
|
||||||
vm_cache *cache = dummyPage.cache;
|
vm_cache *cache = dummyPage.cache;
|
||||||
if (!isLocked)
|
if (!isLocked)
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
|
|
||||||
if (dummyPage.state == PAGE_STATE_BUSY) {
|
if (dummyPage.state == PAGE_STATE_BUSY) {
|
||||||
vm_cache_remove_page(cache, &dummyPage);
|
vm_cache_remove_page(cache, &dummyPage);
|
||||||
@@ -3898,7 +3898,7 @@ fault_remove_dummy_page(vm_dummy_page &dummyPage, bool isLocked)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isLocked)
|
if (!isLocked)
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
|
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
}
|
}
|
||||||
@@ -3923,7 +3923,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
|||||||
vm_page *page = NULL;
|
vm_page *page = NULL;
|
||||||
|
|
||||||
vm_cache_acquire_ref(cache);
|
vm_cache_acquire_ref(cache);
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
// we release this later in the loop
|
// we release this later in the loop
|
||||||
|
|
||||||
while (cache != NULL) {
|
while (cache != NULL) {
|
||||||
@@ -3947,9 +3947,9 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
|||||||
{
|
{
|
||||||
ConditionVariableEntry entry;
|
ConditionVariableEntry entry;
|
||||||
entry.Add(page);
|
entry.Add(page);
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
entry.Wait();
|
entry.Wait();
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cache->busy) {
|
if (cache->busy) {
|
||||||
@@ -3958,7 +3958,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
|||||||
// the top cache.
|
// the top cache.
|
||||||
ConditionVariableEntry entry;
|
ConditionVariableEntry entry;
|
||||||
entry.Add(cache);
|
entry.Add(cache);
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
entry.Wait();
|
entry.Wait();
|
||||||
*_restart = true;
|
*_restart = true;
|
||||||
@@ -3982,7 +3982,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
|||||||
ConditionVariable busyCondition;
|
ConditionVariable busyCondition;
|
||||||
busyCondition.Publish(page, "page");
|
busyCondition.Publish(page, "page");
|
||||||
|
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
|
|
||||||
// get a virtual address for the page
|
// get a virtual address for the page
|
||||||
iovec vec;
|
iovec vec;
|
||||||
@@ -3997,7 +3997,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
|||||||
|
|
||||||
map->ops->put_physical_page((addr_t)vec.iov_base);
|
map->ops->put_physical_page((addr_t)vec.iov_base);
|
||||||
|
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
|
|
||||||
if (status < B_OK) {
|
if (status < B_OK) {
|
||||||
// on error remove and free the page
|
// on error remove and free the page
|
||||||
@@ -4008,7 +4008,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
|||||||
vm_cache_remove_page(cache, page);
|
vm_cache_remove_page(cache, page);
|
||||||
vm_page_set_state(page, PAGE_STATE_FREE);
|
vm_page_set_state(page, PAGE_STATE_FREE);
|
||||||
|
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -4031,16 +4031,16 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
|||||||
// the source cache is currently in the process of being merged
|
// the source cache is currently in the process of being merged
|
||||||
// with his only consumer (cacheRef); since its pages are moved
|
// with his only consumer (cacheRef); since its pages are moved
|
||||||
// upwards, too, we try this cache again
|
// upwards, too, we try this cache again
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
thread_yield(true);
|
thread_yield(true);
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
if (cache->busy) {
|
if (cache->busy) {
|
||||||
// The cache became busy, which means, it is about to be
|
// The cache became busy, which means, it is about to be
|
||||||
// removed by vm_cache_remove_consumer(). We start again with
|
// removed by vm_cache_remove_consumer(). We start again with
|
||||||
// the top cache.
|
// the top cache.
|
||||||
ConditionVariableEntry entry;
|
ConditionVariableEntry entry;
|
||||||
entry.Add(cache);
|
entry.Add(cache);
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
entry.Wait();
|
entry.Wait();
|
||||||
*_restart = true;
|
*_restart = true;
|
||||||
@@ -4051,7 +4051,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
|||||||
} else if (status < B_OK)
|
} else if (status < B_OK)
|
||||||
nextCache = NULL;
|
nextCache = NULL;
|
||||||
|
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
// at this point, we still hold a ref to this cache (through lastCacheRef)
|
// at this point, we still hold a ref to this cache (through lastCacheRef)
|
||||||
|
|
||||||
cache = nextCache;
|
cache = nextCache;
|
||||||
@@ -4066,7 +4066,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
|||||||
// Read-only pages come in the deepest cache - only the
|
// Read-only pages come in the deepest cache - only the
|
||||||
// top most cache may have direct write access.
|
// top most cache may have direct write access.
|
||||||
vm_cache_acquire_ref(cache);
|
vm_cache_acquire_ref(cache);
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
|
|
||||||
if (cache->busy) {
|
if (cache->busy) {
|
||||||
// The cache became busy, which means, it is about to be
|
// The cache became busy, which means, it is about to be
|
||||||
@@ -4074,7 +4074,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
|||||||
// the top cache.
|
// the top cache.
|
||||||
ConditionVariableEntry entry;
|
ConditionVariableEntry entry;
|
||||||
entry.Add(cache);
|
entry.Add(cache);
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
entry.Wait();
|
entry.Wait();
|
||||||
*_restart = true;
|
*_restart = true;
|
||||||
@@ -4085,7 +4085,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
|||||||
// for, but it could as well be a dummy page from someone
|
// for, but it could as well be a dummy page from someone
|
||||||
// else or an otherwise busy page. We can't really handle
|
// else or an otherwise busy page. We can't really handle
|
||||||
// that here. Hence we completely restart this functions.
|
// that here. Hence we completely restart this functions.
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
*_restart = true;
|
*_restart = true;
|
||||||
}
|
}
|
||||||
@@ -4128,7 +4128,7 @@ fault_get_page(vm_translation_map *map, vm_cache *topCache, off_t cacheOffset,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
// Remove the dummy page, if it has been inserted.
|
// Remove the dummy page, if it has been inserted.
|
||||||
cutex_lock(&topCache->lock);
|
mutex_lock(&topCache->lock);
|
||||||
|
|
||||||
if (dummyPage.state == PAGE_STATE_BUSY) {
|
if (dummyPage.state == PAGE_STATE_BUSY) {
|
||||||
ASSERT_PRINT(dummyPage.cache == topCache, "dummy page: %p\n",
|
ASSERT_PRINT(dummyPage.cache == topCache, "dummy page: %p\n",
|
||||||
@@ -4136,7 +4136,7 @@ fault_get_page(vm_translation_map *map, vm_cache *topCache, off_t cacheOffset,
|
|||||||
fault_remove_dummy_page(dummyPage, true);
|
fault_remove_dummy_page(dummyPage, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
cutex_unlock(&topCache->lock);
|
mutex_unlock(&topCache->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page == NULL) {
|
if (page == NULL) {
|
||||||
@@ -4175,9 +4175,9 @@ fault_get_page(vm_translation_map *map, vm_cache *topCache, off_t cacheOffset,
|
|||||||
// This is not the top cache into which we inserted the dummy page,
|
// This is not the top cache into which we inserted the dummy page,
|
||||||
// let's remove it from there. We need to temporarily unlock our
|
// let's remove it from there. We need to temporarily unlock our
|
||||||
// cache to comply with the cache locking policy.
|
// cache to comply with the cache locking policy.
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
fault_remove_dummy_page(dummyPage, false);
|
fault_remove_dummy_page(dummyPage, false);
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4225,8 +4225,8 @@ if (cacheOffset == 0x12000)
|
|||||||
if (sourcePage->state != PAGE_STATE_MODIFIED)
|
if (sourcePage->state != PAGE_STATE_MODIFIED)
|
||||||
vm_page_set_state(sourcePage, PAGE_STATE_ACTIVE);
|
vm_page_set_state(sourcePage, PAGE_STATE_ACTIVE);
|
||||||
|
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
cutex_lock(&topCache->lock);
|
mutex_lock(&topCache->lock);
|
||||||
|
|
||||||
// Since the top cache has been unlocked for a while, someone else
|
// Since the top cache has been unlocked for a while, someone else
|
||||||
// (vm_cache_remove_consumer()) might have replaced our dummy page.
|
// (vm_cache_remove_consumer()) might have replaced our dummy page.
|
||||||
@@ -4244,9 +4244,9 @@ if (cacheOffset == 0x12000)
|
|||||||
// The page is busy, wait till it becomes unbusy.
|
// The page is busy, wait till it becomes unbusy.
|
||||||
ConditionVariableEntry entry;
|
ConditionVariableEntry entry;
|
||||||
entry.Add(newPage);
|
entry.Add(newPage);
|
||||||
cutex_unlock(&topCache->lock);
|
mutex_unlock(&topCache->lock);
|
||||||
entry.Wait();
|
entry.Wait();
|
||||||
cutex_lock(&topCache->lock);
|
mutex_lock(&topCache->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newPage) {
|
if (newPage) {
|
||||||
@@ -4358,7 +4358,7 @@ vm_soft_fault(addr_t originalAddress, bool isWrite, bool isUser)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cutex_unlock(&topCache->lock);
|
mutex_unlock(&topCache->lock);
|
||||||
|
|
||||||
// The top most cache has no fault handler, so let's see if the cache or its sources
|
// The top most cache has no fault handler, so let's see if the cache or its sources
|
||||||
// already have the page we're searching for (we're going from top to bottom)
|
// already have the page we're searching for (we're going from top to bottom)
|
||||||
@@ -4408,7 +4408,7 @@ vm_soft_fault(addr_t originalAddress, bool isWrite, bool isUser)
|
|||||||
|
|
||||||
vm_map_page(area, page, address, newProtection);
|
vm_map_page(area, page, address, newProtection);
|
||||||
|
|
||||||
cutex_unlock(&pageSource->lock);
|
mutex_unlock(&pageSource->lock);
|
||||||
vm_cache_release_ref(pageSource);
|
vm_cache_release_ref(pageSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ delete_cache(vm_cache* cache)
|
|||||||
if (cache->source)
|
if (cache->source)
|
||||||
vm_cache_remove_consumer(cache->source, cache);
|
vm_cache_remove_consumer(cache->source, cache);
|
||||||
|
|
||||||
cutex_destroy(&cache->lock);
|
mutex_destroy(&cache->lock);
|
||||||
free(cache);
|
free(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,7 +194,7 @@ vm_cache_create(vm_store* store)
|
|||||||
if (cache == NULL)
|
if (cache == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
cutex_init(&cache->lock, "vm_cache");
|
mutex_init(&cache->lock, "vm_cache");
|
||||||
list_init_etc(&cache->consumers, offsetof(vm_cache, consumer_link));
|
list_init_etc(&cache->consumers, offsetof(vm_cache, consumer_link));
|
||||||
cache->page_list = NULL;
|
cache->page_list = NULL;
|
||||||
cache->areas = NULL;
|
cache->areas = NULL;
|
||||||
@@ -265,7 +265,7 @@ vm_cache_release_ref(vm_cache* cache)
|
|||||||
vm_cache* c;
|
vm_cache* c;
|
||||||
bool locked = false;
|
bool locked = false;
|
||||||
if (cacheRef->lock.holder != find_thread(NULL)) {
|
if (cacheRef->lock.holder != find_thread(NULL)) {
|
||||||
cutex_lock(&cacheRef->lock);
|
mutex_lock(&cacheRef->lock);
|
||||||
locked = true;
|
locked = true;
|
||||||
}
|
}
|
||||||
for (a = cacheRef->areas; a != NULL; a = a->cache_next)
|
for (a = cacheRef->areas; a != NULL; a = a->cache_next)
|
||||||
@@ -278,7 +278,7 @@ vm_cache_release_ref(vm_cache* cache)
|
|||||||
if (cacheRef->ref_count < min)
|
if (cacheRef->ref_count < min)
|
||||||
panic("cache_ref %p has too little ref_count!!!!", cacheRef);
|
panic("cache_ref %p has too little ref_count!!!!", cacheRef);
|
||||||
if (locked)
|
if (locked)
|
||||||
cutex_unlock(&cacheRef->lock);
|
mutex_unlock(&cacheRef->lock);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
@@ -310,7 +310,7 @@ vm_cache_acquire_page_cache_ref(vm_page* page)
|
|||||||
vm_page*
|
vm_page*
|
||||||
vm_cache_lookup_page(vm_cache* cache, off_t offset)
|
vm_cache_lookup_page(vm_cache* cache, off_t offset)
|
||||||
{
|
{
|
||||||
ASSERT_LOCKED_CUTEX(&cache->lock);
|
ASSERT_LOCKED_MUTEX(&cache->lock);
|
||||||
|
|
||||||
struct page_lookup_key key;
|
struct page_lookup_key key;
|
||||||
key.offset = (uint32)(offset >> PAGE_SHIFT);
|
key.offset = (uint32)(offset >> PAGE_SHIFT);
|
||||||
@@ -336,7 +336,7 @@ vm_cache_insert_page(vm_cache* cache, vm_page* page, off_t offset)
|
|||||||
{
|
{
|
||||||
TRACE(("vm_cache_insert_page: cache %p, page %p, offset %Ld\n",
|
TRACE(("vm_cache_insert_page: cache %p, page %p, offset %Ld\n",
|
||||||
cache, page, offset));
|
cache, page, offset));
|
||||||
ASSERT_LOCKED_CUTEX(&cache->lock);
|
ASSERT_LOCKED_MUTEX(&cache->lock);
|
||||||
|
|
||||||
if (page->cache != NULL) {
|
if (page->cache != NULL) {
|
||||||
panic("insert page %p into cache %p: page cache is set to %p\n",
|
panic("insert page %p into cache %p: page cache is set to %p\n",
|
||||||
@@ -383,7 +383,7 @@ void
|
|||||||
vm_cache_remove_page(vm_cache* cache, vm_page* page)
|
vm_cache_remove_page(vm_cache* cache, vm_page* page)
|
||||||
{
|
{
|
||||||
TRACE(("vm_cache_remove_page: cache %p, page %p\n", cache, page));
|
TRACE(("vm_cache_remove_page: cache %p, page %p\n", cache, page));
|
||||||
ASSERT_LOCKED_CUTEX(&cache->lock);
|
ASSERT_LOCKED_MUTEX(&cache->lock);
|
||||||
|
|
||||||
if (page->cache != cache) {
|
if (page->cache != cache) {
|
||||||
panic("remove page %p from cache %p: page cache is set to %p\n", page,
|
panic("remove page %p from cache %p: page cache is set to %p\n", page,
|
||||||
@@ -421,9 +421,9 @@ vm_cache_write_modified(vm_cache* cache, bool fsReenter)
|
|||||||
if (cache->temporary)
|
if (cache->temporary)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
status_t status = vm_page_write_modified_pages(cache, fsReenter);
|
status_t status = vm_page_write_modified_pages(cache, fsReenter);
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -438,7 +438,7 @@ vm_cache_set_minimal_commitment_locked(vm_cache* cache, off_t commitment)
|
|||||||
{
|
{
|
||||||
TRACE(("vm_cache_set_minimal_commitment_locked(cache %p, commitment %Ld)\n",
|
TRACE(("vm_cache_set_minimal_commitment_locked(cache %p, commitment %Ld)\n",
|
||||||
cache, commitment));
|
cache, commitment));
|
||||||
ASSERT_LOCKED_CUTEX(&cache->lock);
|
ASSERT_LOCKED_MUTEX(&cache->lock);
|
||||||
|
|
||||||
vm_store* store = cache->store;
|
vm_store* store = cache->store;
|
||||||
status_t status = B_OK;
|
status_t status = B_OK;
|
||||||
@@ -471,7 +471,7 @@ vm_cache_resize(vm_cache* cache, off_t newSize)
|
|||||||
{
|
{
|
||||||
TRACE(("vm_cache_resize(cache %p, newSize %Ld) old size %Ld\n",
|
TRACE(("vm_cache_resize(cache %p, newSize %Ld) old size %Ld\n",
|
||||||
cache, newSize, cache->virtual_size));
|
cache, newSize, cache->virtual_size));
|
||||||
ASSERT_LOCKED_CUTEX(&cache->lock);
|
ASSERT_LOCKED_MUTEX(&cache->lock);
|
||||||
|
|
||||||
status_t status = cache->store->ops->commit(cache->store, newSize);
|
status_t status = cache->store->ops->commit(cache->store, newSize);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
@@ -502,9 +502,9 @@ vm_cache_resize(vm_cache* cache, off_t newSize)
|
|||||||
// wait for page to become unbusy
|
// wait for page to become unbusy
|
||||||
ConditionVariableEntry entry;
|
ConditionVariableEntry entry;
|
||||||
entry.Add(page);
|
entry.Add(page);
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
entry.Wait();
|
entry.Wait();
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
|
|
||||||
// restart from the start of the list
|
// restart from the start of the list
|
||||||
page = cache->page_list;
|
page = cache->page_list;
|
||||||
@@ -534,7 +534,7 @@ void
|
|||||||
vm_cache_remove_consumer(vm_cache* cache, vm_cache* consumer)
|
vm_cache_remove_consumer(vm_cache* cache, vm_cache* consumer)
|
||||||
{
|
{
|
||||||
TRACE(("remove consumer vm cache %p from cache %p\n", consumer, cache));
|
TRACE(("remove consumer vm cache %p from cache %p\n", consumer, cache));
|
||||||
ASSERT_LOCKED_CUTEX(&consumer->lock);
|
ASSERT_LOCKED_MUTEX(&consumer->lock);
|
||||||
|
|
||||||
// Remove the store ref before locking the cache. Otherwise we'd call into
|
// Remove the store ref before locking the cache. Otherwise we'd call into
|
||||||
// the VFS while holding the cache lock, which would reverse the usual
|
// the VFS while holding the cache lock, which would reverse the usual
|
||||||
@@ -543,7 +543,7 @@ vm_cache_remove_consumer(vm_cache* cache, vm_cache* consumer)
|
|||||||
cache->store->ops->release_ref(cache->store);
|
cache->store->ops->release_ref(cache->store);
|
||||||
|
|
||||||
// remove the consumer from the cache, but keep its reference until later
|
// remove the consumer from the cache, but keep its reference until later
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
list_remove_item(&cache->consumers, consumer);
|
list_remove_item(&cache->consumers, consumer);
|
||||||
consumer->source = NULL;
|
consumer->source = NULL;
|
||||||
|
|
||||||
@@ -569,10 +569,10 @@ vm_cache_remove_consumer(vm_cache* cache, vm_cache* consumer)
|
|||||||
// need to unlock our cache now
|
// need to unlock our cache now
|
||||||
busyCondition.Publish(cache, "cache");
|
busyCondition.Publish(cache, "cache");
|
||||||
cache->busy = true;
|
cache->busy = true;
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
|
|
||||||
cutex_lock(&consumer->lock);
|
mutex_lock(&consumer->lock);
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
|
|
||||||
if (cache->areas != NULL || cache->source == NULL
|
if (cache->areas != NULL || cache->source == NULL
|
||||||
|| list_is_empty(&cache->consumers)
|
|| list_is_empty(&cache->consumers)
|
||||||
@@ -583,7 +583,7 @@ vm_cache_remove_consumer(vm_cache* cache, vm_cache* consumer)
|
|||||||
merge = false;
|
merge = false;
|
||||||
cache->busy = false;
|
cache->busy = false;
|
||||||
busyCondition.Unpublish();
|
busyCondition.Unpublish();
|
||||||
cutex_unlock(&consumer->lock);
|
mutex_unlock(&consumer->lock);
|
||||||
vm_cache_release_ref(consumer);
|
vm_cache_release_ref(consumer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -637,14 +637,14 @@ vm_cache_remove_consumer(vm_cache* cache, vm_cache* consumer)
|
|||||||
vm_cache* newSource = cache->source;
|
vm_cache* newSource = cache->source;
|
||||||
|
|
||||||
// The remaining consumer has gotten a new source
|
// The remaining consumer has gotten a new source
|
||||||
cutex_lock(&newSource->lock);
|
mutex_lock(&newSource->lock);
|
||||||
|
|
||||||
list_remove_item(&newSource->consumers, cache);
|
list_remove_item(&newSource->consumers, cache);
|
||||||
list_add_item(&newSource->consumers, consumer);
|
list_add_item(&newSource->consumers, consumer);
|
||||||
consumer->source = newSource;
|
consumer->source = newSource;
|
||||||
cache->source = NULL;
|
cache->source = NULL;
|
||||||
|
|
||||||
cutex_unlock(&newSource->lock);
|
mutex_unlock(&newSource->lock);
|
||||||
|
|
||||||
// Release the other reference to the cache - we take over
|
// Release the other reference to the cache - we take over
|
||||||
// its reference of its source cache; we can do this here
|
// its reference of its source cache; we can do this here
|
||||||
@@ -654,7 +654,7 @@ if (cache->ref_count < 2)
|
|||||||
panic("cacheRef %p ref count too low!\n", cache);
|
panic("cacheRef %p ref count too low!\n", cache);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
|
|
||||||
cutex_unlock(&consumer->lock);
|
mutex_unlock(&consumer->lock);
|
||||||
vm_cache_release_ref(consumer);
|
vm_cache_release_ref(consumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -662,7 +662,7 @@ panic("cacheRef %p ref count too low!\n", cache);
|
|||||||
busyCondition.Unpublish();
|
busyCondition.Unpublish();
|
||||||
}
|
}
|
||||||
|
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -676,8 +676,8 @@ void
|
|||||||
vm_cache_add_consumer_locked(vm_cache* cache, vm_cache* consumer)
|
vm_cache_add_consumer_locked(vm_cache* cache, vm_cache* consumer)
|
||||||
{
|
{
|
||||||
TRACE(("add consumer vm cache %p to cache %p\n", consumer, cache));
|
TRACE(("add consumer vm cache %p to cache %p\n", consumer, cache));
|
||||||
ASSERT_LOCKED_CUTEX(&cache->lock);
|
ASSERT_LOCKED_MUTEX(&cache->lock);
|
||||||
ASSERT_LOCKED_CUTEX(&consumer->lock);
|
ASSERT_LOCKED_MUTEX(&consumer->lock);
|
||||||
|
|
||||||
consumer->source = cache;
|
consumer->source = cache;
|
||||||
list_add_item(&cache->consumers, consumer);
|
list_add_item(&cache->consumers, consumer);
|
||||||
@@ -696,7 +696,7 @@ status_t
|
|||||||
vm_cache_insert_area_locked(vm_cache* cache, vm_area* area)
|
vm_cache_insert_area_locked(vm_cache* cache, vm_area* area)
|
||||||
{
|
{
|
||||||
TRACE(("vm_cache_insert_area_locked(cache %p, area %p)\n", cache, area));
|
TRACE(("vm_cache_insert_area_locked(cache %p, area %p)\n", cache, area));
|
||||||
ASSERT_LOCKED_CUTEX(&cache->lock);
|
ASSERT_LOCKED_MUTEX(&cache->lock);
|
||||||
|
|
||||||
area->cache_next = cache->areas;
|
area->cache_next = cache->areas;
|
||||||
if (area->cache_next)
|
if (area->cache_next)
|
||||||
@@ -716,7 +716,7 @@ vm_cache_remove_area(vm_cache* cache, vm_area* area)
|
|||||||
{
|
{
|
||||||
TRACE(("vm_cache_remove_area(cache %p, area %p)\n", cache, area));
|
TRACE(("vm_cache_remove_area(cache %p, area %p)\n", cache, area));
|
||||||
|
|
||||||
CutexLocker locker(cache->lock);
|
MutexLocker locker(cache->lock);
|
||||||
|
|
||||||
if (area->cache_prev)
|
if (area->cache_prev)
|
||||||
area->cache_prev->cache_next = area->cache_next;
|
area->cache_prev->cache_next = area->cache_next;
|
||||||
|
|||||||
@@ -66,15 +66,15 @@ PageCacheLocker::Lock(vm_page* page, bool dontWait)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (dontWait) {
|
if (dontWait) {
|
||||||
if (cutex_trylock(&cache->lock) != B_OK) {
|
if (mutex_trylock(&cache->lock) != B_OK) {
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
|
|
||||||
if (cache != page->cache || _IgnorePage(page)) {
|
if (cache != page->cache || _IgnorePage(page)) {
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -91,7 +91,7 @@ PageCacheLocker::Unlock()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
vm_cache* cache = fPage->cache;
|
vm_cache* cache = fPage->cache;
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
vm_cache_release_ref(cache);
|
vm_cache_release_ref(cache);
|
||||||
|
|
||||||
fPage = NULL;
|
fPage = NULL;
|
||||||
|
|||||||
@@ -184,8 +184,7 @@ vm_low_memory_init(void)
|
|||||||
status_t
|
status_t
|
||||||
vm_low_memory_init_post_thread(void)
|
vm_low_memory_init_post_thread(void)
|
||||||
{
|
{
|
||||||
if (mutex_init(&sLowMemoryMutex, "low memory") < B_OK)
|
mutex_init(&sLowMemoryMutex, "low memory");
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
sLowMemoryWaitSem = create_sem(0, "low memory wait");
|
sLowMemoryWaitSem = create_sem(0, "low memory wait");
|
||||||
if (sLowMemoryWaitSem < B_OK)
|
if (sLowMemoryWaitSem < B_OK)
|
||||||
|
|||||||
@@ -1043,7 +1043,7 @@ page_writer(void* /*unused*/)
|
|||||||
|
|
||||||
for (uint32 i = 0; i < numPages; i++) {
|
for (uint32 i = 0; i < numPages; i++) {
|
||||||
vm_cache *cache = u.pages[i]->cache;
|
vm_cache *cache = u.pages[i]->cache;
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
|
|
||||||
if (writeStatus[i] == B_OK) {
|
if (writeStatus[i] == B_OK) {
|
||||||
// put it into the active queue
|
// put it into the active queue
|
||||||
@@ -1069,7 +1069,7 @@ page_writer(void* /*unused*/)
|
|||||||
busyConditions[i].Unpublish();
|
busyConditions[i].Unpublish();
|
||||||
|
|
||||||
u.caches[i] = cache;
|
u.caches[i] = cache;
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32 i = 0; i < numPages; i++) {
|
for (uint32 i = 0; i < numPages; i++) {
|
||||||
@@ -1156,7 +1156,7 @@ steal_page(vm_page *page, bool stealActive)
|
|||||||
{
|
{
|
||||||
fCache = vm_cache_acquire_page_cache_ref(page);
|
fCache = vm_cache_acquire_page_cache_ref(page);
|
||||||
if (fCache != NULL) {
|
if (fCache != NULL) {
|
||||||
if (cutex_trylock(&fCache->lock) != B_OK)
|
if (mutex_trylock(&fCache->lock) != B_OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fOwnsLock = true;
|
fOwnsLock = true;
|
||||||
@@ -1169,7 +1169,7 @@ steal_page(vm_page *page, bool stealActive)
|
|||||||
~PageCacheTryLocker()
|
~PageCacheTryLocker()
|
||||||
{
|
{
|
||||||
if (fOwnsLock)
|
if (fOwnsLock)
|
||||||
cutex_unlock(&fCache->lock);
|
mutex_unlock(&fCache->lock);
|
||||||
if (fCache != NULL)
|
if (fCache != NULL)
|
||||||
vm_cache_release_ref(fCache);
|
vm_cache_release_ref(fCache);
|
||||||
}
|
}
|
||||||
@@ -1345,9 +1345,9 @@ vm_page_write_modified_pages(vm_cache *cache, bool fsReenter)
|
|||||||
// clear the modified flag
|
// clear the modified flag
|
||||||
vm_clear_map_flags(page, PAGE_MODIFIED);
|
vm_clear_map_flags(page, PAGE_MODIFIED);
|
||||||
|
|
||||||
cutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
status_t status = write_page(page, fsReenter);
|
status_t status = write_page(page, fsReenter);
|
||||||
cutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
|
|
||||||
InterruptsSpinLocker locker(&sPageLock);
|
InterruptsSpinLocker locker(&sPageLock);
|
||||||
|
|
||||||
|
|||||||
@@ -657,7 +657,8 @@ driver_settings_init(kernel_args *args)
|
|||||||
status_t
|
status_t
|
||||||
driver_settings_init_post_sem(kernel_args *args)
|
driver_settings_init_post_sem(kernel_args *args)
|
||||||
{
|
{
|
||||||
return mutex_init(&sLock, "driver settings");
|
mutex_init(&sLock, "driver settings");
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user