/************************************************************************/
/* Copyright 2002 MBARI													*/
/************************************************************************/
/************************************************************************/
/* Summary	: Definitions for Semaphore library for OASIS5				*/
/* Filename : sem.c														*/
/* Author	: Robert Herlien (rah)										*/
/* Project	: OASIS5 Mooring Controller									*/
/* Revision: 1.0														*/
/* Created	: 06/15/2016, from OASIS3 sem.c								*/
/*																			*/
/* MBARI provides this documentation and code "as is", with no warranty,	*/
/* express or implied, of its quality or consistency. It is provided without*/
/* support and without obligation on the part of the Monterey Bay Aquarium	*/
/* Research Institute to assist in its use, correction, modification, or	*/
/* enhancement. This information should not be published or distributed to	*/
/* third parties without specific written permission from MBARI.			*/
/*																			*/
/************************************************************************/
/* Modification History:												*/
/* 10oct2002 rah - OASIS3 version created from OASIS sem.c				*/
/* 15jun2016 rah - OASIS5 version created from OASIS3 sem.c				*/
/* $Log$
 */
/************************************************************************/
/************************************************************************/
/* This module wraps the FreeRTOS semphr library functions in order to	*/
/* save a list of mutex semaphores.  This is used for 2 purposes:		*/
/* 1. When a task exits, we look at all mutexes and release any it owns */
/* 2. For display from the "SYSTEM" command								*/
/************************************************************************/

#include <mbariTypes.h>					/* MBARI type definitions		*/
#include <mbariConst.h>					/* MBARI constants				*/
#include <oasis.h>						/* OASIS controller definitions	*/
#include <debug.h>
#include <olist.h>						/* OASIS linked list definitions*/
#include <sem.h>						/* OASIS semaphore definitions	*/ 
#include <otask.h>						/* OASIS task definitions		*/
#include <FreeRTOS.h>					/* FreeRTOS definitions			*/
#include <semphr.h>						/* FreeRTOS semaphore functions	*/


/********************************/
/*		Module Local Data		*/
/********************************/

MLocal LstHead	semList;				/* List of all mutex  semaphores in system*/


/************************************************************************/
/* Function    : semLibInit												*/
/* Purpose     : Initialize this module									*/
/* Inputs      : None													*/
/* Outputs     : None													*/
/************************************************************************/
void semLibInit(void)
{
  list_init( &semList );

} /* semLibInit() */


/************************************************************************/
/* Function	   : semCreateMutex											*/
/* Purpose	   : Create a semaphore from a static buffer				*/
/* Inputs	   : Static Semaphore buffer, defined by semphr.h			*/
/* Outputs	   : SemaphoreHandle_t										*/
/************************************************************************/
SemaphoreHandle_t	semCreateMutex(SemBuf *semBufp)
{
	if ((semBufp->semHandle = xSemaphoreCreateMutexStatic(&(semBufp->semBuf))) == NULL)
		return(NULL);

	list_add(&semList, (Node *)semBufp);

	return(semBufp->semHandle);
}

/************************************************************************/
/* Function	   : semCreateRecursiveMutex								*/
/* Purpose	   : Create a semaphore from a static buffer				*/
/* Inputs	   : Static Semaphore buffer, defined by semphr.h			*/
/* Outputs	   : SemaphoreHandle_t										*/
/************************************************************************/
SemaphoreHandle_t	semCreateRecursiveMutex(SemBuf *semBufp)
{
	if ((semBufp->semHandle = xSemaphoreCreateRecursiveMutexStatic(&(semBufp->semBuf))) == NULL)
		return(NULL);

	list_add(&semList, (Node *)semBufp);

	return(semBufp->semHandle);
}


/************************************************************************/
/* Function	   : semTaskExit											*/
/* Purpose	   : Unlock semaphores owned by exiting task				*/
/* Inputs	   : Task Handle of exiting task							*/
/* Outputs	   : None													*/
/************************************************************************/
void semTaskExit(TaskHandle_t tid)
{
	Reg Node		*np;

	if (lockListT(&semList, TICKS_PER_SEC/4))
	{
		for (np = list_first(&semList); np != NULLNODE; np = list_next(np))
		{
			if (xSemaphoreGetMutexHolder(NODEtoSEM(np)) == tid)
				xSemaphoreGive(NODEtoSEM(np));
		}

		unlockList(&semList);
	}

} /* semTaskExit() */


#ifdef DEBUG_SYSTEM_CMD

/************************************************************************/
/* Function	   : semGetSemList											*/
/* Purpose	   : Get list of all system semaphores						*/
/* Inputs	   : None													*/
/* Outputs	   : Ptr to sem list										*/
/************************************************************************/
LstHead *semGetSemList(void)
{
  return(&semList);

} /* semGetSemList */

#endif
