2 * Copyright 2009, Michael Lotz, mmlr@mlotz.ch.
3 * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
4 * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
5 * Distributed under the terms of the MIT License.
7 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
8 * Distributed under the terms of the NewOS License.
18 #include <user_mutex_defs.h>
21 #define MAX_UNSUCCESSFUL_SPINS 100
24 extern int32 __gCPUCount
;
27 // #pragma mark - mutex
31 __mutex_init(mutex
*lock
, const char *name
)
40 __mutex_init_etc(mutex
*lock
, const char *name
, uint32 flags
)
42 lock
->name
= (flags
& MUTEX_FLAG_CLONE_NAME
) != 0 ? strdup(name
) : name
;
47 lock
->flags
&= ~uint32(MUTEX_FLAG_ADAPTIVE
);
52 __mutex_destroy(mutex
*lock
)
54 if ((lock
->flags
& MUTEX_FLAG_CLONE_NAME
) != 0)
55 free(const_cast<char*>(lock
->name
));
60 __mutex_lock(mutex
*lock
)
63 const uint32 kMaxCount
64 = (lock
->flags
& MUTEX_FLAG_ADAPTIVE
) != 0 ? MAX_UNSUCCESSFUL_SPINS
: 1;
68 // set the locked flag
69 oldValue
= atomic_or(&lock
->lock
, B_USER_MUTEX_LOCKED
);
71 if ((oldValue
& (B_USER_MUTEX_LOCKED
| B_USER_MUTEX_WAITING
)) == 0
72 || (oldValue
& B_USER_MUTEX_DISABLED
) != 0) {
73 // No one has the lock or is waiting for it, or the mutex has been
77 } while (count
++ < kMaxCount
&& (oldValue
& B_USER_MUTEX_WAITING
) != 0);
79 // we have to call the kernel
82 error
= _kern_mutex_lock(&lock
->lock
, lock
->name
, 0, 0);
83 } while (error
== B_INTERRUPTED
);
90 __mutex_unlock(mutex
*lock
)
92 // clear the locked flag
93 int32 oldValue
= atomic_and(&lock
->lock
, ~(int32
)B_USER_MUTEX_LOCKED
);
94 if ((oldValue
& B_USER_MUTEX_WAITING
) != 0
95 && (oldValue
& B_USER_MUTEX_DISABLED
) == 0) {
96 _kern_mutex_unlock(&lock
->lock
, 0);