/*
 * Amazon FreeRTOS POSIX V1.1.0
 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * http://aws.amazon.com/freertos
 * http://www.FreeRTOS.org
 */

/**
 * @file FreeRTOS_POSIX_pthread.c
 * @brief Implementation of thread functions in pthread.h
 */

/* C standard library includes. */
#include <stddef.h>
#include <string.h>

/* FreeRTOS+POSIX includes. */
#include "FreeRTOS_POSIX.h"
#include "FreeRTOS_POSIX/errno.h"
#include "FreeRTOS_POSIX/pthread.h"

/**
 * @brief Thread attribute object.
 */
typedef struct pthread_attr_internal
{
    uint16_t usStackSize;                /**< Stack size. */
    uint16_t usSchedPriorityDetachState; /**< Schedule priority 15 bits (LSB) Detach state: 1 bits (MSB) */
} pthread_attr_internal_t;

#define pthreadDETACH_STATE_MASK      0x8000
#define pthreadSCHED_PRIORITY_MASK    0x7FFF
#define pthreadDETACH_STATE_SHIFT     15
#define pthreadGET_SCHED_PRIORITY( var )    ( ( var ) & ( pthreadSCHED_PRIORITY_MASK ) )
#define pthreadIS_JOINABLE( var )           ( ( ( var ) & ( pthreadDETACH_STATE_MASK ) ) == pthreadDETACH_STATE_MASK )

/**
 * @brief Thread object.
 */
typedef struct pthread_internal
{
    pthread_attr_internal_t xAttr;        /**< Thread attributes. */
    void * ( *pvStartRoutine )( void * ); /**< Application thread function. */
    void * xTaskArg;                      /**< Arguments for application thread function. */
    TaskHandle_t xTaskHandle;             /**< FreeRTOS task handle. */
    StaticSemaphore_t xJoinBarrier;       /**< Synchronizes the two callers of pthread_join. */
    StaticSemaphore_t xJoinMutex;         /**< Ensures that only one other thread may join this thread. */
    void * xReturn;                       /**< Return value of pvStartRoutine. */
} pthread_internal_t;

/**
 * @brief Terminates the calling thread.
 *
 * For joinable threads, this function waits for pthread_join. Otherwise,
 * it deletes the thread and frees up resources used by the thread.
 *
 * @return This function does not return.
 */
static void prvExitThread( void );

/**
 * @brief Wrapper function for the user's thread routine.
 *
 * This function is executed as a FreeRTOS task function.
 * @param[in] pxArg A pointer to a pthread_internal_t.
 *
 * @return nothing
 */
static void prvRunThread( void * pxArg );

/**
 * @brief Default pthread_attr_t.
 */
static const pthread_attr_internal_t xDefaultThreadAttributes =
{
    .usStackSize                = PTHREAD_STACK_MIN,
    .usSchedPriorityDetachState = ( ( uint16_t ) tskIDLE_PRIORITY & pthreadSCHED_PRIORITY_MASK ) | ( PTHREAD_CREATE_JOINABLE << pthreadDETACH_STATE_SHIFT ),
};

/*-----------------------------------------------------------*/

static void prvExitThread( void )
{
    pthread_internal_t * pxThread = ( pthread_internal_t * ) pthread_self();

    /* If this thread is joinable, wait for a call to pthread_join. */
    if( pthreadIS_JOINABLE( pxThread->xAttr.usSchedPriorityDetachState ) )
    {
        ( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxThread->xJoinBarrier );

        /* Suspend until the call to pthread_join. The caller of pthread_join
         * will perform cleanup. */
        vTaskSuspend( NULL );
    }
    else
    {
        /* For a detached thread, perform cleanup of thread object. */
        vPortFree( pxThread );
        vTaskDelete( NULL );
    }
}

/*-----------------------------------------------------------*/

static void prvRunThread( void * pxArg )
{
    pthread_internal_t * pxThread = ( pthread_internal_t * ) pxArg;

    /* Run the thread routine. */
    pxThread->xReturn = pxThread->pvStartRoutine( ( void * ) pxThread->xTaskArg );

    /* Exit once finished. This function does not return. */
    prvExitThread();
}

/*-----------------------------------------------------------*/

int pthread_attr_destroy( pthread_attr_t * attr )
{
    ( void ) attr;

    return 0;
}

/*-----------------------------------------------------------*/

int pthread_attr_getdetachstate( const pthread_attr_t * attr,
                                 int * detachstate )
{
    pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( attr );

    if( pthreadIS_JOINABLE( pxAttr->usSchedPriorityDetachState ) )
    {
        *detachstate = PTHREAD_CREATE_JOINABLE;
    }
    else
    {
        *detachstate = PTHREAD_CREATE_DETACHED;
    }

    return 0;
}

/*-----------------------------------------------------------*/

int pthread_attr_getschedparam( const pthread_attr_t * attr,
                                struct sched_param * param )
{
    pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( attr );

    param->sched_priority = ( int ) ( pthreadGET_SCHED_PRIORITY( pxAttr->usSchedPriorityDetachState ) );

    return 0;
}

/*-----------------------------------------------------------*/

int pthread_attr_getstacksize( const pthread_attr_t * attr,
                               size_t * stacksize )
{
    pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( attr );

    *stacksize = ( size_t ) pxAttr->usStackSize;

    return 0;
}

/*-----------------------------------------------------------*/

int pthread_attr_init( pthread_attr_t * attr )
{
    /* Copy the default values into the new thread attributes object. */
    *( ( pthread_attr_internal_t * ) ( attr ) ) = xDefaultThreadAttributes;

    return 0;
}

/*-----------------------------------------------------------*/

int pthread_attr_setdetachstate( pthread_attr_t * attr,
                                 int detachstate )
{
    int iStatus = 0;
    pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( attr );

    if( ( detachstate != PTHREAD_CREATE_DETACHED ) && ( detachstate != PTHREAD_CREATE_JOINABLE ) )
    {
        iStatus = EINVAL;
    }
    else
    {
        /* clear and then set msb bit to detachstate) */
        pxAttr->usSchedPriorityDetachState &= ~pthreadDETACH_STATE_MASK;
        pxAttr->usSchedPriorityDetachState |= ( ( uint16_t ) detachstate << pthreadDETACH_STATE_SHIFT );
    }

    return iStatus;
}

/*-----------------------------------------------------------*/

int pthread_attr_setschedparam( pthread_attr_t * attr,
                                const struct sched_param * param )
{
    int iStatus = 0;
    pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( attr );

    /* Check for NULL param. */
    if( param == NULL )
    {
        iStatus = EINVAL;
    }

    /* Ensure that param.sched_priority is valid. */
    if( ( iStatus == 0 ) &&
        ( ( param->sched_priority > sched_get_priority_max( SCHED_OTHER ) ) ||
          ( param->sched_priority < 0 ) ) )
    {
        iStatus = ENOTSUP;
    }

    /* Set the sched_param. */
    if( iStatus == 0 )
    {
        /* clear and then set  15 LSB to schedule priority) */
        pxAttr->usSchedPriorityDetachState &= ~pthreadSCHED_PRIORITY_MASK;
        pxAttr->usSchedPriorityDetachState |= ( ( uint16_t ) param->sched_priority );
    }

    return iStatus;
}

/*-----------------------------------------------------------*/

int pthread_attr_setschedpolicy( pthread_attr_t * attr,
                                 int policy )
{
    /* Silence warnings about unused parameters. */
    ( void ) attr;
    ( void ) policy;

    return 0;
}

/*-----------------------------------------------------------*/

int pthread_attr_setstacksize( pthread_attr_t * attr,
                               size_t stacksize )
{
    int iStatus = 0;
    pthread_attr_internal_t * pxAttr = ( pthread_attr_internal_t * ) ( attr );

    if( stacksize < PTHREAD_STACK_MIN )
    {
        iStatus = EINVAL;
    }
    else
    {
        pxAttr->usStackSize = ( uint16_t ) stacksize;
    }

    return iStatus;
}

/*-----------------------------------------------------------*/

int pthread_create( pthread_t * thread,
                    const pthread_attr_t * attr,
                    void *( *startroutine )( void * ),
                    void * arg )
{
    int iStatus = 0;
    pthread_internal_t * pxThread = NULL;
    struct sched_param xSchedParam = { .sched_priority = tskIDLE_PRIORITY };

    /* Allocate memory for new thread object. */
    pxThread = ( pthread_internal_t * ) pvPortMalloc( sizeof( pthread_internal_t ) );

    if( pxThread == NULL )
    {
        /* No memory. */
        iStatus = EAGAIN;
    }

    if( iStatus == 0 )
    {
        /* No attributes given, use default attributes. */
        if( attr == NULL )
        {
            pxThread->xAttr = xDefaultThreadAttributes;
        }
        /* Otherwise, use provided attributes. */
        else
        {
            pxThread->xAttr = *( ( pthread_attr_internal_t * ) ( attr ) );
        }

        /* Get priority from attributes */
        xSchedParam.sched_priority = ( int ) pthreadGET_SCHED_PRIORITY( pxThread->xAttr.usSchedPriorityDetachState );

        /* Set argument and start routine. */
        pxThread->xTaskArg = arg;
        pxThread->pvStartRoutine = startroutine;

        /* If this thread is joinable, create the synchronization mechanisms for
         * pthread_join. */

        if( pthreadIS_JOINABLE( pxThread->xAttr.usSchedPriorityDetachState ) )
        {
            /* These calls will not fail when their arguments aren't NULL. */
            ( void ) xSemaphoreCreateMutexStatic( &pxThread->xJoinMutex );
            ( void ) xSemaphoreCreateBinaryStatic( &pxThread->xJoinBarrier );
        }
    }

    if( iStatus == 0 )
    {
        /* Suspend all tasks to create a critical section. This ensures that
         * the new thread doesn't exit before a tag is assigned. */
        vTaskSuspendAll();

        /* Create the FreeRTOS task that will run the pthread. */
        if( xTaskCreate( prvRunThread,
                         posixconfigPTHREAD_TASK_NAME,
                         ( uint16_t ) ( pxThread->xAttr.usStackSize / sizeof( StackType_t ) ),
                         ( void * ) pxThread,
                         xSchedParam.sched_priority,
                         &pxThread->xTaskHandle ) != pdPASS )
        {
            /* Task creation failed, no memory. */
            vPortFree( pxThread );
            iStatus = EAGAIN;
        }
        else
        {
            /* Store the pointer to the thread object in the task tag. */
            vTaskSetApplicationTaskTag( pxThread->xTaskHandle, ( TaskHookFunction_t ) pxThread );

            /* Set the thread object for the user. */
            *thread = ( pthread_t ) pxThread;
        }

        /* End the critical section. */
        xTaskResumeAll();
    }

    return iStatus;
}

/*-----------------------------------------------------------*/

int pthread_getschedparam( pthread_t thread,
                           int * policy,
                           struct sched_param * param )
{
    int iStatus = 0;
    pthread_internal_t * pxThread = ( pthread_internal_t * ) thread;

    *policy = SCHED_OTHER;
    param->sched_priority = ( int ) pthreadGET_SCHED_PRIORITY( pxThread->xAttr.usSchedPriorityDetachState );

    return iStatus;
}

/*-----------------------------------------------------------*/

int pthread_equal( pthread_t t1,
                   pthread_t t2 )
{
    return t1 == t2;
}

/*-----------------------------------------------------------*/

void pthread_exit( void * value_ptr )
{
    pthread_internal_t * pxThread = ( pthread_internal_t * ) pthread_self();

    /* Set the return value. */
    pxThread->xReturn = value_ptr;

    /* Exit this thread. */
    prvExitThread();
}

/*-----------------------------------------------------------*/

int pthread_join( pthread_t pthread,
                  void ** retval )
{
    int iStatus = 0;
    pthread_internal_t * pxThread = ( pthread_internal_t * ) pthread;

    /* Make sure pthread is joinable. Otherwise, this function would block
     * forever waiting for an unjoinable thread. */
    if( !pthreadIS_JOINABLE( pxThread->xAttr.usSchedPriorityDetachState ) )
    {
        iStatus = EDEADLK;
    }

    /* Only one thread may attempt to join another. Lock the join mutex
     * to prevent other threads from calling pthread_join on the same thread. */
    if( iStatus == 0 )
    {
        if( xSemaphoreTake( ( SemaphoreHandle_t ) &pxThread->xJoinMutex, 0 ) != pdPASS )
        {
            /* Another thread has already joined the requested thread, which would
             * cause this thread to wait forever. */
            iStatus = EDEADLK;
        }
    }

    /* Attempting to join the calling thread would cause a deadlock. */
    if( iStatus == 0 )
    {
        if( pthread_equal( pthread_self(), pthread ) != 0 )
        {
            iStatus = EDEADLK;
        }
    }

    if( iStatus == 0 )
    {
        /* Wait for the joining thread to finish. Because this call waits forever,
         * it should never fail. */
        ( void ) xSemaphoreTake( ( SemaphoreHandle_t ) &pxThread->xJoinBarrier, portMAX_DELAY );

        /* Create a critical section to clean up the joined thread. */
        vTaskSuspendAll();

        /* Release xJoinBarrier and delete it. */
        ( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxThread->xJoinBarrier );
        vSemaphoreDelete( ( SemaphoreHandle_t ) &pxThread->xJoinBarrier );

        /* Release xJoinMutex and delete it. */
        ( void ) xSemaphoreGive( ( SemaphoreHandle_t ) &pxThread->xJoinMutex );
        vSemaphoreDelete( ( SemaphoreHandle_t ) &pxThread->xJoinMutex );

        /* Delete the FreeRTOS task that ran the thread. */
        vTaskDelete( pxThread->xTaskHandle );

        /* Set the return value. */
        if( retval != NULL )
        {
            *retval = pxThread->xReturn;
        }

        /* Free the thread object. */
        vPortFree( pxThread );

        /* End the critical section. */
        xTaskResumeAll();
    }

    return iStatus;
}

/*-----------------------------------------------------------*/

pthread_t pthread_self( void )
{
    /* Return a reference to this pthread object, which is stored in the
     * FreeRTOS task tag. */
    return ( pthread_t ) xTaskGetApplicationTaskTag( NULL );
}

/*-----------------------------------------------------------*/

int pthread_setschedparam( pthread_t thread,
                           int policy,
                           const struct sched_param * param )
{
    int iStatus = 0;

    pthread_internal_t * pxThread = ( pthread_internal_t * ) thread;

    /* Silence compiler warnings about unused parameters. */
    ( void ) policy;

    /* Copy the given sched_param. */
    iStatus = pthread_attr_setschedparam( ( pthread_attr_t * ) &pxThread->xAttr, param );

    if( iStatus == 0 )
    {
        /* Change the priority of the FreeRTOS task. */
        vTaskPrioritySet( pxThread->xTaskHandle, param->sched_priority );
    }

    return iStatus;
}

/*-----------------------------------------------------------*/
