#ifndef _aplmt_os_semaapi_h_
#define _aplmt_os_semaapi_h_
/*----------------------------------------------------------------------------
** SUMMARY: Semaphore API (SEMA)
**
** DESCRIPTION:
**  This file provides generic interfaces for semaphores. Types of semaphore
**  currently supported:
**      - Counting semaphores
**
** CONFIGURATION 
** -------------
**  COMPILE:        none.
**                                            
**  APPLICATION:    none.
**
**  PLATFORM:       Data Types:    
**                      PLATFORM_APLMT_SEMA_HDL_T
**                      PLATFORM_APLMT_SEMA_COUNT_T
**                      PLATFORM_APLMT_SEMAFAC_HDL_T
**
**                  Definitions:
**                      PLATFORM_APLMT_NULL_SEMA_HANDLE
**                      PLATFORM_APLMT_SEMA_WAIT_NO_TIMEOUT
**
**  NOTES:
**  1. Unless explicitly stated otherwise, NONE of the following methods may be 
**     called from interrupt service routines.
**  2. Unless explicitly stated otherwise, NONE of the following methods may be 
**     called before the platform's kernel is running.
**  3. Unless explicitly stated otherwise, all of the following methods ARE 
**     thread-safe.
**  4. For efficency/optimization some methods are 'inlined'.  The inlining
**     is done by using the preprocessor/macros.  The application should
**     treat all methods as function calls and not rely on the fact they may
**     be currently defined as macros.
----------------------------------------------------------------------------*/

#include "apl/types/types.h"        /* For: basic types */

#ifdef __cplusplus
extern "C" {
#endif


/*-------------- CONSTANTS -------------------------------------------------*/
/** Used to indicate no-timeout/infinite wait when using wait-with-timeout 
    method (is required to be largest possible wait time for the timeout
    mechanism). 
 */
#define APLMT_SEMA_WAIT_NO_TIMEOUT      PLATFORM_APLMT_SEMA_WAIT_NO_TIMEOUT

/** Maximum 'valid' timeout for wait-with-timeout method */
#define APLMT_SEMA_WAIT_MAX_TIMEOUT     ((AplSize_t)(APLMT_SEMA_WAIT_NO_TIMEOUT-1))

/** NULL Thread Handle */
#define APLMT_NULL_SEMA_HANDLE          PLATFORM_APLMT_NULL_SEMA_HANDLE


/*-------------- TYPES -----------------------------------------------------*/
/** Handle to a counting semaphore */
#define AplmtSemaHdl                    PLATFORM_APLMT_SEMA_HDL_T

/** Holds the maximum count for a counting semaphore */
#define AplmtSemaCount                  PLATFORM_APLMT_SEMA_COUNT_T

/** Handle to a counting-semaphore Factory */
#define AplmtSemafacHdl                 PLATFORM_APLMT_SEMAFAC_HDL_T


/*-------------- INLINE PLATFORM IMPLEMENTATION ----------------------------*/
#include "platform/semaapi.h"       


/*-------------- PUBLIC/PUBLISHED API --------------------------------------*/
/** This method atomically "increases the count" of the semaphore specified by
    sema.  If there is a suspended thread waiting on the semaphore, the thread 
    is made ready for execution.  If no thread is waiting, the semaphore's 
    count is incremented by 1.

    Prototype:
        void Aplmt_semaSignal( AplmtSemaHdl sema );
 */
#define Aplmt_semaSignal                        _Aplmt_semaSignal

/** This method is the same as Aplmt_semaSignal() except that can ONLY be called
    from the context of an interrupt service routine.
    Prototype:
        void Aplmt_isr_semaSignal( AplmtSemaHdl sema );
 */
#define Aplmt_isr_semaSignal                    _Aplmt_isr_semaSignal

/** This method suspends the calling thread until the semaphore pointed to by 
    sema has non-zero count. It then atomically decreases the semaphore count.

    Prototype:
        void Aplmt_semaWait( AplmtSemaHdl sema );
 */
#define Aplmt_semaWait                          _Aplmt_semaWait

/** This method is the same as Aplmt_semaWait(), except the method will 
    timeout and/or return after the specified time interval (in milliseconds), 
    if the semaphore was not signaled.  The method normally returns non-zero 
    (true).  It only returns 0 (false) if the thread 'waited' on the semaphore
    and the timeout period expired before the semaphore was signaled.
    NOTES:
        o If APLMT_SEMA_WAIT_NO_TIMEOUT is specified as the timeout period, 
          the method behaves exactly the same as Aplmt_semaWait(), i.e. 
          nevers times-out.
        o The longest timeout period is APLMT_SEMA_WAIT_MAX_TIMEOUT.
        o If 0 is specified as the timout period, then the call acts
          as a 'polled' operation on the semaphore in that it will never 
          block even if the semaphore count is zero when called.
        o CAUTION: Do not assume that since the method returned false due to 
          a time-out, that the semaphore is not signaled (i.e. its count is 
          zero).  It is possible that the semaphore is/was signaled after the
          'time-out', BUT before the application has an opportunity to check
          the return code.
        o This method is consider OPTIONAL, i.e. the underlaying platform
          is NOT REQUIRED to support this method.  CHECK YOUR Platform's
          documentation before using this method.

    Prototype:
        AplBool Aplmt_semaWaitTimeout( AplmtSemaHdl sema, AplSize_t maxWaitInMilliseconds )
 */
#define Aplmt_semaWaitTimeout                   _Aplmt_semaWaitTimeout

/*-------------- PUBLIC/PUBLISHED API --------------------------------------*/
/** This method creates a counting semaphore.  The parameter 'value' is used 
    to speficy the initial count of the semaphore. The method returns a handle 
    to the newly created semaphore, or NULL if the was an error.

    Prototype:
        AplmtSemaHdl Aplmt_createSemaphore(AplmtSemafacHdl semaphoreFactoryToUse, AplmtSemaCount value);
 */
#define Aplmt_createSemaphore                   _Aplmt_createSemaphore

/** This method is used to destroy a counting-semaphore that was created by the 
    specified semaphore factory.

    Prototype:
        void Aplmt_destroySemaphore(AplmtSemafacHdl semaphoreFactoryToUse, AplmtSemaHdl semaphoreToDestroy);
*/
#define Aplmt_destroySemaphore                  _Aplmt_destroySemaphore



#ifdef __cplusplus
}
#endif
/*--------------------------------------------------------------------------*/
#endif  /* end _aplmt_os_semaapi_h_ */

