* 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:
@@ -16,152 +16,98 @@
|
||||
#include <util/OpenHashTable.h>
|
||||
|
||||
|
||||
class PrivateConditionVariable;
|
||||
class ConditionVariable;
|
||||
|
||||
|
||||
struct PrivateConditionVariableEntry
|
||||
: DoublyLinkedListLinkImpl<PrivateConditionVariableEntry> {
|
||||
struct ConditionVariableEntry
|
||||
: DoublyLinkedListLinkImpl<ConditionVariableEntry> {
|
||||
public:
|
||||
#if KDEBUG
|
||||
inline PrivateConditionVariableEntry()
|
||||
: fVariable(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
inline ~PrivateConditionVariableEntry()
|
||||
{
|
||||
if (fVariable != NULL) {
|
||||
panic("Destroying condition variable entry %p, but it's still "
|
||||
"attached to variable %p\n", this, fVariable);
|
||||
}
|
||||
}
|
||||
inline ConditionVariableEntry();
|
||||
inline ~ConditionVariableEntry();
|
||||
#endif
|
||||
|
||||
inline PrivateConditionVariable* Variable() const
|
||||
{ return fVariable; }
|
||||
|
||||
protected:
|
||||
bool Add(const void* object, uint32 flags);
|
||||
bool Add(const void* object, uint32 flags = 0);
|
||||
status_t Wait();
|
||||
status_t Wait(const void* object, uint32 flags);
|
||||
status_t Wait(const void* object, uint32 flags = 0);
|
||||
|
||||
protected:
|
||||
PrivateConditionVariable* fVariable;
|
||||
inline ConditionVariable* Variable() const { return fVariable; }
|
||||
|
||||
private:
|
||||
ConditionVariable* fVariable;
|
||||
struct thread* fThread;
|
||||
|
||||
friend class PrivateConditionVariable;
|
||||
friend class ConditionVariable;
|
||||
};
|
||||
|
||||
|
||||
class PrivateConditionVariable
|
||||
: protected HashTableLink<PrivateConditionVariable> {
|
||||
class ConditionVariable : protected HashTableLink<ConditionVariable> {
|
||||
public:
|
||||
static void ListAll();
|
||||
void Dump() const;
|
||||
const void* Object() const { return fObject; }
|
||||
protected:
|
||||
void Publish(const void* object,
|
||||
const char* objectType);
|
||||
void Unpublish(bool threadsLocked);
|
||||
void Notify(bool all, bool threadsLocked);
|
||||
void Unpublish(bool threadsLocked = false);
|
||||
|
||||
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:
|
||||
void _Notify(bool all, status_t result);
|
||||
void _Notify(bool all, bool threadsLocked);
|
||||
void _NotifyChecked(bool all, status_t result);
|
||||
|
||||
protected:
|
||||
typedef DoublyLinkedList<PrivateConditionVariableEntry> EntryList;
|
||||
typedef DoublyLinkedList<ConditionVariableEntry> EntryList;
|
||||
|
||||
const void* fObject;
|
||||
const char* fObjectType;
|
||||
EntryList fEntries;
|
||||
|
||||
friend class PrivateConditionVariableEntry;
|
||||
friend class ConditionVariableEntry;
|
||||
friend class ConditionVariableHashDefinition;
|
||||
};
|
||||
|
||||
|
||||
template<typename Type = void>
|
||||
class ConditionVariable : private PrivateConditionVariable {
|
||||
public:
|
||||
inline void Publish(const Type* object,
|
||||
const char* objectType);
|
||||
#if KDEBUG
|
||||
|
||||
inline void Unpublish(bool threadsLocked = false);
|
||||
inline void NotifyOne(bool threadsLocked = false);
|
||||
inline void NotifyAll(bool threadsLocked = false);
|
||||
};
|
||||
inline
|
||||
ConditionVariableEntry::ConditionVariableEntry()
|
||||
: 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
|
||||
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
|
||||
ConditionVariable<Type>::Unpublish(bool threadsLocked)
|
||||
ConditionVariable::NotifyAll(bool threadsLocked)
|
||||
{
|
||||
PrivateConditionVariable::Unpublish(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);
|
||||
_Notify(true, threadsLocked);
|
||||
}
|
||||
|
||||
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
struct thread;
|
||||
|
||||
extern void condition_variable_init();
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -61,6 +61,7 @@ enum {
|
||||
THREAD_BLOCK_TYPE_SEMAPHORE = 0,
|
||||
THREAD_BLOCK_TYPE_CONDITION_VARIABLE = 1,
|
||||
THREAD_BLOCK_TYPE_SNOOZE = 2,
|
||||
THREAD_BLOCK_TYPE_SIGNAL = 3,
|
||||
THREAD_BLOCK_TYPE_USER_BASE = 10000
|
||||
};
|
||||
|
||||
@@ -151,10 +152,10 @@ struct team_job_control_children {
|
||||
};
|
||||
|
||||
struct team_dead_children : team_job_control_children {
|
||||
ConditionVariable<team_dead_children> condition_variable;
|
||||
uint32 count;
|
||||
bigtime_t kernel_time;
|
||||
bigtime_t user_time;
|
||||
ConditionVariable condition_variable;
|
||||
uint32 count;
|
||||
bigtime_t kernel_time;
|
||||
bigtime_t user_time;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ enum {
|
||||
};
|
||||
|
||||
struct vm_dummy_page : vm_page {
|
||||
ConditionVariable<vm_page> busy_condition;
|
||||
ConditionVariable busy_condition;
|
||||
};
|
||||
|
||||
struct vm_cache {
|
||||
|
||||
@@ -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.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
@@ -402,12 +402,12 @@ RequestOwner::Wait(bool interruptable)
|
||||
// not yet done
|
||||
|
||||
// publish the condition variable
|
||||
ConditionVariable<> conditionVariable;
|
||||
ConditionVariable conditionVariable;
|
||||
conditionVariable.Publish(this, "tty request");
|
||||
fConditionVariable = &conditionVariable;
|
||||
|
||||
// add an entry to wait on
|
||||
ConditionVariableEntry<> entry;
|
||||
ConditionVariableEntry entry;
|
||||
entry.Add(this, interruptable ? B_CAN_INTERRUPT : 0);
|
||||
|
||||
locker.Unlock();
|
||||
|
||||
@@ -101,7 +101,7 @@ class RequestOwner {
|
||||
status_t Error() const { return fError; }
|
||||
|
||||
private:
|
||||
ConditionVariable<>* fConditionVariable;
|
||||
ConditionVariable* fConditionVariable;
|
||||
tty_cookie* fCookie;
|
||||
status_t fError;
|
||||
RequestQueue* fRequestQueues[2];
|
||||
|
||||
+2
-2
@@ -114,7 +114,7 @@ struct block_cache : DoublyLinkedListLinkImpl<block_cache> {
|
||||
bool read_only;
|
||||
|
||||
NotificationList pending_notifications;
|
||||
ConditionVariable<block_cache> condition_variable;
|
||||
ConditionVariable condition_variable;
|
||||
bool deleting;
|
||||
|
||||
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,
|
||||
cache);
|
||||
|
||||
ConditionVariableEntry<block_cache> entry;
|
||||
ConditionVariableEntry entry;
|
||||
entry.Add(cache);
|
||||
|
||||
add_notification(cache, ¬ification, TRANSACTION_WRITTEN, false);
|
||||
|
||||
+4
-4
@@ -184,7 +184,7 @@ read_into_cache(file_cache_ref *ref, void *cookie, off_t offset,
|
||||
|
||||
size_t numBytes = PAGE_ALIGN(pageOffset + bufferSize);
|
||||
vm_page *pages[MAX_IO_VECS];
|
||||
ConditionVariable<vm_page> busyConditions[MAX_IO_VECS];
|
||||
ConditionVariable busyConditions[MAX_IO_VECS];
|
||||
int32 pageIndex = 0;
|
||||
|
||||
// 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];
|
||||
int32 pageIndex = 0;
|
||||
status_t status = B_OK;
|
||||
ConditionVariable<vm_page> busyConditions[MAX_IO_VECS];
|
||||
ConditionVariable busyConditions[MAX_IO_VECS];
|
||||
|
||||
// ToDo: this should be settable somewhere
|
||||
bool writeThrough = false;
|
||||
@@ -622,7 +622,7 @@ cache_io(void *_cacheRef, void *cookie, off_t offset, addr_t buffer,
|
||||
return status;
|
||||
|
||||
if (page->state == PAGE_STATE_BUSY) {
|
||||
ConditionVariableEntry<vm_page> entry;
|
||||
ConditionVariableEntry entry;
|
||||
entry.Add(page);
|
||||
locker.Unlock();
|
||||
entry.Wait();
|
||||
@@ -790,7 +790,7 @@ cache_prefetch_vnode(struct vnode *vnode, off_t offset, size_t size)
|
||||
if (page != NULL) {
|
||||
if (page->state == PAGE_STATE_BUSY) {
|
||||
// if busy retry again later
|
||||
ConditionVariableEntry<vm_page> entry;
|
||||
ConditionVariableEntry entry;
|
||||
entry.Add(page);
|
||||
mutex_unlock(&cache->lock);
|
||||
entry.Wait();
|
||||
|
||||
@@ -22,16 +22,15 @@ static const int kConditionVariableHashSize = 512;
|
||||
|
||||
struct ConditionVariableHashDefinition {
|
||||
typedef const void* KeyType;
|
||||
typedef PrivateConditionVariable ValueType;
|
||||
typedef ConditionVariable ValueType;
|
||||
|
||||
size_t HashKey(const void* key) const
|
||||
{ return (size_t)key; }
|
||||
size_t Hash(PrivateConditionVariable* variable) const
|
||||
size_t Hash(ConditionVariable* variable) const
|
||||
{ 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; }
|
||||
HashTableLink<PrivateConditionVariable>* GetLink(
|
||||
PrivateConditionVariable* variable) const
|
||||
HashTableLink<ConditionVariable>* GetLink(ConditionVariable* variable) const
|
||||
{ return variable; }
|
||||
};
|
||||
|
||||
@@ -43,7 +42,7 @@ static spinlock sConditionVariablesLock;
|
||||
static int
|
||||
list_condition_variables(int argc, char** argv)
|
||||
{
|
||||
PrivateConditionVariable::ListAll();
|
||||
ConditionVariable::ListAll();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -60,14 +59,13 @@ dump_condition_variable(int argc, char** argv)
|
||||
if (address == 0)
|
||||
return 0;
|
||||
|
||||
PrivateConditionVariable* variable = sConditionVariableHash.Lookup(
|
||||
(void*)address);
|
||||
ConditionVariable* variable = sConditionVariableHash.Lookup((void*)address);
|
||||
|
||||
if (variable == NULL) {
|
||||
// It might be a direct pointer to a condition variable. Search the
|
||||
// hash.
|
||||
ConditionVariableHash::Iterator it(&sConditionVariableHash);
|
||||
while (PrivateConditionVariable* hashVariable = it.Next()) {
|
||||
while (ConditionVariable* hashVariable = it.Next()) {
|
||||
if (hashVariable == (void*)address) {
|
||||
variable = hashVariable;
|
||||
break;
|
||||
@@ -88,11 +86,11 @@ dump_condition_variable(int argc, char** argv)
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - PrivateConditionVariableEntry
|
||||
// #pragma mark - ConditionVariableEntry
|
||||
|
||||
|
||||
bool
|
||||
PrivateConditionVariableEntry::Add(const void* object, uint32 flags)
|
||||
ConditionVariableEntry::Add(const void* object, uint32 flags)
|
||||
{
|
||||
ASSERT(object != NULL);
|
||||
|
||||
@@ -121,7 +119,7 @@ PrivateConditionVariableEntry::Add(const void* object, uint32 flags)
|
||||
|
||||
|
||||
status_t
|
||||
PrivateConditionVariableEntry::Wait()
|
||||
ConditionVariableEntry::Wait()
|
||||
{
|
||||
if (!are_interrupts_enabled()) {
|
||||
panic("wait_for_condition_variable_entry() called with interrupts "
|
||||
@@ -148,7 +146,7 @@ PrivateConditionVariableEntry::Wait()
|
||||
|
||||
|
||||
status_t
|
||||
PrivateConditionVariableEntry::Wait(const void* object, uint32 flags)
|
||||
ConditionVariableEntry::Wait(const void* object, uint32 flags)
|
||||
{
|
||||
if (Add(object, flags))
|
||||
return Wait();
|
||||
@@ -156,42 +154,11 @@ PrivateConditionVariableEntry::Wait(const void* object, uint32 flags)
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - PrivateConditionVariable
|
||||
|
||||
|
||||
/*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);
|
||||
}
|
||||
}
|
||||
// #pragma mark - ConditionVariable
|
||||
|
||||
|
||||
void
|
||||
PrivateConditionVariable::Dump() const
|
||||
{
|
||||
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)
|
||||
ConditionVariable::Publish(const void* object, const char* objectType)
|
||||
{
|
||||
ASSERT(object != NULL);
|
||||
|
||||
@@ -210,7 +177,7 @@ PrivateConditionVariable::Publish(const void* object, const char* objectType)
|
||||
|
||||
|
||||
void
|
||||
PrivateConditionVariable::Unpublish(bool threadsLocked)
|
||||
ConditionVariable::Unpublish(bool threadsLocked)
|
||||
{
|
||||
ASSERT(fObject != NULL);
|
||||
|
||||
@@ -219,7 +186,7 @@ PrivateConditionVariable::Unpublish(bool threadsLocked)
|
||||
SpinLocker locker(sConditionVariablesLock);
|
||||
|
||||
#if KDEBUG
|
||||
PrivateConditionVariable* variable = sConditionVariableHash.Lookup(fObject);
|
||||
ConditionVariable* variable = sConditionVariableHash.Lookup(fObject);
|
||||
if (variable != this) {
|
||||
panic("Condition variable %p not published, found: %p", this, variable);
|
||||
return;
|
||||
@@ -231,12 +198,43 @@ PrivateConditionVariable::Unpublish(bool threadsLocked)
|
||||
fObjectType = NULL;
|
||||
|
||||
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
|
||||
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);
|
||||
|
||||
@@ -245,7 +243,7 @@ PrivateConditionVariable::Notify(bool all, bool threadsLocked)
|
||||
SpinLocker locker(sConditionVariablesLock);
|
||||
|
||||
#if KDEBUG
|
||||
PrivateConditionVariable* variable = sConditionVariableHash.Lookup(fObject);
|
||||
ConditionVariable* variable = sConditionVariableHash.Lookup(fObject);
|
||||
if (variable != this) {
|
||||
panic("Condition variable %p not published, found: %p", this, variable);
|
||||
return;
|
||||
@@ -253,7 +251,7 @@ PrivateConditionVariable::Notify(bool all, bool threadsLocked)
|
||||
#endif
|
||||
|
||||
if (!fEntries.IsEmpty())
|
||||
_Notify(all, B_OK);
|
||||
_NotifyChecked(all, B_OK);
|
||||
}
|
||||
|
||||
|
||||
@@ -261,10 +259,10 @@ PrivateConditionVariable::Notify(bool all, bool threadsLocked)
|
||||
thread lock held.
|
||||
*/
|
||||
void
|
||||
PrivateConditionVariable::_Notify(bool all, status_t result)
|
||||
ConditionVariable::_NotifyChecked(bool all, status_t result)
|
||||
{
|
||||
// dequeue and wake up the blocked threads
|
||||
while (PrivateConditionVariableEntry* entry = fEntries.RemoveHead()) {
|
||||
while (ConditionVariableEntry* entry = fEntries.RemoveHead()) {
|
||||
entry->fVariable = NULL;
|
||||
|
||||
thread_unblock_locked(entry->fThread, B_OK);
|
||||
|
||||
@@ -84,10 +84,10 @@ class ReadRequest : public DoublyLinkedListLinkImpl<ReadRequest> {
|
||||
}
|
||||
}
|
||||
|
||||
ConditionVariable<>& WaitCondition() { return fWaitCondition; }
|
||||
ConditionVariable& WaitCondition() { return fWaitCondition; }
|
||||
|
||||
private:
|
||||
ConditionVariable<> fWaitCondition;
|
||||
ConditionVariable fWaitCondition;
|
||||
bool fNotified;
|
||||
};
|
||||
|
||||
@@ -167,7 +167,7 @@ class Inode {
|
||||
|
||||
benaphore fRequestLock;
|
||||
|
||||
ConditionVariable<> fWriteCondition;
|
||||
ConditionVariable fWriteCondition;
|
||||
|
||||
int32 fReaderCount;
|
||||
int32 fWriterCount;
|
||||
@@ -358,7 +358,7 @@ Inode::WriteDataToBuffer(const void *_data, size_t *_length, bool nonBlocking)
|
||||
if (nonBlocking)
|
||||
return B_WOULD_BLOCK;
|
||||
|
||||
ConditionVariableEntry<> entry;
|
||||
ConditionVariableEntry entry;
|
||||
entry.Add(this, B_CAN_INTERRUPT);
|
||||
|
||||
WriteRequest request(minToWrite);
|
||||
@@ -468,11 +468,11 @@ Inode::WaitForReadRequest(ReadRequest &request)
|
||||
request.SetUnnotified();
|
||||
|
||||
// publish the condition variable
|
||||
ConditionVariable<>& conditionVariable = request.WaitCondition();
|
||||
ConditionVariable& conditionVariable = request.WaitCondition();
|
||||
conditionVariable.Publish(&request, "pipe request");
|
||||
|
||||
// add the entry to wait on
|
||||
ConditionVariableEntry<> entry;
|
||||
ConditionVariableEntry entry;
|
||||
entry.Add(&request, B_CAN_INTERRUPT);
|
||||
|
||||
// wait
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include <OS.h>
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <condition_variable.h>
|
||||
#include <debug.h>
|
||||
#include <kernel.h>
|
||||
#include <kscheduler.h>
|
||||
@@ -786,22 +785,14 @@ int
|
||||
sigwait(const sigset_t *set, int *_signal)
|
||||
{
|
||||
struct thread *thread = thread_get_current_thread();
|
||||
int signalsPending = 0;
|
||||
|
||||
ConditionVariable<sigset_t> conditionVar;
|
||||
conditionVar.Publish(set, "sigwait");
|
||||
|
||||
while (true) {
|
||||
ConditionVariableEntry<sigset_t> entry;
|
||||
entry.Wait(set, B_CAN_INTERRUPT);
|
||||
|
||||
if (has_signals_pending(thread)) {
|
||||
signalsPending = atomic_get(&thread->sig_pending) & *set;
|
||||
break;
|
||||
}
|
||||
while (!has_signals_pending(thread)) {
|
||||
thread_prepare_to_block(thread, B_CAN_INTERRUPT,
|
||||
THREAD_BLOCK_TYPE_SIGNAL, NULL);
|
||||
thread_block();
|
||||
}
|
||||
|
||||
conditionVar.Unpublish();
|
||||
int signalsPending = atomic_get(&thread->sig_pending) & *set;
|
||||
|
||||
update_current_thread_signals_flag();
|
||||
|
||||
@@ -828,24 +819,16 @@ sigsuspend(const sigset_t *mask)
|
||||
struct thread *thread = thread_get_current_thread();
|
||||
sigset_t oldMask = atomic_get(&thread->sig_block_mask);
|
||||
|
||||
// Set the new block mask and interuptably block wait for a condition
|
||||
// variable no one will ever notify.
|
||||
// Set the new block mask and block until interrupted.
|
||||
|
||||
atomic_set(&thread->sig_block_mask, *mask & BLOCKABLE_SIGNALS);
|
||||
|
||||
ConditionVariable<sigset_t> conditionVar;
|
||||
conditionVar.Publish(mask, "sigsuspend");
|
||||
|
||||
while (true) {
|
||||
ConditionVariableEntry<sigset_t> entry;
|
||||
entry.Wait(mask, B_CAN_INTERRUPT);
|
||||
|
||||
if (has_signals_pending(thread))
|
||||
break;
|
||||
while (!has_signals_pending(thread)) {
|
||||
thread_prepare_to_block(thread, B_CAN_INTERRUPT,
|
||||
THREAD_BLOCK_TYPE_SIGNAL, NULL);
|
||||
thread_block();
|
||||
}
|
||||
|
||||
conditionVar.Unpublish();
|
||||
|
||||
// restore the original block mask
|
||||
atomic_set(&thread->sig_block_mask, oldMask);
|
||||
|
||||
|
||||
@@ -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.
|
||||
ConditionVariableEntry<team_dead_children> deadWaitEntry;
|
||||
ConditionVariableEntry deadWaitEntry;
|
||||
|
||||
if (status == B_WOULD_BLOCK && (flags & WNOHANG) == 0)
|
||||
deadWaitEntry.Add(team->dead_children, B_CAN_INTERRUPT);
|
||||
|
||||
@@ -666,12 +666,12 @@ get_thread_wait_sem(struct thread* thread)
|
||||
}
|
||||
|
||||
|
||||
static PrivateConditionVariable*
|
||||
static ConditionVariable*
|
||||
get_thread_wait_cvar(struct thread* thread)
|
||||
{
|
||||
if (thread->state == B_THREAD_WAITING
|
||||
&& thread->wait.type == THREAD_BLOCK_TYPE_CONDITION_VARIABLE) {
|
||||
return (PrivateConditionVariable*)thread->wait.object;
|
||||
return (ConditionVariable*)thread->wait.object;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -3952,7 +3952,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
|
||||
|
||||
// page must be busy -- wait for it to become unbusy
|
||||
{
|
||||
ConditionVariableEntry<vm_page> entry;
|
||||
ConditionVariableEntry entry;
|
||||
entry.Add(page);
|
||||
mutex_unlock(&cache->lock);
|
||||
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
|
||||
// removed by vm_cache_remove_consumer(). We start again with
|
||||
// the top cache.
|
||||
ConditionVariableEntry<vm_cache> entry;
|
||||
ConditionVariableEntry entry;
|
||||
entry.Add(cache);
|
||||
mutex_unlock(&cache->lock);
|
||||
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);
|
||||
vm_cache_insert_page(cache, page, cacheOffset);
|
||||
|
||||
ConditionVariable<vm_page> busyCondition;
|
||||
ConditionVariable busyCondition;
|
||||
busyCondition.Publish(page, "page");
|
||||
|
||||
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
|
||||
// removed by vm_cache_remove_consumer(). We start again with
|
||||
// the top cache.
|
||||
ConditionVariableEntry<vm_cache> entry;
|
||||
ConditionVariableEntry entry;
|
||||
entry.Add(cache);
|
||||
mutex_unlock(&cache->lock);
|
||||
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
|
||||
// removed by vm_cache_remove_consumer(). We start again with
|
||||
// the top cache.
|
||||
ConditionVariableEntry<vm_cache> entry;
|
||||
ConditionVariableEntry entry;
|
||||
entry.Add(cache);
|
||||
mutex_unlock(&cache->lock);
|
||||
vm_cache_release_ref(cache);
|
||||
@@ -4249,7 +4249,7 @@ if (cacheOffset == 0x12000)
|
||||
break;
|
||||
|
||||
// The page is busy, wait till it becomes unbusy.
|
||||
ConditionVariableEntry<vm_page> entry;
|
||||
ConditionVariableEntry entry;
|
||||
entry.Add(newPage);
|
||||
mutex_unlock(&topCache->lock);
|
||||
entry.Wait();
|
||||
|
||||
@@ -507,7 +507,7 @@ vm_cache_resize(vm_cache* cache, off_t newSize)
|
||||
page = next;
|
||||
} else {
|
||||
// wait for page to become unbusy
|
||||
ConditionVariableEntry<vm_page> entry;
|
||||
ConditionVariableEntry entry;
|
||||
entry.Add(page);
|
||||
mutex_unlock(&cache->lock);
|
||||
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
|
||||
// consumer of the cache we want to merge it with.
|
||||
|
||||
ConditionVariable<vm_cache> busyCondition;
|
||||
ConditionVariable busyCondition;
|
||||
|
||||
if (merge) {
|
||||
// But since we need to keep the locking order upper->lower cache, we
|
||||
|
||||
@@ -60,7 +60,7 @@ static size_t sReservedPages;
|
||||
static vint32 sPageDeficit;
|
||||
static size_t sModifiedTemporaryPages;
|
||||
|
||||
static ConditionVariable<page_queue> sFreePageCondition;
|
||||
static ConditionVariable sFreePageCondition;
|
||||
static spinlock sPageLock;
|
||||
|
||||
static sem_id sWriterWaitSem;
|
||||
@@ -966,7 +966,7 @@ page_writer(void* /*unused*/)
|
||||
}
|
||||
|
||||
const uint32 kNumPages = 32;
|
||||
ConditionVariable<vm_page> busyConditions[kNumPages];
|
||||
ConditionVariable busyConditions[kNumPages];
|
||||
union {
|
||||
vm_page *pages[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
|
||||
|
||||
ConditionVariableEntry<page_queue> freeConditionEntry;
|
||||
ConditionVariableEntry freeConditionEntry;
|
||||
sPageDeficit++;
|
||||
freeConditionEntry.Add(&sFreePageQueue);
|
||||
locker.Unlock();
|
||||
@@ -1324,7 +1324,7 @@ vm_page_write_modified_pages(vm_cache *cache, bool fsReenter)
|
||||
page->state = PAGE_STATE_BUSY;
|
||||
page->busy_writing = true;
|
||||
|
||||
ConditionVariable<vm_page> busyCondition;
|
||||
ConditionVariable busyCondition;
|
||||
busyCondition.Publish(page, "page");
|
||||
|
||||
// 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
|
||||
vm_page_init_post_thread(kernel_args *args)
|
||||
{
|
||||
new (&sFreePageCondition) ConditionVariable<page_queue>;
|
||||
new (&sFreePageCondition) ConditionVariable;
|
||||
sFreePageCondition.Publish(&sFreePageQueue, "free page");
|
||||
|
||||
// create a kernel thread to clear out pages
|
||||
@@ -1613,7 +1613,7 @@ vm_page_reserve_pages(uint32 count)
|
||||
vm_page *
|
||||
vm_page_allocate_page(int pageState, bool reserved)
|
||||
{
|
||||
ConditionVariableEntry<page_queue> freeConditionEntry;
|
||||
ConditionVariableEntry freeConditionEntry;
|
||||
page_queue *queue;
|
||||
page_queue *otherQueue;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user