diff options
| author | bhgv <bhgv.empire@gmail.com> | 2020-05-10 02:59:23 +0300 |
|---|---|---|
| committer | bhgv <bhgv.empire@gmail.com> | 2020-05-10 02:59:23 +0300 |
| commit | 31b4edc67b75658ce5e2d41f2fc87331f4b26d49 (patch) | |
| tree | a7b6ea659fe62e0a7239f29170024f524595fb4d /libiot/pthread/mutex.c | |
| parent | c76314f0f38f4ed028610a6db4452879a556b35f (diff) | |
a try to add support of FreeRTOS riscV-64 (k210 cpu). first step
Diffstat (limited to 'libiot/pthread/mutex.c')
| -rw-r--r-- | libiot/pthread/mutex.c | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/libiot/pthread/mutex.c b/libiot/pthread/mutex.c new file mode 100644 index 0000000..c4850d1 --- /dev/null +++ b/libiot/pthread/mutex.c @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2015 - 2018, IBEROXARXA SERVICIOS INTEGRALES, S.L. + * Copyright (C) 2015 - 2018, Jaume Olivé Petrus (jolive@whitecatboard.org) + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of the <organization> nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * * The WHITECAT logotype cannot be changed, you can remove it, but you + * cannot change it in any way. The WHITECAT logotype is: + * + * /\ /\ + * / \_____/ \ + * /_____________\ + * W H I T E C A T + * + * * Redistributions in binary form must retain all copyright notices printed + * to any local or remote output device. This include any reference to + * Lua RTOS, whitecatboard.org, Lua, and other copyright notices that may + * appear in the future. + * + * 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 <COPYRIGHT HOLDER> 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. + * + * Lua RTOS pthread implementation for FreeRTOS + * + */ + +#include "_pthread.h" + +//#include "esp_attr.h" + +#include <stdlib.h> + +static int _check_attr(const pthread_mutexattr_t *attr) { + int type = attr->type; + + if ((type < PTHREAD_MUTEX_NORMAL) || (type > PTHREAD_MUTEX_DEFAULT)) { + return EINVAL; + } + + return 0; +} + +int pthread_mutex_init(pthread_mutex_t *mut, const pthread_mutexattr_t *attr) { + struct pthread_mutex *mutex; + int res; + + if (!mut) { + return EINVAL; + } + + // Check attr + if (attr) { + res = _check_attr(attr); + if (res) { + return res; + } + } + + // Test if it's init yet + if (*mut != PTHREAD_MUTEX_INITIALIZER) { + return EBUSY; + } + + // Create mutex structure + mutex = (struct pthread_mutex *)malloc(sizeof(struct pthread_mutex)); + if (!mutex) { + return EINVAL; + } + + if (attr) { + mutex->type = attr->type; + } else { + mutex->type = PTHREAD_MUTEX_NORMAL; + } + // Create semaphore + if (mutex->type == PTHREAD_MUTEX_RECURSIVE) { + mutex->sem = xSemaphoreCreateRecursiveMutex(); + } else { + mutex->sem = xSemaphoreCreateMutex(); + } + if(!mutex->sem){ + *mut = PTHREAD_MUTEX_INITIALIZER; + free(mutex->sem); + free(mutex); + return ENOMEM; + } + + mutex->owner = pthread_self(); + + *mut = (unsigned int )mutex; + + return 0; +} + +int IRAM_ATTR pthread_mutex_lock(pthread_mutex_t *mut) { + struct pthread_mutex *mutex; + int res; + + if (!mut) { + return EINVAL; + } + + if ((intptr_t) *mut == PTHREAD_MUTEX_INITIALIZER) { + if ((res = pthread_mutex_init(mut, NULL))) { + return res; + } + } + + mutex = (struct pthread_mutex *)(*mut); + + // Lock + if (mutex->type == PTHREAD_MUTEX_RECURSIVE) { + if (xSemaphoreTakeRecursive(mutex->sem, PTHREAD_MTX_LOCK_TIMEOUT) != pdPASS) { + PTHREAD_MTX_DEBUG_LOCK(); + return EINVAL; + } + } else { + if (xSemaphoreTake(mutex->sem, PTHREAD_MTX_LOCK_TIMEOUT) != pdPASS) { + PTHREAD_MTX_DEBUG_LOCK(); + return EINVAL; + } + } + + return 0; +} + +int IRAM_ATTR pthread_mutex_unlock(pthread_mutex_t *mut) { + if (!mut) { + return EINVAL; + } + + struct pthread_mutex *mutex = ( struct pthread_mutex *)(*mut); + + // Unlock + if (mutex->type == PTHREAD_MUTEX_RECURSIVE) { + xSemaphoreGiveRecursive(mutex->sem); + } else { + xSemaphoreGive(mutex->sem); + } + + return 0; +} + +int pthread_mutex_trylock(pthread_mutex_t *mut) { + struct pthread_mutex *mutex; + int res; + + if (!mut) { + return EINVAL; + } + + if ((intptr_t) *mut == PTHREAD_MUTEX_INITIALIZER) { + if ((res = pthread_mutex_init(mut, NULL))) { + return res; + } + } + + mutex = ( struct pthread_mutex *)(*mut); + + // Try lock + if (mutex->type == PTHREAD_MUTEX_RECURSIVE) { + if (xSemaphoreTakeRecursive(mutex->sem,0 ) != pdTRUE) { + return EBUSY; + } + } else { + if (xSemaphoreTake(mutex->sem,0 ) != pdTRUE) { + return EBUSY; + } + } + + return 0; +} + +int pthread_mutex_destroy(pthread_mutex_t *mut) { + if (!mut) { + return EINVAL; + } + + struct pthread_mutex *mutex = ( struct pthread_mutex *)(*mut); + + if (mutex->type == PTHREAD_MUTEX_RECURSIVE) { + xSemaphoreGiveRecursive(mutex->sem); + } else { + xSemaphoreGive(mutex->sem); + } + + vSemaphoreDelete(mutex->sem); + + return 0; +} + +int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) { + pthread_mutexattr_t temp_attr; + int res; + + // Check attr + if (!attr) { + return EINVAL; + } + + temp_attr.type = type; + + res = _check_attr(&temp_attr); + if (res) { + return res; + } + + attr->type = type; + + return 0; +} + +int pthread_mutexattr_init(pthread_mutexattr_t *attr) { + if (!attr) { + return EINVAL; + } + + attr->type = PTHREAD_MUTEX_NORMAL; + attr->is_initialized = 1; + + return 0; +} |
