Re: Question on __retarget_lock function

[email protected]
Newsgroups gmane.comp.lib.newlib
Message-ID <[email protected]>
On 07/12/2024 08:58, Kedar Karandikar wrote:
> Hi
> I am trying to override the __retarget_lock* dummy functions that are 
> provided by NewLib lock.c in my baremetal environment.
> 
> I was trying not to touch the newlib source code, but rather implement 
> those functions in my framework.
> 
> However, the functions defined in lock.c do not have a “weak” attribute 
> next to the functions and this causes linker error when I try to define 
> them in my framework.
> 
> Any reason why they are not defined as weak? Is the expectation that I 
> update the functions directly in newlib lock.c and compile the newlib 
> after that?
> 
> Thanks for the help!
> 
> -Kedar K Karandikar

I had the same problem with the version of Newlib provided with the GCC 
toolchain with STM's STM32CubeIDE. (And the OpenSTM32 Workbench one as 
well.)

The problem is that 'struct _lock' and _LOCK_T (struct _lock *) are 
supposed to be defined by the target platform implementer. Because of 
this, the functions cannot be defined as weak so as to be overridable by 
the end user.

Newlib's lock.c is simply an example dummy implementation but STM in 
their stupidity chose to simply compile in this code which defines 
struct _lock as being a single byte structure.

That makes reimplementing for, say, FreeRTOS tricky. What I did was use 
GCC's symbol wrapper to reimplement all the __retarget_lock_xxxx() 
functions and overlay them in the linker. (See the GCC LD --wrap option.)

The functions can simply cast the _LOCK_T arguments to pointers to the 
real mutex objects (e.g. cast to SemaphoreHandle_t which is itself a 
pointer to an opaque mutex object) and do similar for the _LOCK_T 
pointer output parameters in the init functions after obtaining a mutex 
pointer from the threading library.

However all the wrapper functions check their  _LOCK_T arguments against 
a static lookup table mapping from pointers to the predefined library 
lock objects (e.g. &__lock___sinit_recursive_mutex) to actual mutex 
objects/object pointers values.

Before starting the main() and switching into multithreaded mode, I call 
an internal function that creates/initialized recursive or non-recursive 
mutexes as appropriate for all the NULL SemaphoreHandle_t values in the 
lookup table.

It's messy but it works.

Unfortunately, that's just the start of your problem if your vendor has 
compiled in the dummy lock.c. If they've compiled GCC single-threaded, 
the C++ STL, C & C++ atomics either aren't implemented or aren't thread 
safe either which has knock-on effects for everything else in the C++ 
libraries when using a pre-emptive threading library

A better approach to take if you have the time is to bite the bullet and 
create your own GCC & newlib toolchain, provide the required stubs for 
all newlib's locking and for POSIX threads using your threading library 
and compile GCC as POSIX-thread aware. That way all the C/C++ atomics 
and Newlib APIs are fully reentrant. But it's a much bigger job of course.

-- 
Sam Edge
OpenPGP_0xE6200DE0C92CEC06_and_old_rev.asc (application/pgp-keys, 1.1 KB)
-----BEGIN PGP PUBLIC KEY BLOCK-----

xjMEZRUsPRYJKwYBBAHaRw8BAQdAJJIM3nIi/0AlR8YNKSbIucsGaX/dfmp7oBLT
C6Di1UHNIlNhbSBFZGdlIDxzYW0uZWRnZS5uZXdsaWJAZ214LmNvbT7CjwQTFggA
NxYhBNdZ6mE651AobMQsM+YgDeDJLOwGBQJlFSw9BQkSzAMAAhsDBAsJCAcFFQgJ
CgsFFgIDAQAACgkQ5iAN4Mks7AY5JAEApAAHuSOu21+x2uLpSmN2mi/yCAS5cGpy
OYfUVJ6kTloA+wVEhOFeeRAl8jQCEw0QOki/+7hGW1N9z3qG+ND14vUIzjgEZRUs
PRIKKwYBBAGXVQEFAQEHQKiCziMIYxB6C419NstmKUgH6/TQ0DmtAqBhhBjEC9UZ
AwEIB8J+BBgWCAAmFiEE11nqYTrnUChsxCwz5iAN4Mks7AYFAmUVLD0FCRLMAwAC
GwwACgkQ5iAN4Mks7AbuRgD+IQL27tV1vjSXHL0uKObS+pcZETsH3FA1LwR8cZw3
3x4A/iqA04meXfecoyi3lr5O20NsWSsucpzazIAH8hYzrT0OxjMEZRUsPBYJKwYB
BAHaRw8BAQdAfTvjyHM/Oum9+RhQ4sczPMQ3qZ1rvy+R7xOgV5fIpWLCeAQgFggA
IBYhBNT+XGXKdDxOakWZc0GqKxqf/+MDBQJlFTKLAh0AAAoJEEGqKxqf/+MDuTEA
/0gy4cxdzIE7hL3ehbcjmkpqc0CHnkbYPnUsweMxZAcTAQCKWOy7f66LyqsImOHg
EBCQ+ttUK1xX+fl7wtoeeG/RBc44BGUVLDwSCisGAQQBl1UBBQEBB0DNsJdpv0iR
5XIyxFG8OSqDQojGSVmaSCFwiUXjRxwPDAMBCAfCfgQYFggAJhYhBNT+XGXKdDxO
akWZc0GqKxqf/+MDBQJlFSw8BQkSzAMAAhsMAAoJEEGqKxqf/+MDY84BALkIC2Ao
5uqJlP2hIfRyAlDO3CiGB+pcoPqfL+yTLFQzAP46VlC/2Ll0LI3tBmYZ0aDLu0N+
bN3b0msL+HioGuigBg==
=R8EG
-----END PGP PUBLIC KEY BLOCK-----
OpenPGP_signature.asc (application/pgp-signature, 236 B)
-----BEGIN PGP SIGNATURE-----

wnsEABYIACMWIQTXWephOudQKGzELDPmIA3gySzsBgUCZ1QrnAUDAAAAAAAKCRDmIA3gySzsBs+J
APwKhDT3c7CJ8bhHwy9YtpAshvdyMbpbNeFLiIx5kNswIwD/YqhLAOtawC5CKuTqdRkfe10nJjCr
C7xioXy/HjFMEAg=
=Bcms
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.