/* mutex kernel services */

/*
 * Copyright (c) 1997-2015 Wind River Systems, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1) Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2) Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * 3) Neither the name of Wind River Systems nor the names of its contributors
 * may be used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/*
DESCRIPTION
This module contains routines for handling mutex locking and unlocking.  It
also includes routines that force the release of  mutex objects when a task
is aborted or unloaded.

Mutexes implement a priority inheritance algorithm that boosts the priority
level of the owning task to match the priority level of the highest priority
task waiting on the mutex.

Each mutex that contributes to priority inheritance must be released in the
reverse order in which is was acquired.  Furthermore each subsequent mutex
that contributes to raising the owning task's priority level must be acquired
at a point after the most recent "bumping" of the priority level.

For example, if task A has two mutexes contributing to the raising of its
priority level, the second mutex M2 must be acquired by task A after task
A's priority level was bumped due to owning the first mutex M1.  When
releasing the mutex, task A must release M2 before it releases M1.  Failure
to follow this nested model may result in tasks running at unexpected priority
levels (too high, or too low).

NOMANUAL
*/

#include <microkernel.h>
#include <micro_private.h>
#include <nano_private.h>

/*******************************************************************************
*
* _k_mutex_lock_reply - reply to a mutex lock request (LOCK_TMO, LOCK_RPL)
*
* This routine replies to a mutex lock request.  This will occur if either
* the waiting task times out or acquires the mutex lock.
*
* RETURNS: N/A
*
* \NOMANUAL
*/

void _k_mutex_lock_reply(
	struct k_args *A /* pointer to mutex lock reply request arguments */
	)
{
#ifdef CONFIG_SYS_CLOCK_EXISTS
	struct mutex_struct *Mutex; /* pointer to internal mutex structure */
	struct k_args *PrioChanger; /* used to change a task's priority level */
	struct k_args *FirstWaiter; /* pointer to first task in wait queue */
	kpriority_t newPriority;    /* priority level to which to drop */
	int MutexId;                /* mutex ID obtained from request args */

	if (A->Time.timer) {
		FREETIMER(A->Time.timer);
	}

	if (A->Comm == LOCK_TMO) {/* Timeout case */

		REMOVE_ELM(A);
		A->Time.rcode = RC_TIME;

		MutexId = A->Args.l1.mutex;
		Mutex = _k_mutex_list + OBJ_INDEX(MutexId);

		FirstWaiter = Mutex->Waiters;

		/*
		 * When timing out, there are two cases to consider.
		 * 1. There are no waiting tasks.
		 *    - As there are no waiting tasks, this mutex is no longer
		 *    involved in priority inheritance.  It's current priority
		 *    level should be dropped (if needed) to the original
		 *    priority level.
		 * 2. There is at least one waiting task in a priority ordered
		 *    list.
		 *    - Depending upon the the priority level of the first
		 *    waiting task, the owner task's original priority and
		 *    the ceiling priority, the owner's priority level may
		 *    be dropped but not necessarily to the original priority
		 *    level.
		 */

		newPriority = Mutex->OwnerOriginalPrio;

		if (FirstWaiter != NULL) {
			newPriority = (FirstWaiter->Prio < newPriority)
					      ? FirstWaiter->Prio
					      : newPriority;
			newPriority = (newPriority > CONFIG_PRIORITY_CEILING)
					      ? newPriority
					      : CONFIG_PRIORITY_CEILING;
		}

		if (Mutex->OwnerCurrentPrio != newPriority) {
			GETARGS(PrioChanger);
			PrioChanger->alloc = true;
			PrioChanger->Comm = SPRIO;
			PrioChanger->Prio = newPriority;
			PrioChanger->Args.g1.task = Mutex->Owner;
			PrioChanger->Args.g1.prio = newPriority;
			SENDARGS(PrioChanger);
			Mutex->OwnerCurrentPrio = newPriority;
		}
	} else {/* LOCK_RPL: Reply case */
		A->Time.rcode = RC_OK;
	}
#else
	/* LOCK_RPL: Reply case */
	A->Time.rcode = RC_OK;
#endif

	_k_state_bit_reset(A->Ctxt.proc, TF_LOCK);
}

/*******************************************************************************
*
* _k_mutex_lock_request - process a mutex lock request
*
* This routine processes a mutex lock request (LOCK_REQ).  If the mutex
* is already locked, and the timeout is non-zero then the priority inheritance
* algorithm may be applied to prevent priority inversion scenarios.
*
* RETURNS: N/A
*
* \NOMANUAL
*/

void _k_mutex_lock_request(struct k_args *A /* pointer to mutex lock
						  request arguments */
				     )
{
	struct mutex_struct *Mutex; /* pointer to internal mutex structure */
	int MutexId;                /* mutex ID obtained from lock request */
	struct k_args *PrioBooster; /* used to change a task's priority level */
	kpriority_t BoostedPrio;    /* new "boosted" priority level */

	MutexId = A->Args.l1.mutex;


	Mutex = _k_mutex_list + OBJ_INDEX(MutexId);
	if (Mutex->Level == 0 || Mutex->Owner == A->Args.l1.task) {
		/* The mutex is either unowned or this is a nested lock. */
#ifdef CONFIG_OBJECT_MONITOR
		Mutex->Count++;
#endif

		Mutex->Owner = A->Args.l1.task;

		/*
		 * Assign the task's priority directly if the requesting
		 * task is on this node.  This may be more recent than
		 * that stored in struct k_args.
		 */
		Mutex->OwnerCurrentPrio = _k_current_task->Prio;

		/*
		 * Save the original priority when first acquiring the lock (but
		 * not on nested locks).  The original priority level only
		 * reflects the priority level of the requesting task at the
		 * time the lock is acquired.  Consequently, if the requesting
		 * task is already involved in priority inheritance, this
		 * original priority reflects its "boosted" priority.
		 */
		if (Mutex->Level == 0) {
			Mutex->OwnerOriginalPrio = Mutex->OwnerCurrentPrio;
		}

		Mutex->Level++;

		A->Time.rcode = RC_OK;

	} else {
		/* The mutex is owned by another task. */
#ifdef CONFIG_OBJECT_MONITOR
		Mutex->Confl++;
#endif

		if (likely(A->Time.ticks != TICKS_NONE)) {
			/* A non-zero timeout was specified. */
				/*
				 * The requesting task is on this node. Ensure
				 * the priority saved in the request is up to
				 * date.
				 */
				A->Ctxt.proc = _k_current_task;
				A->Prio = _k_current_task->Prio;
				_k_state_bit_set(_k_current_task, TF_LOCK);
			/* Note: Mutex->Waiters is a priority sorted list */
			INSERT_ELM(Mutex->Waiters, A);
#ifdef CONFIG_SYS_CLOCK_EXISTS
			if (A->Time.ticks == TICKS_UNLIMITED) {
				/* Request will not time out */
				A->Time.timer = NULL;
			} else {
				/*
				 * Prepare to call _k_mutex_lock_reply() should
				 * the request time out.
				 */
				A->Comm = LOCK_TMO;
				_k_timeout_alloc(A);
			}
#endif
			if (A->Prio < Mutex->OwnerCurrentPrio) {
				/*
				 * The priority level of the owning task is less
				 * than that of the requesting task.  Boost the
				 * priority level of the owning task to match
				 * the priority level of the requesting task.
				 * Note that the boosted priority level is
				 * limited to <K_PrioCeiling>.
				 */
				BoostedPrio = (A->Prio > CONFIG_PRIORITY_CEILING)
						      ? A->Prio
						      : CONFIG_PRIORITY_CEILING;
				if (BoostedPrio < Mutex->OwnerCurrentPrio) {
					/* Boost the priority level */
					GETARGS(PrioBooster);

					PrioBooster->alloc = true;
					PrioBooster->Comm = SPRIO;
					PrioBooster->Prio = BoostedPrio;
					PrioBooster->Args.g1.task = Mutex->Owner;
					PrioBooster->Args.g1.prio = BoostedPrio;
					SENDARGS(PrioBooster);
					Mutex->OwnerCurrentPrio = BoostedPrio;
				}
			}
		} else {
			/*
			 * ERROR.  The mutex is locked by another task and
			 * this is an immediate lock request (timeout = 0).
			 */
			A->Time.rcode = RC_FAIL;
		}
	}
}

/*******************************************************************************
*
* _task_mutex_lock - mutex lock kernel service
*
* This routine is the entry to the mutex lock kernel service.
*
* RETURNS: RC_OK on success, RC_FAIL on error, RC_TIME on timeout
*/

int _task_mutex_lock(
	kmutex_t mutex,   /* mutex to lock */
	int32_t time /* max # of ticks to wait for mutex */
	)
{
	struct k_args A; /* argument packet */

	A.Comm = LOCK_REQ;
	A.Time.ticks = time;
	A.Args.l1.mutex = mutex;
	A.Args.l1.task = _k_current_task->Ident;
	KERNEL_ENTRY(&A);
	return A.Time.rcode;
}

/*******************************************************************************
*
* _k_mutex_unlock - process a mutex unlock request
*
* This routine processes a mutex unlock request (UNLOCK).  If the mutex
* was involved in priority inheritance, then it will change the priority level
* of the current owner to the priority level it had when it acquired the
* mutex.
*
* RETURNS: N/A
*
* \NOMANUAL
*/

void _k_mutex_unlock(struct k_args *A /* pointer to mutex unlock
						 request arguments */
				    )
{
	struct mutex_struct *Mutex; /* pointer internal mutex structure */
	int MutexId;                /* mutex ID obtained from unlock request */
	struct k_args *PrioDowner;  /* used to change a task's priority level */

	MutexId = A->Args.l1.mutex;
	Mutex = _k_mutex_list + OBJ_INDEX(MutexId);
	if (Mutex->Owner == A->Args.l1.task && --(Mutex->Level) == 0) {
		/*
		 * The requesting task owns the mutex and all locks
		 * have been released.
		 */

		struct k_args *X;

#ifdef CONFIG_OBJECT_MONITOR
		Mutex->Count++;
#endif

		if (Mutex->OwnerCurrentPrio != Mutex->OwnerOriginalPrio) {
			/*
			 * This mutex is involved in priority inheritance.
			 * Send a request to revert the priority level of
			 * the owning task back to its priority level when
			 * it first acquired the mutex.
			 */
			GETARGS(PrioDowner);

			PrioDowner->alloc = true;
			PrioDowner->Comm = SPRIO;
			PrioDowner->Prio = Mutex->OwnerOriginalPrio;
			PrioDowner->Args.g1.task = Mutex->Owner;
			PrioDowner->Args.g1.prio = Mutex->OwnerOriginalPrio;
			SENDARGS(PrioDowner);
		}

		X = Mutex->Waiters;
		if (X != NULL) {
			/*
			 * At least one task was waiting for the mutex.
			 * Assign the new owner of the task to be the
			 * first in the queue.
			 */

			Mutex->Waiters = X->Forw;
			Mutex->Owner = X->Args.l1.task;
			Mutex->Level = 1;
			Mutex->OwnerCurrentPrio = X->Prio;
			Mutex->OwnerOriginalPrio = X->Prio;

#ifdef CONFIG_SYS_CLOCK_EXISTS
			if (X->Time.timer) {
				/*
				 * Trigger a call to _k_mutex_lock_reply()--it will
				 * send a reply with a return code of RC_OK.
				 */
				_k_timeout_cancel(X);
				X->Comm = LOCK_RPL;
			} else {
#endif
				/*
				 * There is no timer to update.
				 * Set the return code.
				 */
				X->Time.rcode = RC_OK;
					_k_state_bit_reset(X->Ctxt.proc, TF_LOCK);
#ifdef CONFIG_SYS_CLOCK_EXISTS
			}
#endif
		} else {
			/* No task is waiting in the queue. */
			Mutex->Owner = ANYTASK;
			Mutex->Level = 0;
		}
	}
}

/*******************************************************************************
*
* _task_mutex_unlock - mutex unlock kernel service
*
* This routine is the entry to the mutex unlock kernel service.
*
* RETURNS: N/A
*/

void _task_mutex_unlock(kmutex_t mutex /* mutex to unlock */
					 )
{
	struct k_args A; /* argument packet */

	A.Comm = UNLOCK;
	A.Args.l1.mutex = mutex;
	A.Args.l1.task = _k_current_task->Ident;
	KERNEL_ENTRY(&A);
}


