luckfox-pico-sdk/sysdrv/source/mcu/rt-thread/components/libc/pthreads/pthread_mutex.c
luckfox-eng29 8f34c2760d project:build.sh: Added fastboot support; custom modifications to U-Boot and kernel implemented using patches.
project:cfg:BoardConfig_IPC: Added fastboot BoardConfig file and firmware post-scripts, distinguishing between
the BoardConfigs for Luckfox Pico Pro and Luckfox Pico Max. project:app: Added fastboot_client and rk_smart_door
for quick boot applications; updated rkipc app to adapt to the latest media library. media:samples: Added more
usage examples. media:rockit: Fixed bugs; removed support for retrieving data frames from VPSS. media:isp:
Updated rkaiq library and related tools to support connection to RKISP_Tuner. sysdrv:Makefile: Added support for
compiling drv_ko on Luckfox Pico Ultra W using Ubuntu; added support for custom root filesystem.
sysdrv:tools:board: Updated Buildroot optional mirror sources, updated some software versions, and stored device
tree files and configuration files that undergo multiple modifications for U-Boot and kernel separately.
sysdrv:source:mcu: Used RISC-V MCU SDK with RT-Thread system, mainly for initializing camera AE during quick
boot. sysdrv:source:uboot: Added support for fastboot; added high baud rate DDR bin for serial firmware upgrades.
sysdrv:source:kernel: Upgraded to version 5.10.160; increased NPU frequency for RV1106G3; added support for
fastboot.

Signed-off-by: luckfox-eng29 <eng29@luckfox.com>
2024-10-14 09:47:04 +08:00

249 lines
5.2 KiB
C

/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-10-26 Bernard the first version
*/
#include <rtthread.h>
#include "pthread.h"
#define MUTEXATTR_SHARED_MASK 0x0010
#define MUTEXATTR_TYPE_MASK 0x000f
const pthread_mutexattr_t pthread_default_mutexattr = PTHREAD_PROCESS_PRIVATE;
int pthread_mutexattr_init(pthread_mutexattr_t *attr)
{
if (attr)
{
*attr = pthread_default_mutexattr;
return 0;
}
return EINVAL;
}
RTM_EXPORT(pthread_mutexattr_init);
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
{
if (attr)
{
*attr = -1;
return 0;
}
return EINVAL;
}
RTM_EXPORT(pthread_mutexattr_destroy);
int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type)
{
if (attr && type)
{
int atype = (*attr & MUTEXATTR_TYPE_MASK);
if (atype >= PTHREAD_MUTEX_NORMAL && atype <= PTHREAD_MUTEX_ERRORCHECK)
{
*type = atype;
return 0;
}
}
return EINVAL;
}
RTM_EXPORT(pthread_mutexattr_gettype);
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
{
if (attr && type >= PTHREAD_MUTEX_NORMAL && type <= PTHREAD_MUTEX_ERRORCHECK)
{
*attr = (*attr & ~MUTEXATTR_TYPE_MASK) | type;
return 0;
}
return EINVAL;
}
RTM_EXPORT(pthread_mutexattr_settype);
int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared)
{
if (!attr)
return EINVAL;
switch (pshared)
{
case PTHREAD_PROCESS_PRIVATE:
*attr &= ~MUTEXATTR_SHARED_MASK;
return 0;
case PTHREAD_PROCESS_SHARED:
*attr |= MUTEXATTR_SHARED_MASK;
return 0;
}
return EINVAL;
}
RTM_EXPORT(pthread_mutexattr_setpshared);
int pthread_mutexattr_getpshared(pthread_mutexattr_t *attr, int *pshared)
{
if (!attr || !pshared)
return EINVAL;
*pshared = (*attr & MUTEXATTR_SHARED_MASK) ? PTHREAD_PROCESS_SHARED
: PTHREAD_PROCESS_PRIVATE;
return 0;
}
RTM_EXPORT(pthread_mutexattr_getpshared);
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
{
rt_err_t result;
char name[RT_NAME_MAX];
static rt_uint16_t pthread_mutex_number = 0;
if (!mutex)
return EINVAL;
/* build mutex name */
rt_snprintf(name, sizeof(name), "pmtx%02d", pthread_mutex_number ++);
if (attr == RT_NULL)
mutex->attr = pthread_default_mutexattr;
else
mutex->attr = *attr;
/* init mutex lock */
result = rt_mutex_init(&(mutex->lock), name, RT_IPC_FLAG_FIFO);
if (result != RT_EOK)
return EINVAL;
/* detach the object from system object container */
rt_object_detach(&(mutex->lock.parent.parent));
mutex->lock.parent.parent.type = RT_Object_Class_Mutex;
return 0;
}
RTM_EXPORT(pthread_mutex_init);
int pthread_mutex_destroy(pthread_mutex_t *mutex)
{
if (!mutex || mutex->attr == -1)
return EINVAL;
/* it's busy */
if (mutex->lock.owner != RT_NULL)
return EBUSY;
rt_memset(mutex, 0, sizeof(pthread_mutex_t));
mutex->attr = -1;
return 0;
}
RTM_EXPORT(pthread_mutex_destroy);
int pthread_mutex_lock(pthread_mutex_t *mutex)
{
int mtype;
rt_err_t result;
if (!mutex)
return EINVAL;
if (mutex->attr == -1)
{
/* init mutex */
pthread_mutex_init(mutex, RT_NULL);
}
mtype = mutex->attr & MUTEXATTR_TYPE_MASK;
rt_enter_critical();
if (mutex->lock.owner == rt_thread_self() &&
mtype != PTHREAD_MUTEX_RECURSIVE)
{
rt_exit_critical();
return EDEADLK;
}
rt_exit_critical();
result = rt_mutex_take(&(mutex->lock), RT_WAITING_FOREVER);
if (result == RT_EOK)
return 0;
return EINVAL;
}
RTM_EXPORT(pthread_mutex_lock);
int pthread_mutex_unlock(pthread_mutex_t *mutex)
{
rt_err_t result;
if (!mutex)
return EINVAL;
if (mutex->attr == -1)
{
/* init mutex */
pthread_mutex_init(mutex, RT_NULL);
}
if (mutex->lock.owner != rt_thread_self())
{
int mtype;
mtype = mutex->attr & MUTEXATTR_TYPE_MASK;
/* error check, return EPERM */
if (mtype == PTHREAD_MUTEX_ERRORCHECK)
return EPERM;
/* no thread waiting on this mutex */
if (mutex->lock.owner == RT_NULL)
return 0;
}
result = rt_mutex_release(&(mutex->lock));
if (result == RT_EOK)
return 0;
return EINVAL;
}
RTM_EXPORT(pthread_mutex_unlock);
int pthread_mutex_trylock(pthread_mutex_t *mutex)
{
rt_err_t result;
int mtype;
if (!mutex)
return EINVAL;
if (mutex->attr == -1)
{
/* init mutex */
pthread_mutex_init(mutex, RT_NULL);
}
mtype = mutex->attr & MUTEXATTR_TYPE_MASK;
rt_enter_critical();
if (mutex->lock.owner == rt_thread_self() &&
mtype != PTHREAD_MUTEX_RECURSIVE)
{
rt_exit_critical();
return EDEADLK;
}
rt_exit_critical();
result = rt_mutex_take(&(mutex->lock), 0);
if (result == RT_EOK) return 0;
return EBUSY;
}
RTM_EXPORT(pthread_mutex_trylock);