Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

116 lines
2.5 KiB

/*
* Copyright © 2021, Keith Packard <keithp@keithp.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "picolibc-hooks.h"
#ifdef CONFIG_MULTITHREADING
#include <sys/lock.h>
/* Define the picolibc lock type */
struct __lock {
struct k_mutex m;
};
STRUCT_SECTION_ITERABLE_ALTERNATE(k_mutex, __lock,
__lock___libc_recursive_mutex) = {
.m = Z_MUTEX_INITIALIZER(__lock___libc_recursive_mutex.m),
};
#ifdef CONFIG_USERSPACE
/* Grant public access to picolibc lock after boot */
static int picolibc_locks_prepare(void)
{
/* Initialise recursive locks */
k_object_access_all_grant(&__lock___libc_recursive_mutex);
return 0;
}
SYS_INIT(picolibc_locks_prepare, POST_KERNEL,
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
#endif /* CONFIG_USERSPACE */
/* Create a new dynamic recursive lock */
void __retarget_lock_init_recursive(_LOCK_T *lock)
{
__ASSERT_NO_MSG(lock != NULL);
/* Allocate mutex object */
#ifndef CONFIG_USERSPACE
*lock = malloc(sizeof(struct __lock));
#else
*lock = k_object_alloc(K_OBJ_MUTEX);
#endif /* !CONFIG_USERSPACE */
__ASSERT(*lock != NULL, "recursive lock allocation failed");
k_mutex_init(&(*lock)->m);
}
/* Create a new dynamic non-recursive lock */
void __retarget_lock_init(_LOCK_T *lock)
{
__retarget_lock_init_recursive(lock);
}
/* Close dynamic recursive lock */
void __retarget_lock_close_recursive(_LOCK_T lock)
{
__ASSERT_NO_MSG(lock != NULL);
#ifndef CONFIG_USERSPACE
free(lock);
#else
k_object_release(lock);
#endif /* !CONFIG_USERSPACE */
}
/* Close dynamic non-recursive lock */
void __retarget_lock_close(_LOCK_T lock)
{
__retarget_lock_close_recursive(lock);
}
/* Acquiure recursive lock */
void __retarget_lock_acquire_recursive(_LOCK_T lock)
{
__ASSERT_NO_MSG(lock != NULL);
k_mutex_lock(&lock->m, K_FOREVER);
}
/* Acquiure non-recursive lock */
void __retarget_lock_acquire(_LOCK_T lock)
{
__retarget_lock_acquire_recursive(lock);
}
/* Try acquiring recursive lock */
int __retarget_lock_try_acquire_recursive(_LOCK_T lock)
{
__ASSERT_NO_MSG(lock != NULL);
return !k_mutex_lock(&lock->m, K_NO_WAIT);
}
/* Try acquiring non-recursive lock */
int __retarget_lock_try_acquire(_LOCK_T lock)
{
return __retarget_lock_try_acquire_recursive(lock);
}
/* Release recursive lock */
void __retarget_lock_release_recursive(_LOCK_T lock)
{
__ASSERT_NO_MSG(lock != NULL);
k_mutex_unlock(&lock->m);
}
/* Release non-recursive lock */
void __retarget_lock_release(_LOCK_T lock)
{
__retarget_lock_release_recursive(lock);
}
#endif /* CONFIG_MULTITHREADING */