* Detemplatized ConditionVariable{Entry}. Merged them with their

respective Private* base class.
* Changed sigwait() and sigsuspend() to use thread_block() instead of a
  condition variable.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25100 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2008-04-22 18:32:15 +00:00
parent b95f6d4710
commit 6cef245eca
15 changed files with 149 additions and 221 deletions
+47 -101
View File
@@ -16,152 +16,98 @@
#include <util/OpenHashTable.h> #include <util/OpenHashTable.h>
class PrivateConditionVariable; class ConditionVariable;
struct PrivateConditionVariableEntry struct ConditionVariableEntry
: DoublyLinkedListLinkImpl<PrivateConditionVariableEntry> { : DoublyLinkedListLinkImpl<ConditionVariableEntry> {
public: public:
#if KDEBUG #if KDEBUG
inline PrivateConditionVariableEntry() inline ConditionVariableEntry();
: fVariable(NULL) inline ~ConditionVariableEntry();
{
}
inline ~PrivateConditionVariableEntry()
{
if (fVariable != NULL) {
panic("Destroying condition variable entry %p, but it's still "
"attached to variable %p\n", this, fVariable);
}
}
#endif #endif
inline PrivateConditionVariable* Variable() const bool Add(const void* object, uint32 flags = 0);
{ return fVariable; }
protected:
bool Add(const void* object, uint32 flags);
status_t Wait(); status_t Wait();
status_t Wait(const void* object, uint32 flags); status_t Wait(const void* object, uint32 flags = 0);
protected: inline ConditionVariable* Variable() const { return fVariable; }
PrivateConditionVariable* fVariable;
private:
ConditionVariable* fVariable;
struct thread* fThread; struct thread* fThread;
friend class PrivateConditionVariable; friend class ConditionVariable;
}; };
class PrivateConditionVariable class ConditionVariable : protected HashTableLink<ConditionVariable> {
: protected HashTableLink<PrivateConditionVariable> {
public: public:
static void ListAll();
void Dump() const;
const void* Object() const { return fObject; }
protected:
void Publish(const void* object, void Publish(const void* object,
const char* objectType); const char* objectType);
void Unpublish(bool threadsLocked); void Unpublish(bool threadsLocked = false);
void Notify(bool all, bool threadsLocked);
inline void NotifyOne(bool threadsLocked = false);
inline void NotifyAll(bool threadsLocked = false);
const void* Object() const { return fObject; }
static void ListAll();
void Dump() const;
private: private:
void _Notify(bool all, status_t result); void _Notify(bool all, bool threadsLocked);
void _NotifyChecked(bool all, status_t result);
protected: protected:
typedef DoublyLinkedList<PrivateConditionVariableEntry> EntryList; typedef DoublyLinkedList<ConditionVariableEntry> EntryList;
const void* fObject; const void* fObject;
const char* fObjectType; const char* fObjectType;
EntryList fEntries; EntryList fEntries;
friend class PrivateConditionVariableEntry; friend class ConditionVariableEntry;
friend class ConditionVariableHashDefinition; friend class ConditionVariableHashDefinition;
}; };
template<typename Type = void> #if KDEBUG
class ConditionVariable : private PrivateConditionVariable {
public:
inline void Publish(const Type* object,
const char* objectType);
inline void Unpublish(bool threadsLocked = false); inline
inline void NotifyOne(bool threadsLocked = false); ConditionVariableEntry::ConditionVariableEntry()
inline void NotifyAll(bool threadsLocked = false); : fVariable(NULL)
}; {
}
inline
ConditionVariableEntry::~ConditionVariableEntry()
{
if (fVariable != NULL) {
panic("Destroying condition variable entry %p, but it's still "
"attached to variable %p\n", this, fVariable);
}
}
#endif
template<typename Type = void>
class ConditionVariableEntry : public PrivateConditionVariableEntry {
public:
inline bool Add(const Type* object, uint32 flags = 0);
inline status_t Wait();
inline status_t Wait(const Type* object, uint32 flags = 0);
};
template<typename Type>
inline void inline void
ConditionVariable<Type>::Publish(const Type* object, const char* objectType) ConditionVariable::NotifyOne(bool threadsLocked)
{ {
PrivateConditionVariable::Publish(object, objectType); _Notify(false, threadsLocked);
} }
template<typename Type>
inline void inline void
ConditionVariable<Type>::Unpublish(bool threadsLocked) ConditionVariable::NotifyAll(bool threadsLocked)
{ {
PrivateConditionVariable::Unpublish(threadsLocked); _Notify(true, threadsLocked);
}
template<typename Type>
inline void
ConditionVariable<Type>::NotifyOne(bool threadsLocked)
{
PrivateConditionVariable::Notify(false, threadsLocked);
}
template<typename Type>
inline void
ConditionVariable<Type>::NotifyAll(bool threadsLocked)
{
PrivateConditionVariable::Notify(true, threadsLocked);
}
template<typename Type>
inline bool
ConditionVariableEntry<Type>::Add(const Type* object, uint32 flags)
{
return PrivateConditionVariableEntry::Add(object, flags);
}
template<typename Type>
inline status_t
ConditionVariableEntry<Type>::Wait()
{
return PrivateConditionVariableEntry::Wait();
}
template<typename Type>
inline status_t
ConditionVariableEntry<Type>::Wait(const Type* object, uint32 flags)
{
return PrivateConditionVariableEntry::Wait(object, flags);
} }
extern "C" { extern "C" {
#endif // __cplusplus #endif // __cplusplus
struct thread;
extern void condition_variable_init(); extern void condition_variable_init();
#ifdef __cplusplus #ifdef __cplusplus
+5 -4
View File
@@ -61,6 +61,7 @@ enum {
THREAD_BLOCK_TYPE_SEMAPHORE = 0, THREAD_BLOCK_TYPE_SEMAPHORE = 0,
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_USER_BASE = 10000 THREAD_BLOCK_TYPE_USER_BASE = 10000
}; };
@@ -151,10 +152,10 @@ struct team_job_control_children {
}; };
struct team_dead_children : team_job_control_children { struct team_dead_children : team_job_control_children {
ConditionVariable<team_dead_children> condition_variable; ConditionVariable condition_variable;
uint32 count; uint32 count;
bigtime_t kernel_time; bigtime_t kernel_time;
bigtime_t user_time; bigtime_t user_time;
}; };
+1 -1
View File
@@ -131,7 +131,7 @@ enum {
}; };
struct vm_dummy_page : vm_page { struct vm_dummy_page : vm_page {
ConditionVariable<vm_page> busy_condition; ConditionVariable busy_condition;
}; };
struct vm_cache { struct vm_cache {
+3 -3
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2007, Ingo Weinhold, [email protected]. All rights reserved. * Copyright 2007-2008, Ingo Weinhold, [email protected].
* Copyright 2004-2006, Axel Dörfler, [email protected]. All rights reserved. * Copyright 2004-2006, Axel Dörfler, [email protected]. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
@@ -402,12 +402,12 @@ RequestOwner::Wait(bool interruptable)
// not yet done // not yet done
// publish the condition variable // publish the condition variable
ConditionVariable<> conditionVariable; ConditionVariable conditionVariable;
conditionVariable.Publish(this, "tty request"); conditionVariable.Publish(this, "tty request");
fConditionVariable = &conditionVariable; fConditionVariable = &conditionVariable;
// add an entry to wait on // add an entry to wait on
ConditionVariableEntry<> entry; ConditionVariableEntry entry;
entry.Add(this, interruptable ? B_CAN_INTERRUPT : 0); entry.Add(this, interruptable ? B_CAN_INTERRUPT : 0);
locker.Unlock(); locker.Unlock();
+1 -1
View File
@@ -101,7 +101,7 @@ class RequestOwner {
status_t Error() const { return fError; } status_t Error() const { return fError; }
private: private:
ConditionVariable<>* fConditionVariable; ConditionVariable* fConditionVariable;
tty_cookie* fCookie; tty_cookie* fCookie;
status_t fError; status_t fError;
RequestQueue* fRequestQueues[2]; RequestQueue* fRequestQueues[2];
+2 -2
View File
@@ -114,7 +114,7 @@ struct block_cache : DoublyLinkedListLinkImpl<block_cache> {
bool read_only; bool read_only;
NotificationList pending_notifications; NotificationList pending_notifications;
ConditionVariable<block_cache> condition_variable; ConditionVariable condition_variable;
bool deleting; bool deleting;
block_cache(int fd, off_t numBlocks, size_t blockSize, bool readOnly); block_cache(int fd, off_t numBlocks, size_t blockSize, bool readOnly);
@@ -1611,7 +1611,7 @@ wait_for_notifications(block_cache *cache)
set_notification(NULL, notification, TRANSACTION_WRITTEN, notify_sync, set_notification(NULL, notification, TRANSACTION_WRITTEN, notify_sync,
cache); cache);
ConditionVariableEntry<block_cache> entry; ConditionVariableEntry entry;
entry.Add(cache); entry.Add(cache);
add_notification(cache, &notification, TRANSACTION_WRITTEN, false); add_notification(cache, &notification, TRANSACTION_WRITTEN, false);
+4 -4
View File
@@ -184,7 +184,7 @@ read_into_cache(file_cache_ref *ref, void *cookie, off_t offset,
size_t numBytes = PAGE_ALIGN(pageOffset + bufferSize); size_t numBytes = PAGE_ALIGN(pageOffset + bufferSize);
vm_page *pages[MAX_IO_VECS]; vm_page *pages[MAX_IO_VECS];
ConditionVariable<vm_page> busyConditions[MAX_IO_VECS]; ConditionVariable busyConditions[MAX_IO_VECS];
int32 pageIndex = 0; int32 pageIndex = 0;
// allocate pages for the cache and mark them busy // allocate pages for the cache and mark them busy
@@ -324,7 +324,7 @@ write_to_cache(file_cache_ref *ref, void *cookie, off_t offset,
vm_page *pages[MAX_IO_VECS]; vm_page *pages[MAX_IO_VECS];
int32 pageIndex = 0; int32 pageIndex = 0;
status_t status = B_OK; status_t status = B_OK;
ConditionVariable<vm_page> busyConditions[MAX_IO_VECS]; ConditionVariable busyConditions[MAX_IO_VECS];
// ToDo: this should be settable somewhere // ToDo: this should be settable somewhere
bool writeThrough = false; bool writeThrough = false;
@@ -622,7 +622,7 @@ cache_io(void *_cacheRef, void *cookie, off_t offset, addr_t buffer,
return status; return status;
if (page->state == PAGE_STATE_BUSY) { if (page->state == PAGE_STATE_BUSY) {
ConditionVariableEntry<vm_page> entry; ConditionVariableEntry entry;
entry.Add(page); entry.Add(page);
locker.Unlock(); locker.Unlock();
entry.Wait(); entry.Wait();
@@ -790,7 +790,7 @@ cache_prefetch_vnode(struct vnode *vnode, off_t offset, size_t size)
if (page != NULL) { if (page != NULL) {
if (page->state == PAGE_STATE_BUSY) { if (page->state == PAGE_STATE_BUSY) {
// if busy retry again later // if busy retry again later
ConditionVariableEntry<vm_page> entry; ConditionVariableEntry entry;
entry.Add(page); entry.Add(page);
mutex_unlock(&cache->lock); mutex_unlock(&cache->lock);
entry.Wait(); entry.Wait();
+52 -54
View File
@@ -22,16 +22,15 @@ static const int kConditionVariableHashSize = 512;
struct ConditionVariableHashDefinition { struct ConditionVariableHashDefinition {
typedef const void* KeyType; typedef const void* KeyType;
typedef PrivateConditionVariable ValueType; typedef ConditionVariable ValueType;
size_t HashKey(const void* key) const size_t HashKey(const void* key) const
{ return (size_t)key; } { return (size_t)key; }
size_t Hash(PrivateConditionVariable* variable) const size_t Hash(ConditionVariable* variable) const
{ return (size_t)variable->fObject; } { return (size_t)variable->fObject; }
bool Compare(const void* key, PrivateConditionVariable* variable) const bool Compare(const void* key, ConditionVariable* variable) const
{ return key == variable->fObject; } { return key == variable->fObject; }
HashTableLink<PrivateConditionVariable>* GetLink( HashTableLink<ConditionVariable>* GetLink(ConditionVariable* variable) const
PrivateConditionVariable* variable) const
{ return variable; } { return variable; }
}; };
@@ -43,7 +42,7 @@ static spinlock sConditionVariablesLock;
static int static int
list_condition_variables(int argc, char** argv) list_condition_variables(int argc, char** argv)
{ {
PrivateConditionVariable::ListAll(); ConditionVariable::ListAll();
return 0; return 0;
} }
@@ -60,14 +59,13 @@ dump_condition_variable(int argc, char** argv)
if (address == 0) if (address == 0)
return 0; return 0;
PrivateConditionVariable* variable = sConditionVariableHash.Lookup( ConditionVariable* variable = sConditionVariableHash.Lookup((void*)address);
(void*)address);
if (variable == NULL) { if (variable == NULL) {
// It might be a direct pointer to a condition variable. Search the // It might be a direct pointer to a condition variable. Search the
// hash. // hash.
ConditionVariableHash::Iterator it(&sConditionVariableHash); ConditionVariableHash::Iterator it(&sConditionVariableHash);
while (PrivateConditionVariable* hashVariable = it.Next()) { while (ConditionVariable* hashVariable = it.Next()) {
if (hashVariable == (void*)address) { if (hashVariable == (void*)address) {
variable = hashVariable; variable = hashVariable;
break; break;
@@ -88,11 +86,11 @@ dump_condition_variable(int argc, char** argv)
} }
// #pragma mark - PrivateConditionVariableEntry // #pragma mark - ConditionVariableEntry
bool bool
PrivateConditionVariableEntry::Add(const void* object, uint32 flags) ConditionVariableEntry::Add(const void* object, uint32 flags)
{ {
ASSERT(object != NULL); ASSERT(object != NULL);
@@ -121,7 +119,7 @@ PrivateConditionVariableEntry::Add(const void* object, uint32 flags)
status_t status_t
PrivateConditionVariableEntry::Wait() ConditionVariableEntry::Wait()
{ {
if (!are_interrupts_enabled()) { if (!are_interrupts_enabled()) {
panic("wait_for_condition_variable_entry() called with interrupts " panic("wait_for_condition_variable_entry() called with interrupts "
@@ -148,7 +146,7 @@ PrivateConditionVariableEntry::Wait()
status_t status_t
PrivateConditionVariableEntry::Wait(const void* object, uint32 flags) ConditionVariableEntry::Wait(const void* object, uint32 flags)
{ {
if (Add(object, flags)) if (Add(object, flags))
return Wait(); return Wait();
@@ -156,42 +154,11 @@ PrivateConditionVariableEntry::Wait(const void* object, uint32 flags)
} }
// #pragma mark - PrivateConditionVariable // #pragma mark - ConditionVariable
/*static*/ void
PrivateConditionVariable::ListAll()
{
kprintf(" variable object (type) waiting threads\n");
kprintf("------------------------------------------------------------\n");
ConditionVariableHash::Iterator it(&sConditionVariableHash);
while (PrivateConditionVariable* variable = it.Next()) {
// count waiting threads
int count = variable->fEntries.Size();
kprintf("%p %p %-20s %15d\n", variable, variable->fObject,
variable->fObjectType, count);
}
}
void void
PrivateConditionVariable::Dump() const ConditionVariable::Publish(const void* object, const char* objectType)
{
kprintf("condition variable %p\n", this);
kprintf(" object: %p (%s)\n", fObject, fObjectType);
kprintf(" threads:");
for (EntryList::ConstIterator it = fEntries.GetIterator();
PrivateConditionVariableEntry* entry = it.Next();) {
kprintf(" %ld", entry->fThread->id);
}
kprintf("\n");
}
void
PrivateConditionVariable::Publish(const void* object, const char* objectType)
{ {
ASSERT(object != NULL); ASSERT(object != NULL);
@@ -210,7 +177,7 @@ PrivateConditionVariable::Publish(const void* object, const char* objectType)
void void
PrivateConditionVariable::Unpublish(bool threadsLocked) ConditionVariable::Unpublish(bool threadsLocked)
{ {
ASSERT(fObject != NULL); ASSERT(fObject != NULL);
@@ -219,7 +186,7 @@ PrivateConditionVariable::Unpublish(bool threadsLocked)
SpinLocker locker(sConditionVariablesLock); SpinLocker locker(sConditionVariablesLock);
#if KDEBUG #if KDEBUG
PrivateConditionVariable* variable = sConditionVariableHash.Lookup(fObject); ConditionVariable* variable = sConditionVariableHash.Lookup(fObject);
if (variable != this) { if (variable != this) {
panic("Condition variable %p not published, found: %p", this, variable); panic("Condition variable %p not published, found: %p", this, variable);
return; return;
@@ -231,12 +198,43 @@ PrivateConditionVariable::Unpublish(bool threadsLocked)
fObjectType = NULL; fObjectType = NULL;
if (!fEntries.IsEmpty()) if (!fEntries.IsEmpty())
_Notify(true, B_ENTRY_NOT_FOUND); _NotifyChecked(true, B_ENTRY_NOT_FOUND);
}
/*static*/ void
ConditionVariable::ListAll()
{
kprintf(" variable object (type) waiting threads\n");
kprintf("------------------------------------------------------------\n");
ConditionVariableHash::Iterator it(&sConditionVariableHash);
while (ConditionVariable* variable = it.Next()) {
// count waiting threads
int count = variable->fEntries.Size();
kprintf("%p %p %-20s %15d\n", variable, variable->fObject,
variable->fObjectType, count);
}
} }
void void
PrivateConditionVariable::Notify(bool all, bool threadsLocked) ConditionVariable::Dump() const
{
kprintf("condition variable %p\n", this);
kprintf(" object: %p (%s)\n", fObject, fObjectType);
kprintf(" threads:");
for (EntryList::ConstIterator it = fEntries.GetIterator();
ConditionVariableEntry* entry = it.Next();) {
kprintf(" %ld", entry->fThread->id);
}
kprintf("\n");
}
void
ConditionVariable::_Notify(bool all, bool threadsLocked)
{ {
ASSERT(fObject != NULL); ASSERT(fObject != NULL);
@@ -245,7 +243,7 @@ PrivateConditionVariable::Notify(bool all, bool threadsLocked)
SpinLocker locker(sConditionVariablesLock); SpinLocker locker(sConditionVariablesLock);
#if KDEBUG #if KDEBUG
PrivateConditionVariable* variable = sConditionVariableHash.Lookup(fObject); ConditionVariable* variable = sConditionVariableHash.Lookup(fObject);
if (variable != this) { if (variable != this) {
panic("Condition variable %p not published, found: %p", this, variable); panic("Condition variable %p not published, found: %p", this, variable);
return; return;
@@ -253,7 +251,7 @@ PrivateConditionVariable::Notify(bool all, bool threadsLocked)
#endif #endif
if (!fEntries.IsEmpty()) if (!fEntries.IsEmpty())
_Notify(all, B_OK); _NotifyChecked(all, B_OK);
} }
@@ -261,10 +259,10 @@ PrivateConditionVariable::Notify(bool all, bool threadsLocked)
thread lock held. thread lock held.
*/ */
void void
PrivateConditionVariable::_Notify(bool all, status_t result) ConditionVariable::_NotifyChecked(bool all, status_t result)
{ {
// dequeue and wake up the blocked threads // dequeue and wake up the blocked threads
while (PrivateConditionVariableEntry* entry = fEntries.RemoveHead()) { while (ConditionVariableEntry* entry = fEntries.RemoveHead()) {
entry->fVariable = NULL; entry->fVariable = NULL;
thread_unblock_locked(entry->fThread, B_OK); thread_unblock_locked(entry->fThread, B_OK);
+6 -6
View File
@@ -84,10 +84,10 @@ class ReadRequest : public DoublyLinkedListLinkImpl<ReadRequest> {
} }
} }
ConditionVariable<>& WaitCondition() { return fWaitCondition; } ConditionVariable& WaitCondition() { return fWaitCondition; }
private: private:
ConditionVariable<> fWaitCondition; ConditionVariable fWaitCondition;
bool fNotified; bool fNotified;
}; };
@@ -167,7 +167,7 @@ class Inode {
benaphore fRequestLock; benaphore fRequestLock;
ConditionVariable<> fWriteCondition; ConditionVariable fWriteCondition;
int32 fReaderCount; int32 fReaderCount;
int32 fWriterCount; int32 fWriterCount;
@@ -358,7 +358,7 @@ Inode::WriteDataToBuffer(const void *_data, size_t *_length, bool nonBlocking)
if (nonBlocking) if (nonBlocking)
return B_WOULD_BLOCK; return B_WOULD_BLOCK;
ConditionVariableEntry<> entry; ConditionVariableEntry entry;
entry.Add(this, B_CAN_INTERRUPT); entry.Add(this, B_CAN_INTERRUPT);
WriteRequest request(minToWrite); WriteRequest request(minToWrite);
@@ -468,11 +468,11 @@ Inode::WaitForReadRequest(ReadRequest &request)
request.SetUnnotified(); request.SetUnnotified();
// publish the condition variable // publish the condition variable
ConditionVariable<>& conditionVariable = request.WaitCondition(); ConditionVariable& conditionVariable = request.WaitCondition();
conditionVariable.Publish(&request, "pipe request"); conditionVariable.Publish(&request, "pipe request");
// add the entry to wait on // add the entry to wait on
ConditionVariableEntry<> entry; ConditionVariableEntry entry;
entry.Add(&request, B_CAN_INTERRUPT); entry.Add(&request, B_CAN_INTERRUPT);
// wait // wait
+10 -27
View File
@@ -15,7 +15,6 @@
#include <OS.h> #include <OS.h>
#include <KernelExport.h> #include <KernelExport.h>
#include <condition_variable.h>
#include <debug.h> #include <debug.h>
#include <kernel.h> #include <kernel.h>
#include <kscheduler.h> #include <kscheduler.h>
@@ -786,22 +785,14 @@ int
sigwait(const sigset_t *set, int *_signal) sigwait(const sigset_t *set, int *_signal)
{ {
struct thread *thread = thread_get_current_thread(); struct thread *thread = thread_get_current_thread();
int signalsPending = 0;
ConditionVariable<sigset_t> conditionVar; while (!has_signals_pending(thread)) {
conditionVar.Publish(set, "sigwait"); thread_prepare_to_block(thread, B_CAN_INTERRUPT,
THREAD_BLOCK_TYPE_SIGNAL, NULL);
while (true) { thread_block();
ConditionVariableEntry<sigset_t> entry;
entry.Wait(set, B_CAN_INTERRUPT);
if (has_signals_pending(thread)) {
signalsPending = atomic_get(&thread->sig_pending) & *set;
break;
}
} }
conditionVar.Unpublish(); int signalsPending = atomic_get(&thread->sig_pending) & *set;
update_current_thread_signals_flag(); update_current_thread_signals_flag();
@@ -828,24 +819,16 @@ sigsuspend(const sigset_t *mask)
struct thread *thread = thread_get_current_thread(); struct thread *thread = thread_get_current_thread();
sigset_t oldMask = atomic_get(&thread->sig_block_mask); sigset_t oldMask = atomic_get(&thread->sig_block_mask);
// Set the new block mask and interuptably block wait for a condition // Set the new block mask and block until interrupted.
// variable no one will ever notify.
atomic_set(&thread->sig_block_mask, *mask & BLOCKABLE_SIGNALS); atomic_set(&thread->sig_block_mask, *mask & BLOCKABLE_SIGNALS);
ConditionVariable<sigset_t> conditionVar; while (!has_signals_pending(thread)) {
conditionVar.Publish(mask, "sigsuspend"); thread_prepare_to_block(thread, B_CAN_INTERRUPT,
THREAD_BLOCK_TYPE_SIGNAL, NULL);
while (true) { thread_block();
ConditionVariableEntry<sigset_t> entry;
entry.Wait(mask, B_CAN_INTERRUPT);
if (has_signals_pending(thread))
break;
} }
conditionVar.Unpublish();
// restore the original block mask // restore the original block mask
atomic_set(&thread->sig_block_mask, oldMask); atomic_set(&thread->sig_block_mask, oldMask);
+2 -2
View File
@@ -1740,9 +1740,9 @@ wait_for_child(pid_t child, uint32 flags, int32 *_reason,
} }
} }
// If we haven't got anything yet, add prepare for waiting for the // If we haven't got anything yet, prepare for waiting for the
// condition variable. // condition variable.
ConditionVariableEntry<team_dead_children> deadWaitEntry; ConditionVariableEntry deadWaitEntry;
if (status == B_WOULD_BLOCK && (flags & WNOHANG) == 0) if (status == B_WOULD_BLOCK && (flags & WNOHANG) == 0)
deadWaitEntry.Add(team->dead_children, B_CAN_INTERRUPT); deadWaitEntry.Add(team->dead_children, B_CAN_INTERRUPT);
+2 -2
View File
@@ -666,12 +666,12 @@ get_thread_wait_sem(struct thread* thread)
} }
static PrivateConditionVariable* static ConditionVariable*
get_thread_wait_cvar(struct thread* thread) get_thread_wait_cvar(struct thread* thread)
{ {
if (thread->state == B_THREAD_WAITING if (thread->state == B_THREAD_WAITING
&& thread->wait.type == THREAD_BLOCK_TYPE_CONDITION_VARIABLE) { && thread->wait.type == THREAD_BLOCK_TYPE_CONDITION_VARIABLE) {
return (PrivateConditionVariable*)thread->wait.object; return (ConditionVariable*)thread->wait.object;
} }
return NULL; return NULL;
} }
+6 -6
View File
@@ -3952,7 +3952,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
// page must be busy -- wait for it to become unbusy // page must be busy -- wait for it to become unbusy
{ {
ConditionVariableEntry<vm_page> entry; ConditionVariableEntry entry;
entry.Add(page); entry.Add(page);
mutex_unlock(&cache->lock); mutex_unlock(&cache->lock);
entry.Wait(); entry.Wait();
@@ -3963,7 +3963,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
// 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<vm_cache> entry; ConditionVariableEntry entry;
entry.Add(cache); entry.Add(cache);
mutex_unlock(&cache->lock); mutex_unlock(&cache->lock);
vm_cache_release_ref(cache); vm_cache_release_ref(cache);
@@ -3986,7 +3986,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
page = vm_page_allocate_page(PAGE_STATE_FREE, true); page = vm_page_allocate_page(PAGE_STATE_FREE, true);
vm_cache_insert_page(cache, page, cacheOffset); vm_cache_insert_page(cache, page, cacheOffset);
ConditionVariable<vm_page> busyCondition; ConditionVariable busyCondition;
busyCondition.Publish(page, "page"); busyCondition.Publish(page, "page");
mutex_unlock(&cache->lock); mutex_unlock(&cache->lock);
@@ -4045,7 +4045,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
// 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<vm_cache> entry; ConditionVariableEntry entry;
entry.Add(cache); entry.Add(cache);
mutex_unlock(&cache->lock); mutex_unlock(&cache->lock);
vm_cache_release_ref(cache); vm_cache_release_ref(cache);
@@ -4079,7 +4079,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
// 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<vm_cache> entry; ConditionVariableEntry entry;
entry.Add(cache); entry.Add(cache);
mutex_unlock(&cache->lock); mutex_unlock(&cache->lock);
vm_cache_release_ref(cache); vm_cache_release_ref(cache);
@@ -4249,7 +4249,7 @@ if (cacheOffset == 0x12000)
break; break;
// The page is busy, wait till it becomes unbusy. // The page is busy, wait till it becomes unbusy.
ConditionVariableEntry<vm_page> entry; ConditionVariableEntry entry;
entry.Add(newPage); entry.Add(newPage);
mutex_unlock(&topCache->lock); mutex_unlock(&topCache->lock);
entry.Wait(); entry.Wait();
+2 -2
View File
@@ -507,7 +507,7 @@ vm_cache_resize(vm_cache* cache, off_t newSize)
page = next; page = next;
} else { } else {
// wait for page to become unbusy // wait for page to become unbusy
ConditionVariableEntry<vm_page> entry; ConditionVariableEntry entry;
entry.Add(page); entry.Add(page);
mutex_unlock(&cache->lock); mutex_unlock(&cache->lock);
entry.Wait(); entry.Wait();
@@ -569,7 +569,7 @@ vm_cache_remove_consumer(vm_cache* cache, vm_cache* consumer)
// to, so we need to check if this cache is really the last // to, so we need to check if this cache is really the last
// consumer of the cache we want to merge it with. // consumer of the cache we want to merge it with.
ConditionVariable<vm_cache> busyCondition; ConditionVariable busyCondition;
if (merge) { if (merge) {
// But since we need to keep the locking order upper->lower cache, we // But since we need to keep the locking order upper->lower cache, we
+6 -6
View File
@@ -60,7 +60,7 @@ static size_t sReservedPages;
static vint32 sPageDeficit; static vint32 sPageDeficit;
static size_t sModifiedTemporaryPages; static size_t sModifiedTemporaryPages;
static ConditionVariable<page_queue> sFreePageCondition; static ConditionVariable sFreePageCondition;
static spinlock sPageLock; static spinlock sPageLock;
static sem_id sWriterWaitSem; static sem_id sWriterWaitSem;
@@ -966,7 +966,7 @@ page_writer(void* /*unused*/)
} }
const uint32 kNumPages = 32; const uint32 kNumPages = 32;
ConditionVariable<vm_page> busyConditions[kNumPages]; ConditionVariable busyConditions[kNumPages];
union { union {
vm_page *pages[kNumPages]; vm_page *pages[kNumPages];
vm_cache *caches[kNumPages]; vm_cache *caches[kNumPages];
@@ -1278,7 +1278,7 @@ steal_pages(vm_page **pages, size_t count, bool reserve)
// we need to wait for pages to become inactive // we need to wait for pages to become inactive
ConditionVariableEntry<page_queue> freeConditionEntry; ConditionVariableEntry freeConditionEntry;
sPageDeficit++; sPageDeficit++;
freeConditionEntry.Add(&sFreePageQueue); freeConditionEntry.Add(&sFreePageQueue);
locker.Unlock(); locker.Unlock();
@@ -1324,7 +1324,7 @@ vm_page_write_modified_pages(vm_cache *cache, bool fsReenter)
page->state = PAGE_STATE_BUSY; page->state = PAGE_STATE_BUSY;
page->busy_writing = true; page->busy_writing = true;
ConditionVariable<vm_page> busyCondition; ConditionVariable busyCondition;
busyCondition.Publish(page, "page"); busyCondition.Publish(page, "page");
// We have a modified page - however, while we're writing it back, // We have a modified page - however, while we're writing it back,
@@ -1482,7 +1482,7 @@ vm_page_init_post_area(kernel_args *args)
status_t status_t
vm_page_init_post_thread(kernel_args *args) vm_page_init_post_thread(kernel_args *args)
{ {
new (&sFreePageCondition) ConditionVariable<page_queue>; new (&sFreePageCondition) ConditionVariable;
sFreePageCondition.Publish(&sFreePageQueue, "free page"); sFreePageCondition.Publish(&sFreePageQueue, "free page");
// create a kernel thread to clear out pages // create a kernel thread to clear out pages
@@ -1613,7 +1613,7 @@ vm_page_reserve_pages(uint32 count)
vm_page * vm_page *
vm_page_allocate_page(int pageState, bool reserved) vm_page_allocate_page(int pageState, bool reserved)
{ {
ConditionVariableEntry<page_queue> freeConditionEntry; ConditionVariableEntry freeConditionEntry;
page_queue *queue; page_queue *queue;
page_queue *otherQueue; page_queue *otherQueue;