Fixed a dead-lock that could happen if an attribute was changed and you
had some running live queries. SimpleLock now allows nesting; added some missing atomic operations to make its implementation as easy as possible. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1901 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
37935f570b
commit
fb39a31ca7
@ -10,11 +10,19 @@
|
||||
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include "Utility.h"
|
||||
|
||||
|
||||
// configure here if and when real benaphores should be used
|
||||
// Configure here if and when real benaphores should be used
|
||||
// Benaphores doesn't make much sense in the kernel, so they are only
|
||||
// enabled for the user-space test application
|
||||
#ifdef USER
|
||||
# define USE_BENAPHORE 1
|
||||
# define USE_BENAPHORE
|
||||
// if defined, benaphores are used for the Semaphore class
|
||||
//# define FAST_LOCK
|
||||
// the ReadWriteLock class uses a second Semaphore to
|
||||
// speed up locking - only makes sense if USE_BENAPHORE
|
||||
// is defined, too.
|
||||
#endif
|
||||
|
||||
|
||||
@ -136,7 +144,6 @@ class Locker {
|
||||
// expensive regarding that BeOS only allows for a total of 64k
|
||||
// semaphores.
|
||||
|
||||
//#define FAST_LOCK
|
||||
#ifdef FAST_LOCK
|
||||
class ReadWriteLock {
|
||||
public:
|
||||
@ -317,35 +324,43 @@ class WriteLocked {
|
||||
|
||||
// A simple locking structure that doesn't use a semaphore - it's useful
|
||||
// if you have to protect critical parts with a short runtime.
|
||||
// It also allows to nest several locks for the same thread.
|
||||
|
||||
class SimpleLock {
|
||||
public:
|
||||
SimpleLock()
|
||||
:
|
||||
fLock(0),
|
||||
fUnlock(0)
|
||||
fHolder(-1),
|
||||
fCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
status_t Lock(bigtime_t time = 500)
|
||||
{
|
||||
int32 turn = atomic_add(&fLock,1);
|
||||
while (turn != fUnlock)
|
||||
int32 thisThread = find_thread(NULL);
|
||||
int32 current;
|
||||
while ((current = atomic_test_and_set(&fHolder, thisThread, -1)) != -1) {
|
||||
if (current == thisThread)
|
||||
break;
|
||||
|
||||
snooze(time);
|
||||
}
|
||||
|
||||
// ToDo: the lock cannot fail currently! We may want
|
||||
// to change this
|
||||
atomic_add(&fCount, 1);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
void Unlock()
|
||||
{
|
||||
atomic_add(&fUnlock,1);
|
||||
if (atomic_add(&fCount, -1) == 1)
|
||||
atomic_set(&fHolder, -1);
|
||||
}
|
||||
|
||||
private:
|
||||
vint32 fLock;
|
||||
vint32 fUnlock;
|
||||
vint32 fHolder;
|
||||
vint32 fCount;
|
||||
};
|
||||
|
||||
// A convenience class to lock the SimpleLock, note the
|
||||
|
@ -107,4 +107,31 @@ template<class Node> struct list {
|
||||
};
|
||||
|
||||
|
||||
// Some atomic operations that are somehow missing in BeOS:
|
||||
//
|
||||
// atomic_test_and_set(value, newValue, testAgainst)
|
||||
// sets "value" to "newValue", if "value" is equal to "testAgainst"
|
||||
// atomic_set(value, newValue)
|
||||
// sets "value" to "newValue"
|
||||
|
||||
#if __INTEL__
|
||||
inline int32
|
||||
atomic_test_and_set(volatile int32 *value, int32 newValue, int32 testAgainst)
|
||||
{
|
||||
int32 oldValue;
|
||||
asm volatile("lock; cmpxchg %%ecx, (%%edx)"
|
||||
: "=a" (oldValue) : "a" (testAgainst), "c" (newValue), "d" (value));
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
inline void
|
||||
atomic_set(volatile int32 *value, int32 newValue)
|
||||
{
|
||||
asm volatile("lock; xchg %%eax, (%%edx)"
|
||||
: : "a" (newValue), "d" (value));
|
||||
}
|
||||
#else
|
||||
# error The macros atomic_set(), and atomic_test_and_set() are not defined for the target processor
|
||||
#endif
|
||||
|
||||
#endif /* UTILITY_H */
|
||||
|
@ -474,7 +474,7 @@ bfs_suspend_vnode(void *_ns, void *_node)
|
||||
static int
|
||||
bfs_walk(void *_ns, void *_directory, const char *file, char **_resolvedPath, vnode_id *vnid)
|
||||
{
|
||||
FUNCTION_START(("file = %s\n",file));
|
||||
//FUNCTION_START(("file = %s\n",file));
|
||||
|
||||
if (_ns == NULL || _directory == NULL || file == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
Loading…
Reference in New Issue
Block a user