77#include "picolibc-hooks.h"
88
99#ifdef CONFIG_MULTITHREADING
10-
11- #include <sys/lock.h>
12-
13- /* Define the picolibc lock type */
10+ /* newlib expects `struct __lock` and `_LOCK_T` to be a pointer to it */
1411struct __lock {
15- struct k_mutex m ;
12+ #ifndef CONFIG_USERSPACE
13+ struct k_mutex mutex ;
14+ #else
15+ struct k_mutex * mutex ;
16+ #endif
1617};
1718
18- STRUCT_SECTION_ITERABLE_ALTERNATE (k_mutex , __lock ,
19- __lock___libc_recursive_mutex ) = {
20- .m = Z_MUTEX_INITIALIZER (__lock___libc_recursive_mutex .m ),
21- };
19+ typedef struct __lock * _LOCK_T ;
2220
23- #ifdef CONFIG_USERSPACE
24- /* Grant public access to picolibc lock after boot */
21+ struct __lock __lock___libc_recursive_mutex ;
22+
23+ /* Initialise recursive locks and grant userspace access after boot */
2524static int picolibc_locks_prepare (void )
2625{
27-
28- /* Initialise recursive locks */
29- k_object_access_all_grant (& __lock___libc_recursive_mutex );
26+ #ifndef CONFIG_USERSPACE
27+ k_mutex_init (& __lock___libc_recursive_mutex .mutex );
28+ #else
29+ __lock___libc_recursive_mutex .mutex = k_object_alloc (K_OBJ_MUTEX );
30+ k_mutex_init (__lock___libc_recursive_mutex .mutex );
31+ k_object_access_all_grant (__lock___libc_recursive_mutex .mutex );
32+ #endif
3033
3134 return 0 ;
3235}
3336
3437SYS_INIT (picolibc_locks_prepare , POST_KERNEL ,
3538 CONFIG_KERNEL_INIT_PRIORITY_DEFAULT );
36- #endif /* CONFIG_USERSPACE */
3739
3840/* Create a new dynamic recursive lock */
3941void __retarget_lock_init_recursive (_LOCK_T * lock )
4042{
4143 __ASSERT_NO_MSG (lock != NULL );
4244
43- /* Allocate mutex object */
45+ /* Allocate lock wrapper and underlying mutex as needed */
46+ struct __lock * obj = malloc (sizeof (struct __lock ));
47+ __ASSERT (obj != NULL , "recursive lock allocation failed" );
48+
4449#ifndef CONFIG_USERSPACE
45- * lock = malloc ( sizeof ( struct __lock ) );
50+ k_mutex_init ( & obj -> mutex );
4651#else
47- * lock = k_object_alloc (K_OBJ_MUTEX );
48- #endif /* !CONFIG_USERSPACE */
49- __ASSERT (* lock != NULL , "recursive lock allocation failed" );
52+ obj -> mutex = k_object_alloc (K_OBJ_MUTEX );
53+ __ASSERT (obj -> mutex != NULL , "k_object_alloc failed" );
54+ k_mutex_init (obj -> mutex );
55+ #endif
5056
51- k_mutex_init ( & ( * lock ) -> m ) ;
57+ * lock = obj ;
5258}
5359
5460/* Create a new dynamic non-recursive lock */
@@ -64,7 +70,10 @@ void __retarget_lock_close_recursive(_LOCK_T lock)
6470#ifndef CONFIG_USERSPACE
6571 free (lock );
6672#else
67- k_object_release (lock );
73+ if (lock -> mutex ) {
74+ k_object_release (lock -> mutex );
75+ }
76+ free (lock );
6877#endif /* !CONFIG_USERSPACE */
6978}
7079
@@ -78,7 +87,11 @@ void __retarget_lock_close(_LOCK_T lock)
7887void __retarget_lock_acquire_recursive (_LOCK_T lock )
7988{
8089 __ASSERT_NO_MSG (lock != NULL );
81- k_mutex_lock (& lock -> m , K_FOREVER );
90+ #ifndef CONFIG_USERSPACE
91+ k_mutex_lock (& lock -> mutex , K_FOREVER );
92+ #else
93+ k_mutex_lock (lock -> mutex , K_FOREVER );
94+ #endif
8295}
8396
8497/* Acquiure non-recursive lock */
@@ -91,7 +104,11 @@ void __retarget_lock_acquire(_LOCK_T lock)
91104int __retarget_lock_try_acquire_recursive (_LOCK_T lock )
92105{
93106 __ASSERT_NO_MSG (lock != NULL );
94- return !k_mutex_lock (& lock -> m , K_NO_WAIT );
107+ #ifndef CONFIG_USERSPACE
108+ return !k_mutex_lock (& lock -> mutex , K_NO_WAIT );
109+ #else
110+ return !k_mutex_lock (lock -> mutex , K_NO_WAIT );
111+ #endif
95112}
96113
97114/* Try acquiring non-recursive lock */
@@ -104,7 +121,11 @@ int __retarget_lock_try_acquire(_LOCK_T lock)
104121void __retarget_lock_release_recursive (_LOCK_T lock )
105122{
106123 __ASSERT_NO_MSG (lock != NULL );
107- k_mutex_unlock (& lock -> m );
124+ #ifndef CONFIG_USERSPACE
125+ k_mutex_unlock (& lock -> mutex );
126+ #else
127+ k_mutex_unlock (lock -> mutex );
128+ #endif
108129}
109130
110131/* Release non-recursive lock */
0 commit comments