forked from KolibriOS/kolibrios
ddk: 3.17-rc1
git-svn-id: svn://kolibrios.org@5056 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
117
drivers/ddk/linux/mutex.c
Normal file
117
drivers/ddk/linux/mutex.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* kernel/locking/mutex.c
|
||||
*
|
||||
* Mutexes: blocking mutual exclusion locks
|
||||
*
|
||||
* Started by Ingo Molnar:
|
||||
*
|
||||
* Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
|
||||
*
|
||||
* Many thanks to Arjan van de Ven, Thomas Gleixner, Steven Rostedt and
|
||||
* David Howells for suggestions and improvements.
|
||||
*
|
||||
* - Adaptive spinning for mutexes by Peter Zijlstra. (Ported to mainline
|
||||
* from the -rt tree, where it was originally implemented for rtmutexes
|
||||
* by Steven Rostedt, based on work by Gregory Haskins, Peter Morreale
|
||||
* and Sven Dietrich.
|
||||
*
|
||||
* Also see Documentation/mutex-design.txt.
|
||||
*/
|
||||
#include <linux/lockdep.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/ww_mutex.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <syscall.h>
|
||||
/*
|
||||
* A negative mutex count indicates that waiters are sleeping waiting for the
|
||||
* mutex.
|
||||
*/
|
||||
#define MUTEX_SHOW_NO_WAITER(mutex) (atomic_read(&(mutex)->count) >= 0)
|
||||
|
||||
void
|
||||
__mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key)
|
||||
{
|
||||
atomic_set(&lock->count, 1);
|
||||
// spin_lock_init(&lock->wait_lock);
|
||||
INIT_LIST_HEAD(&lock->wait_list);
|
||||
// mutex_clear_owner(lock);
|
||||
#ifdef CONFIG_MUTEX_SPIN_ON_OWNER
|
||||
lock->osq = NULL;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static __always_inline void ww_mutex_lock_acquired(struct ww_mutex *ww,
|
||||
struct ww_acquire_ctx *ww_ctx)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG_MUTEXES
|
||||
/*
|
||||
* If this WARN_ON triggers, you used ww_mutex_lock to acquire,
|
||||
* but released with a normal mutex_unlock in this call.
|
||||
*
|
||||
* This should never happen, always use ww_mutex_unlock.
|
||||
*/
|
||||
DEBUG_LOCKS_WARN_ON(ww->ctx);
|
||||
|
||||
/*
|
||||
* Not quite done after calling ww_acquire_done() ?
|
||||
*/
|
||||
DEBUG_LOCKS_WARN_ON(ww_ctx->done_acquire);
|
||||
|
||||
if (ww_ctx->contending_lock) {
|
||||
/*
|
||||
* After -EDEADLK you tried to
|
||||
* acquire a different ww_mutex? Bad!
|
||||
*/
|
||||
DEBUG_LOCKS_WARN_ON(ww_ctx->contending_lock != ww);
|
||||
|
||||
/*
|
||||
* You called ww_mutex_lock after receiving -EDEADLK,
|
||||
* but 'forgot' to unlock everything else first?
|
||||
*/
|
||||
DEBUG_LOCKS_WARN_ON(ww_ctx->acquired > 0);
|
||||
ww_ctx->contending_lock = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Naughty, using a different class will lead to undefined behavior!
|
||||
*/
|
||||
DEBUG_LOCKS_WARN_ON(ww_ctx->ww_class != ww->ww_class);
|
||||
#endif
|
||||
ww_ctx->acquired++;
|
||||
}
|
||||
|
||||
void ww_mutex_unlock(struct ww_mutex *lock)
|
||||
{
|
||||
/*
|
||||
* The unlocking fastpath is the 0->1 transition from 'locked'
|
||||
* into 'unlocked' state:
|
||||
*/
|
||||
if (lock->ctx) {
|
||||
if (lock->ctx->acquired > 0)
|
||||
lock->ctx->acquired--;
|
||||
lock->ctx = NULL;
|
||||
}
|
||||
MutexUnlock(&lock->base);
|
||||
}
|
||||
|
||||
int __ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ctx)
|
||||
{
|
||||
MutexLock(&lock->base);
|
||||
ww_mutex_lock_acquired(lock, ctx);
|
||||
lock->ctx = ctx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int __ww_mutex_lock_interruptible(struct ww_mutex *lock, struct ww_acquire_ctx *ctx)
|
||||
{
|
||||
MutexLock(&lock->base);
|
||||
ww_mutex_lock_acquired(lock, ctx);
|
||||
lock->ctx = ctx;
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user