/*
 * @Author: jiejie
 * @Github: https://github.com/jiejieTop
 * @Date: 2019-12-23 19:26:27
 * @LastEditTime: 2020-02-23 16:19:07
 * @Description: the code belongs to jiejie, please keep the author information and source code according to the license.
 */
#include "platform_thread.h"
#include "platform_memory.h"

platform_thread_t *platform_thread_init( const char *name,
                                        void (*entry)(void *),
                                        void * const param,
                                        unsigned int stack_size,
                                        unsigned int priority,
                                        unsigned int tick)
{
    int res;
    platform_thread_t *thread;
    void *(*thread_entry) (void *);

    thread_entry = (void *(*)(void*))entry;
    thread = platform_memory_alloc(sizeof(platform_thread_t));

    if (NULL == thread) {
        return NULL;
    }

    // 修复竞态条件：在创建线程之前先初始化 mutex 和 cond
    // 否则新线程可能在这些成员初始化之前就开始访问它们
    thread->mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
    thread->cond = (pthread_cond_t)PTHREAD_COND_INITIALIZER;

    // 现在才创建线程，此时 mutex 和 cond 已经初始化完成
    res = pthread_create(&thread->thread, NULL, thread_entry, param);
    if(res != 0) {
        platform_memory_free(thread);
        return NULL;
    }

    return thread;
}

void platform_thread_startup(platform_thread_t* thread)
{
    (void) thread;
}

void platform_thread_stop(platform_thread_t* thread)
{
    // 添加 NULL 检查，防止空指针解引用
    if (NULL == thread) {
        return;
    }
    pthread_mutex_lock(&(thread->mutex));
    pthread_cond_wait(&(thread->cond), &(thread->mutex));
    pthread_mutex_unlock(&(thread->mutex));
}

void platform_thread_start(platform_thread_t* thread)
{
    // 添加 NULL 检查，防止空指针解引用
    if (NULL == thread) {
        return;
    }
    pthread_mutex_lock(&(thread->mutex));
    pthread_cond_signal(&(thread->cond));
    pthread_mutex_unlock(&(thread->mutex));
}

void platform_thread_destroy(platform_thread_t* thread)
{
    if (NULL != thread)
        pthread_detach(thread->thread);
}


