public inbox for newlib@sourceware.org
 help / color / mirror / Atom feed
* [PATCH, newlib] Allow locking routine to be retargeted
@ 2016-12-13 17:18 Thomas Preudhomme
  2016-12-13 20:13 ` Freddie Chopin
                   ` (3 more replies)
  0 siblings, 4 replies; 51+ messages in thread
From: Thomas Preudhomme @ 2016-12-13 17:18 UTC (permalink / raw)
  To: newlib

[-- Attachment #1: Type: text/plain, Size: 1088 bytes --]

Hi,

At the moment when targeting bare-metal targets or systems without definition 
for the locking primitives newlib, uses dummy empty macros. This has the 
advantage of reduced size and faster implementation but does not allow the 
application to retarget the locking routines. Retargeting is useful for a single 
toolchain to support multiple systems since then it's only at build time that 
you know which system you are targeting.

This patch adds a new configure option --enable-newlib-retargetable-locking to 
use dummy empty weakly defined functions instead of dummy empty macros. The 
default is to keep the current behavior to not have any size or speed impact on 
targets not interested in this feature.

Testing: I've built a simple test program that calls malloc and free with all 
the locking function defined in the same file. Running into a debugger with 
breakpoints on the function shows that they are indeed called. Newlib testsuite 
(the 30 tests that run wich check-target-newlib from GCC) also comes back clean.

Is this ok for master branch?

Best regards,

Thomas

[-- Attachment #2: newlib_retargetable_locking_routine.patch --]
[-- Type: text/x-patch, Size: 23620 bytes --]

diff --git a/newlib/configure b/newlib/configure
index 30e1d57664302248af9087b0051290e2aff4b382..42b1e13feeda8a5b7ad3cf365393bd4640da4c8c 100755
--- a/newlib/configure
+++ b/newlib/configure
@@ -798,6 +798,7 @@ enable_newlib_nano_malloc
 enable_newlib_unbuf_stream_opt
 enable_lite_exit
 enable_newlib_nano_formatted_io
+enable_newlib_retargetable_locking
 enable_multilib
 enable_target_optspace
 enable_malloc_debugging
@@ -1469,6 +1470,7 @@ Optional Features:
   --disable-newlib-unbuf-stream-opt    disable unbuffered stream optimization in streamio
   --enable-lite-exit	enable light weight exit
   --enable-newlib-nano-formatted-io    Use nano version formatted IO
+  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time
   --enable-multilib         build many library versions (default)
   --enable-target-optspace  optimize for space
   --enable-malloc-debugging indicate malloc debugging requested
@@ -2470,6 +2472,18 @@ else
 fi
 
 
+# Check whether --enable-newlib-retargetable-locking was given.
+if test "${enable_newlib_retargetable_locking+set}" = set; then :
+  enableval=$enable_newlib_retargetable_locking; case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_locking=no ;;
+   *) as_fn_error $? "bad value ${enableval} for newlib-retargetable-locking" "$LINENO" 5 ;;
+ esac
+else
+  newlib_retargetable_locking=no
+fi
+
+
 
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
@@ -11776,7 +11790,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11779 "configure"
+#line 11793 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11882,7 +11896,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11885 "configure"
+#line 11899 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12421,6 +12435,13 @@ _ACEOF
 
 fi
 
+if test "${newlib_retargetable_locking}" = "yes"; then
+cat >>confdefs.h <<_ACEOF
+#define _RETARGETABLE_LOCKING 1
+_ACEOF
+
+fi
+
 
 if test "x${iconv_encodings}" != "x" \
    || test "x${iconv_to_encodings}" != "x" \
diff --git a/newlib/configure.in b/newlib/configure.in
index 01c6367a99cdf6f74a5ad15c8a4eb4a45f206e9d..70cffa76a966f8d9cd1c8888156002e76ea13dc2 100644
--- a/newlib/configure.in
+++ b/newlib/configure.in
@@ -218,6 +218,17 @@ AC_ARG_ENABLE(newlib_nano_formatted_io,
    *) AC_MSG_ERROR(bad value ${enableval} for newlib-nano-formatted-io) ;;
  esac],[newlib_nano_formatted_io=no])
 
+dnl Support --enable-retargetable-locking
+dnl This option is also read in libc/configure.in.  It is repeated
+dnl here so that it shows up in the help text.
+AC_ARG_ENABLE(newlib-retargetable-locking,
+[  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time],
+[case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_locking=no ;;
+   *) AC_MSG_ERROR(bad value ${enableval} for newlib-retargetable-locking) ;;
+ esac],[newlib_retargetable_locking=no])
+
 NEWLIB_CONFIGURE(.)
 
 dnl We have to enable libtool after NEWLIB_CONFIGURE because if we try and
@@ -442,6 +453,10 @@ if test "${newlib_nano_formatted_io}" = "yes"; then
 AC_DEFINE_UNQUOTED(_NANO_FORMATTED_IO)
 fi
 
+if test "${newlib_retargetable_locking}" = "yes"; then
+AC_DEFINE_UNQUOTED(_RETARGETABLE_LOCKING)
+fi
+
 dnl
 dnl Parse --enable-newlib-iconv-encodings option argument
 dnl
diff --git a/newlib/libc/configure b/newlib/libc/configure
index 5dccc852b8cd90d697a90f113ec17982741ecc3a..35077b81550aa999026ff67a7428fec6509a26ce 100755
--- a/newlib/libc/configure
+++ b/newlib/libc/configure
@@ -751,6 +751,8 @@ build
 newlib_basedir
 MAY_SUPPLY_SYSCALLS_FALSE
 MAY_SUPPLY_SYSCALLS_TRUE
+NEWLIB_RETARGETABLE_LOCKING_FALSE
+NEWLIB_RETARGETABLE_LOCKING_TRUE
 NEWLIB_NANO_FORMATTED_IO_FALSE
 NEWLIB_NANO_FORMATTED_IO_TRUE
 target_alias
@@ -797,6 +799,7 @@ enable_option_checking
 enable_newlib_io_pos_args
 enable_newlib_nano_malloc
 enable_newlib_nano_formatted_io
+enable_newlib_retargetable_locking
 enable_multilib
 enable_target_optspace
 enable_malloc_debugging
@@ -1448,6 +1451,7 @@ Optional Features:
   --enable-newlib-io-pos-args enable printf-family positional arg support
   --enable-newlib-nano-malloc    Use small-footprint nano-malloc implementation
   --enable-newlib-nano-formatted-io    Use small-footprint nano-formatted-IO implementation
+  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time
   --enable-multilib         build many library versions (default)
   --enable-target-optspace  optimize for space
   --enable-malloc-debugging indicate malloc debugging requested
@@ -2252,6 +2256,26 @@ else
 fi
 
 
+# Check whether --enable-newlib-retargetable-locking was given.
+if test "${enable_newlib_retargetable_locking+set}" = set; then :
+  enableval=$enable_newlib_retargetable_locking; case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_lock=no ;;
+   *) as_fn_error $? "bad value ${enableval} for newlib-retargetable-locking" "$LINENO" 5 ;;
+ esac
+else
+  newlib_retargetable_locking=no
+fi
+
+ if test x$newlib_retargetable_locking = xyes; then
+  NEWLIB_RETARGETABLE_LOCKING_TRUE=
+  NEWLIB_RETARGETABLE_LOCKING_FALSE='#'
+else
+  NEWLIB_RETARGETABLE_LOCKING_TRUE='#'
+  NEWLIB_RETARGETABLE_LOCKING_FALSE=
+fi
+
+
 
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
@@ -11525,7 +11549,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11528 "configure"
+#line 11552 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11631,7 +11655,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11634 "configure"
+#line 11658 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12248,6 +12272,10 @@ if test -z "${NEWLIB_NANO_FORMATTED_IO_TRUE}" && test -z "${NEWLIB_NANO_FORMATTE
   as_fn_error $? "conditional \"NEWLIB_NANO_FORMATTED_IO\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${NEWLIB_RETARGETABLE_LOCKING_TRUE}" && test -z "${NEWLIB_RETARGETABLE_LOCKING_FALSE}"; then
+  as_fn_error $? "conditional \"NEWLIB_RETARGETABLE_LOCKING\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${MAY_SUPPLY_SYSCALLS_TRUE}" && test -z "${MAY_SUPPLY_SYSCALLS_FALSE}"; then
   as_fn_error $? "conditional \"MAY_SUPPLY_SYSCALLS\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
diff --git a/newlib/libc/configure.in b/newlib/libc/configure.in
index 0a7bb8815be44fb1e92f753fa2c8df2a31b95f94..ac25a3933c4a4794f3cfe291e0275d0ed001b96a 100644
--- a/newlib/libc/configure.in
+++ b/newlib/libc/configure.in
@@ -36,6 +36,16 @@ AC_ARG_ENABLE(newlib_nano_formatted_io,
  esac],[newlib_nano_formatted_io=no])
 AM_CONDITIONAL(NEWLIB_NANO_FORMATTED_IO, test x$newlib_nano_formatted_io = xyes)
 
+dnl Support --enable-retargetable-locking used by libc/sys
+AC_ARG_ENABLE(newlib-retargetable-locking,
+[  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time],
+[case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_lock=no ;;
+   *) AC_MSG_ERROR(bad value ${enableval} for newlib-retargetable-locking) ;;
+ esac],[newlib_retargetable_locking=no])
+AM_CONDITIONAL(NEWLIB_RETARGETABLE_LOCKING, test x$newlib_retargetable_locking = xyes)
+
 NEWLIB_CONFIGURE(..)
 
 AM_CONDITIONAL(NEWLIB_NANO_MALLOC, test x$newlib_nano_malloc = xyes)
diff --git a/newlib/libc/include/sys/lock.h b/newlib/libc/include/sys/lock.h
index 9075e35c9179968031010432515e3a845ff6ca8d..e5bdcd001ea348bac6a77d45eeb1b48f7ef2a69a 100644
--- a/newlib/libc/include/sys/lock.h
+++ b/newlib/libc/include/sys/lock.h
@@ -3,10 +3,13 @@
 
 /* dummy lock routines for single-threaded aps */
 
+#include <newlib.h>
+#include <_ansi.h>
+
+#ifndef _RETARGETABLE_LOCKING
+
 typedef int _LOCK_T;
 typedef int _LOCK_RECURSIVE_T;
- 
-#include <_ansi.h>
 
 #define __LOCK_INIT(class,lock) static int lock = 0;
 #define __LOCK_INIT_RECURSIVE(class,lock) static int lock = 0;
@@ -21,4 +24,37 @@ typedef int _LOCK_RECURSIVE_T;
 #define __lock_release(lock) (_CAST_VOID 0)
 #define __lock_release_recursive(lock) (_CAST_VOID 0)
 
+#else
+
+typedef void * _LOCK_T;
+#define _LOCK_RECURSIVE_T _LOCK_T
+
+#define __LOCK_INIT(class,lock) extern struct _lock _lock_ ## lock; \
+	class _LOCK_T lock = &_lock_ ## lock
+#define __LOCK_INIT_RECURSIVE(class,lock) __LOCK_INIT(class,lock)
+
+extern void __retarget_lock_init(_LOCK_T *lock);
+#define __lock_init(lock) __retarget_lock_init(&lock)
+extern void __retarget_lock_init_recursive(_LOCK_T *lock);
+#define __lock_init_recursive(lock) __retarget_lock_init_recursive(&lock)
+extern void __retarget_lock_close(_LOCK_T lock);
+#define __lock_close(lock) __retarget_lock_close(lock)
+extern void __retarget_lock_close_recursive(_LOCK_T lock);
+#define __lock_close_recursive(lock) __retarget_lock_close_recursive(lock)
+extern void __retarget_lock_acquire(_LOCK_T lock);
+#define __lock_acquire(lock) __retarget_lock_acquire(lock)
+extern void __retarget_lock_acquire_recursive(_LOCK_T lock);
+#define __lock_acquire_recursive(lock) __retarget_lock_acquire_recursive(lock)
+extern int __retarget_lock_try_acquire(_LOCK_T lock);
+#define __lock_try_acquire(lock) __retarget_lock_try_acquire(lock)
+extern int __retarget_lock_try_acquire_recursive(_LOCK_T lock);
+#define __lock_try_acquire_recursive(lock) \
+  __retarget_lock_try_acquire_recursive(lock)
+extern void __retarget_lock_release(_LOCK_T lock);
+#define __lock_release(lock) __retarget_lock_release(lock)
+extern void __retarget_lock_release_recursive(_LOCK_T lock);
+#define __lock_release_recursive(lock) __retarget_lock_release_recursive(lock)
+
+#endif /* _RETARGETABLE_LOCKING */
+
 #endif /* __SYS_LOCK_H__ */
diff --git a/newlib/libc/stdlib/Makefile.am b/newlib/libc/stdlib/Makefile.am
index 2d45d1029ace8087b57657cbc11feabf76f4206e..76ed8480c28ebfb68e2f48432c0359b11f1522a8 100644
--- a/newlib/libc/stdlib/Makefile.am
+++ b/newlib/libc/stdlib/Makefile.am
@@ -74,6 +74,11 @@ GENERAL_SOURCES += \
 	wcstold.c
 endif # HAVE_LONG_DOUBLE
 
+if NEWLIB_RETARGETABLE_LOCKING
+GENERAL_SOURCES += \
+	lock.c
+endif
+
 if NEWLIB_NANO_MALLOC
 MALIGNR=nano-malignr
 MALLOPTR=nano-malloptr
diff --git a/newlib/libc/stdlib/Makefile.in b/newlib/libc/stdlib/Makefile.in
index 466ab6d1e02ea919f6c8ceed792024955bef1a66..3295e981c87bac3b21a6b72dda148f892fe018d6 100644
--- a/newlib/libc/stdlib/Makefile.in
+++ b/newlib/libc/stdlib/Makefile.in
@@ -57,6 +57,9 @@ host_triplet = @host@
 @HAVE_LONG_DOUBLE_TRUE@	strtold.c \
 @HAVE_LONG_DOUBLE_TRUE@	wcstold.c
 
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@am__append_2 = \
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@	lock.c
+
 DIST_COMMON = $(srcdir)/../../Makefile.shared $(srcdir)/Makefile.in \
 	$(srcdir)/Makefile.am
 subdir = stdlib
@@ -81,7 +84,9 @@ lib_a_AR = $(AR) $(ARFLAGS)
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(ELIX_2_OBJS)
 @HAVE_LONG_DOUBLE_TRUE@am__objects_1 = lib_a-strtold.$(OBJEXT) \
 @HAVE_LONG_DOUBLE_TRUE@	lib_a-wcstold.$(OBJEXT)
-am__objects_2 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@am__objects_2 =  \
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@	lib_a-lock.$(OBJEXT)
+am__objects_3 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \
 	lib_a-__call_atexit.$(OBJEXT) lib_a-__exp10.$(OBJEXT) \
 	lib_a-__ten_mu.$(OBJEXT) lib_a-_Exit.$(OBJEXT) \
 	lib_a-abort.$(OBJEXT) lib_a-abs.$(OBJEXT) \
@@ -112,8 +117,8 @@ am__objects_2 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \
 	lib_a-wcstol.$(OBJEXT) lib_a-wcstoul.$(OBJEXT) \
 	lib_a-wcstombs.$(OBJEXT) lib_a-wcstombs_r.$(OBJEXT) \
 	lib_a-wctomb.$(OBJEXT) lib_a-wctomb_r.$(OBJEXT) \
-	$(am__objects_1)
-am__objects_3 = lib_a-arc4random.$(OBJEXT) \
+	$(am__objects_1) $(am__objects_2)
+am__objects_4 = lib_a-arc4random.$(OBJEXT) \
 	lib_a-arc4random_uniform.$(OBJEXT) lib_a-cxa_atexit.$(OBJEXT) \
 	lib_a-cxa_finalize.$(OBJEXT) lib_a-drand48.$(OBJEXT) \
 	lib_a-ecvtbuf.$(OBJEXT) lib_a-efgcvt.$(OBJEXT) \
@@ -128,7 +133,7 @@ am__objects_3 = lib_a-arc4random.$(OBJEXT) \
 	lib_a-wcstoll_r.$(OBJEXT) lib_a-wcstoull.$(OBJEXT) \
 	lib_a-wcstoull_r.$(OBJEXT) lib_a-atoll.$(OBJEXT) \
 	lib_a-llabs.$(OBJEXT) lib_a-lldiv.$(OBJEXT)
-am__objects_4 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \
+am__objects_5 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \
 	lib_a-getopt.$(OBJEXT) lib_a-getsubopt.$(OBJEXT) \
 	lib_a-l64a.$(OBJEXT) lib_a-malign.$(OBJEXT) \
 	lib_a-mbrlen.$(OBJEXT) lib_a-mbrtowc.$(OBJEXT) \
@@ -137,22 +142,23 @@ am__objects_4 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \
 	lib_a-valloc.$(OBJEXT) lib_a-wcrtomb.$(OBJEXT) \
 	lib_a-wcsnrtombs.$(OBJEXT) lib_a-wcsrtombs.$(OBJEXT) \
 	lib_a-wctob.$(OBJEXT)
-am__objects_5 = lib_a-putenv.$(OBJEXT) lib_a-putenv_r.$(OBJEXT) \
+am__objects_6 = lib_a-putenv.$(OBJEXT) lib_a-putenv_r.$(OBJEXT) \
 	lib_a-setenv.$(OBJEXT) lib_a-setenv_r.$(OBJEXT)
-am__objects_6 = lib_a-rpmatch.$(OBJEXT) lib_a-system.$(OBJEXT)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_7 = $(am__objects_4) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_5) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_6)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_7 = $(am__objects_4) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_5)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_7 =  \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_4)
-@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_2) \
-@USE_LIBTOOL_FALSE@	$(am__objects_3) $(am__objects_7)
+am__objects_7 = lib_a-rpmatch.$(OBJEXT) lib_a-system.$(OBJEXT)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_8 = $(am__objects_5) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_6) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_7)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_8 = $(am__objects_5) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_6)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_8 =  \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_5)
+@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_3) \
+@USE_LIBTOOL_FALSE@	$(am__objects_4) $(am__objects_8)
 lib_a_OBJECTS = $(am_lib_a_OBJECTS)
 LTLIBRARIES = $(noinst_LTLIBRARIES)
-@HAVE_LONG_DOUBLE_TRUE@am__objects_8 = strtold.lo wcstold.lo
-am__objects_9 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \
+@HAVE_LONG_DOUBLE_TRUE@am__objects_9 = strtold.lo wcstold.lo
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@am__objects_10 = lock.lo
+am__objects_11 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \
 	__ten_mu.lo _Exit.lo abort.lo abs.lo aligned_alloc.lo \
 	assert.lo atexit.lo atof.lo atoff.lo atoi.lo atol.lo calloc.lo \
 	div.lo dtoa.lo dtoastub.lo environ.lo envlock.lo eprintf.lo \
@@ -163,28 +169,28 @@ am__objects_9 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \
 	rand_r.lo random.lo realloc.lo reallocf.lo sb_charsets.lo \
 	strtod.lo strtodg.lo strtol.lo strtorx.lo strtoul.lo utoa.lo \
 	wcstod.lo wcstol.lo wcstoul.lo wcstombs.lo wcstombs_r.lo \
-	wctomb.lo wctomb_r.lo $(am__objects_8)
-am__objects_10 = arc4random.lo arc4random_uniform.lo cxa_atexit.lo \
+	wctomb.lo wctomb_r.lo $(am__objects_9) $(am__objects_10)
+am__objects_12 = arc4random.lo arc4random_uniform.lo cxa_atexit.lo \
 	cxa_finalize.lo drand48.lo ecvtbuf.lo efgcvt.lo erand48.lo \
 	jrand48.lo lcong48.lo lrand48.lo mrand48.lo msize.lo mtrim.lo \
 	nrand48.lo rand48.lo seed48.lo srand48.lo strtoll.lo \
 	strtoll_r.lo strtoull.lo strtoull_r.lo wcstoll.lo wcstoll_r.lo \
 	wcstoull.lo wcstoull_r.lo atoll.lo llabs.lo lldiv.lo
-am__objects_11 = a64l.lo btowc.lo getopt.lo getsubopt.lo l64a.lo \
+am__objects_13 = a64l.lo btowc.lo getopt.lo getsubopt.lo l64a.lo \
 	malign.lo mbrlen.lo mbrtowc.lo mbsinit.lo mbsnrtowcs.lo \
 	mbsrtowcs.lo on_exit.lo valloc.lo wcrtomb.lo wcsnrtombs.lo \
 	wcsrtombs.lo wctob.lo
-am__objects_12 = putenv.lo putenv_r.lo setenv.lo setenv_r.lo
-am__objects_13 = rpmatch.lo system.lo
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_14 = $(am__objects_11) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_12) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_13)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_14 = $(am__objects_11) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_12)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_14 =  \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_11)
-@USE_LIBTOOL_TRUE@am_libstdlib_la_OBJECTS = $(am__objects_9) \
-@USE_LIBTOOL_TRUE@	$(am__objects_10) $(am__objects_14)
+am__objects_14 = putenv.lo putenv_r.lo setenv.lo setenv_r.lo
+am__objects_15 = rpmatch.lo system.lo
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_16 = $(am__objects_13) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_14) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_15)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_16 = $(am__objects_13) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_14)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_16 =  \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_13)
+@USE_LIBTOOL_TRUE@am_libstdlib_la_OBJECTS = $(am__objects_11) \
+@USE_LIBTOOL_TRUE@	$(am__objects_12) $(am__objects_16)
 libstdlib_la_OBJECTS = $(am_libstdlib_la_OBJECTS)
 libstdlib_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -367,7 +373,7 @@ GENERAL_SOURCES = __adjust.c __atexit.c __call_atexit.c __exp10.c \
 	quick_exit.c rand.c rand_r.c random.c realloc.c reallocf.c \
 	sb_charsets.c strtod.c strtodg.c strtol.c strtorx.c strtoul.c \
 	utoa.c wcstod.c wcstol.c wcstoul.c wcstombs.c wcstombs_r.c \
-	wctomb.c wctomb_r.c $(am__append_1)
+	wctomb.c wctomb_r.c $(am__append_1) $(am__append_2)
 @NEWLIB_NANO_MALLOC_FALSE@MALIGNR = malignr
 @NEWLIB_NANO_MALLOC_TRUE@MALIGNR = nano-malignr
 @NEWLIB_NANO_MALLOC_FALSE@MALLOPTR = malloptr
@@ -1002,6 +1008,12 @@ lib_a-wcstold.o: wcstold.c
 lib_a-wcstold.obj: wcstold.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcstold.obj `if test -f 'wcstold.c'; then $(CYGPATH_W) 'wcstold.c'; else $(CYGPATH_W) '$(srcdir)/wcstold.c'; fi`
 
+lib_a-lock.o: lock.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lock.o `test -f 'lock.c' || echo '$(srcdir)/'`lock.c
+
+lib_a-lock.obj: lock.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lock.obj `if test -f 'lock.c'; then $(CYGPATH_W) 'lock.c'; else $(CYGPATH_W) '$(srcdir)/lock.c'; fi`
+
 lib_a-arc4random.o: arc4random.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-arc4random.o `test -f 'arc4random.c' || echo '$(srcdir)/'`arc4random.c
 
diff --git a/newlib/libc/stdlib/lock.c b/newlib/libc/stdlib/lock.c
new file mode 100644
index 0000000000000000000000000000000000000000..3349ef36d7c7b0dfce065de3c8df4fe8eb05c002
--- /dev/null
+++ b/newlib/libc/stdlib/lock.c
@@ -0,0 +1,130 @@
+/*
+FUNCTION
+<<__retarget_lock_init>>, <<__retarget_lock_init_recursive>>, <<__retarget_lock_close>>, <<__retarget_lock_close_recursive>>, <<__retarget_lock_acquire>>, <<__retarget_lock_acquire_recursive>>, <<__retarget_lock_try_acquire>>, <<__retarget_lock_try_acquire_recursive>>, <<__retarget_lock_release>>, <<__retarget_lock_release_recursive>>---locking routines
+
+INDEX
+	__retarget_lock_init
+INDEX
+	__retarget_lock_init_recursive
+INDEX
+	__retarget_lock_close
+INDEX
+	__retarget_lock_close_recursive
+INDEX
+	__retarget_lock_acquire
+INDEX
+	__retarget_lock_acquire_recursive
+INDEX
+	__retarget_lock_try_acquire
+INDEX
+	__retarget_lock_try_acquire_recursive
+INDEX
+	__retarget_lock_release
+INDEX
+	__retarget_lock_release_recursive
+
+ANSI_SYNOPSIS
+	#include <lock.h>
+	void __retarget_lock_init (_LOCK_T * <[lock_ptr]>);
+	void __retarget_lock_init_recursive (_LOCK_T * <[lock_ptr]>);
+	void __retarget_lock_close (_LOCK_T <[lock]>);
+	void __retarget_lock_close_recursive (_LOCK_T <[lock]>);
+	void __retarget_lock_acquire (_LOCK_T <[lock]>);
+	void __retarget_lock_acquire_recursive (_LOCK_T <[lock]>);
+	int __retarget_lock_try_acquire (_LOCK_T <[lock]>);
+	int __retarget_lock_try_acquire_recursive (_LOCK_T <[lock]>);
+	void __retarget_lock_release (_LOCK_T <[lock]>);
+	void __retarget_lock_release_recursive (_LOCK_T <[lock]>);
+
+TRAD_SYNOPSIS
+	void __retarget_lock_init(<[lock_ptr]>)
+	_LOCK_T * <[lock_ptr]>;
+
+	void __retarget_lock_init_recursive(<[lock_ptr]>)
+	_LOCK_T * <[lock_ptr]>;
+
+	void __retarget_lock_close(<[lock]>)
+	_LOCK_T <[lock]>;
+
+	void __retarget_lock_close_recursive(<[lock]>)
+	_LOCK_T <[lock]>;
+
+	void __retarget_lock_acquire(<[lock]>)
+	_LOCK_T <[lock]>;
+
+	void __retarget_lock_acquire_recursive(<[lock]>)
+	_LOCK_T <[lock]>;
+
+	int __retarget_lock_try_acquire(<[lock]>)
+	_LOCK_T <[lock]>;
+
+	int __retarget_lock_try_acquire_recursive(<[lock]>)
+	_LOCK_T <[lock]>;
+
+	void __retarget_lock_release(<[lock]>)
+	_LOCK_T <[lock]>;
+
+	void __retarget_lock_release_recursive(<[lock]>)
+	_LOCK_T <[lock]>;
+
+DESCRIPTION
+These empty functions are used for locking to allow applications to retarget
+them.  They are used in place of the default dummy lock macros when newlib
+is configured with --enable-newlib-retargetable-locking.
+*/
+
+/* dummy lock routines for single-threaded apps */
+
+#include <sys/lock.h>
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_init (_LOCK_T *lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_init_recursive(_LOCK_T *lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_close(_LOCK_T lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_close_recursive(_LOCK_T lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_acquire (_LOCK_T lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_acquire_recursive (_LOCK_T lock)
+{
+}
+
+int _ATTRIBUTE((__weak__))
+__retarget_lock_try_acquire(_LOCK_T lock)
+{
+  return 1;
+}
+
+int _ATTRIBUTE((__weak__))
+__retarget_lock_try_acquire_recursive(_LOCK_T lock)
+{
+  return 1;
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_release (_LOCK_T lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_release_recursive (_LOCK_T lock)
+{
+}
diff --git a/newlib/newlib.hin b/newlib/newlib.hin
index d03dfac0eea6a8917a92b8f0f3584c2cd42b9388..397bc9b96eafddace3a75be509157040654b6fde 100644
--- a/newlib/newlib.hin
+++ b/newlib/newlib.hin
@@ -82,6 +82,9 @@
 /* Define if small footprint nano-formatted-IO implementation used.  */
 #undef _NANO_FORMATTED_IO
 
+/* Define if using retargetable functions for default lock routines.  */
+#undef _RETARGETABLE_LOCKING
+
 /*
  * Iconv encodings enabled ("to" direction)
  */

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-12-13 17:18 [PATCH, newlib] Allow locking routine to be retargeted Thomas Preudhomme
@ 2016-12-13 20:13 ` Freddie Chopin
  2016-12-14 11:54   ` Thomas Preudhomme
  2016-12-13 21:11 ` Freddie Chopin
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 51+ messages in thread
From: Freddie Chopin @ 2016-12-13 20:13 UTC (permalink / raw)
  To: newlib

Great!

I've already managed to compile the toolchain for ARM, now I'm trying
to implement all these "retargeting" functions and required lock
objects. We'll see how it works (;

BTW - maybe it would be better to leave the functions undefined and
provide the stubs only in libnosys.a? This would be consistent with
other newlib stubs (like _sbrk_r(), _read_r() and so on)?

Regards,
FCh

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-12-13 17:18 [PATCH, newlib] Allow locking routine to be retargeted Thomas Preudhomme
  2016-12-13 20:13 ` Freddie Chopin
@ 2016-12-13 21:11 ` Freddie Chopin
  2016-12-13 21:41 ` Freddie Chopin
  2016-12-14 14:22 ` Sebastian Huber
  3 siblings, 0 replies; 51+ messages in thread
From: Freddie Chopin @ 2016-12-13 21:11 UTC (permalink / raw)
  To: newlib

OK.

Issue 1 - contents of lock.h should be surrounded with:

#ifdef __cplusplus
extern "C" {
#endif

...

#ifdef __cplusplus
}
#endif

Regards,
FCh

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-12-13 17:18 [PATCH, newlib] Allow locking routine to be retargeted Thomas Preudhomme
  2016-12-13 20:13 ` Freddie Chopin
  2016-12-13 21:11 ` Freddie Chopin
@ 2016-12-13 21:41 ` Freddie Chopin
  2016-12-14 14:22 ` Sebastian Huber
  3 siblings, 0 replies; 51+ messages in thread
From: Freddie Chopin @ 2016-12-13 21:41 UTC (permalink / raw)
  To: newlib

Apart from the issue with missing extern "C" for C++, everything seems
to work fine in my limited test with four required global locks and
some uses of stdio functions.

Regards,
FCh

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-12-13 20:13 ` Freddie Chopin
@ 2016-12-14 11:54   ` Thomas Preudhomme
  2016-12-14 12:39     ` Freddie Chopin
  0 siblings, 1 reply; 51+ messages in thread
From: Thomas Preudhomme @ 2016-12-14 11:54 UTC (permalink / raw)
  To: newlib

On 13/12/16 20:12, Freddie Chopin wrote:
> Great!
>
> I've already managed to compile the toolchain for ARM, now I'm trying
> to implement all these "retargeting" functions and required lock
> objects. We'll see how it works (;
>
> BTW - maybe it would be better to leave the functions undefined and
> provide the stubs only in libnosys.a? This would be consistent with
> other newlib stubs (like _sbrk_r(), _read_r() and so on)?

I need to look into how does that work when not using libnosys.a. I'll also add 
the extern C as per your suggestion.

Thanks,

Thomas

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-12-14 11:54   ` Thomas Preudhomme
@ 2016-12-14 12:39     ` Freddie Chopin
  2017-01-11 13:09       ` Thomas Preudhomme
  0 siblings, 1 reply; 51+ messages in thread
From: Freddie Chopin @ 2016-12-14 12:39 UTC (permalink / raw)
  To: newlib

On Wed, 2016-12-14 at 11:54 +0000, Thomas Preudhomme wrote:
> On 13/12/16 20:12, Freddie Chopin wrote:
> > Great!
> > 
> > I've already managed to compile the toolchain for ARM, now I'm
> > trying
> > to implement all these "retargeting" functions and required lock
> > objects. We'll see how it works (;
> > 
> > BTW - maybe it would be better to leave the functions undefined and
> > provide the stubs only in libnosys.a? This would be consistent with
> > other newlib stubs (like _sbrk_r(), _read_r() and so on)?
> 
> I need to look into how does that work when not using libnosys

It's worth trying. I think that as long as the project doesn't use any
code which requires locking, there will be no problem at all.

When the user _DOES_ use some code which requires them, he'll get the
linking errors (withou libnosys.a). But given the fact that the two
most "popular" locks which will be used are atexit and malloc, the
situation is not so bad:
1. atexit usually uses malloc anyway,
2. malloc requires you to provide _sbrk_r() - if you don't you'll get a
linking error,
3. the fact that the functions are provided as weak symbols probably
doesn't change much - the user would get linking errors anyway, because
the storage for locks is not provided.

With item 3 in mind, I guess that if you provide weak functions, some
dummy storage should also be provided as a weak symbol - either in
lock.c or in libnosys.a.

Regards,
FCh

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-12-13 17:18 [PATCH, newlib] Allow locking routine to be retargeted Thomas Preudhomme
                   ` (2 preceding siblings ...)
  2016-12-13 21:41 ` Freddie Chopin
@ 2016-12-14 14:22 ` Sebastian Huber
  2016-12-14 14:36   ` Thomas Preudhomme
  3 siblings, 1 reply; 51+ messages in thread
From: Sebastian Huber @ 2016-12-14 14:22 UTC (permalink / raw)
  To: Thomas Preudhomme, newlib



On 13/12/16 18:18, Thomas Preudhomme wrote:
> +#else
> +
> +typedef void * _LOCK_T;
> +#define _LOCK_RECURSIVE_T _LOCK_T
> +
> +#define __LOCK_INIT(class,lock) extern struct_lock _lock_  ## lock; \
> +	class_LOCK_T lock = &_lock_  ## lock
> +#define __LOCK_INIT_RECURSIVE(class,lock) __LOCK_INIT(class,lock)

I would use:

struct _lock;
typedef struct _lock *_LOCK_T;

This makes debugging a bit easier.

-- 
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
E-Mail  : sebastian.huber@embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-12-14 14:22 ` Sebastian Huber
@ 2016-12-14 14:36   ` Thomas Preudhomme
  2016-12-14 14:52     ` Thomas Preudhomme
  2016-12-14 15:27     ` Freddie Chopin
  0 siblings, 2 replies; 51+ messages in thread
From: Thomas Preudhomme @ 2016-12-14 14:36 UTC (permalink / raw)
  To: newlib



On 14/12/16 14:21, Sebastian Huber wrote:
>
>
> On 13/12/16 18:18, Thomas Preudhomme wrote:
>> +#else
>> +
>> +typedef void * _LOCK_T;
>> +#define _LOCK_RECURSIVE_T _LOCK_T
>> +
>> +#define __LOCK_INIT(class,lock) extern struct_lock _lock_  ## lock; \
>> +    class_LOCK_T lock = &_lock_  ## lock
>> +#define __LOCK_INIT_RECURSIVE(class,lock) __LOCK_INIT(class,lock)
>
> I would use:
>
> struct _lock;
> typedef struct _lock *_LOCK_T;
>
> This makes debugging a bit easier.

But then if your lock is just an integer you have to use a structure with a 
single field, right?

Why is struct _lock easier to debug by the way?

Best regards,

Thomas

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-12-14 14:36   ` Thomas Preudhomme
@ 2016-12-14 14:52     ` Thomas Preudhomme
  2017-01-09 18:49       ` Freddie Chopin
  2016-12-14 15:27     ` Freddie Chopin
  1 sibling, 1 reply; 51+ messages in thread
From: Thomas Preudhomme @ 2016-12-14 14:52 UTC (permalink / raw)
  To: newlib

On 14/12/16 14:36, Thomas Preudhomme wrote:
>
>
> On 14/12/16 14:21, Sebastian Huber wrote:
>>
>>
>> On 13/12/16 18:18, Thomas Preudhomme wrote:
>>> +#else
>>> +
>>> +typedef void * _LOCK_T;
>>> +#define _LOCK_RECURSIVE_T _LOCK_T
>>> +
>>> +#define __LOCK_INIT(class,lock) extern struct_lock _lock_  ## lock; \
>>> +    class_LOCK_T lock = &_lock_  ## lock
>>> +#define __LOCK_INIT_RECURSIVE(class,lock) __LOCK_INIT(class,lock)
>>
>> I would use:
>>
>> struct _lock;
>> typedef struct _lock *_LOCK_T;
>>
>> This makes debugging a bit easier.
>
> But then if your lock is just an integer you have to use a structure with a
> single field, right?

I'm thinking that the lock also needs to be weakly defined so that there is no 
link failure on single threaded environment.

Best regards,

Thomas

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-12-14 14:36   ` Thomas Preudhomme
  2016-12-14 14:52     ` Thomas Preudhomme
@ 2016-12-14 15:27     ` Freddie Chopin
  1 sibling, 0 replies; 51+ messages in thread
From: Freddie Chopin @ 2016-12-14 15:27 UTC (permalink / raw)
  To: newlib

On Wed, 2016-12-14 at 14:36 +0000, Thomas Preudhomme wrote:
> Why is struct _lock easier to debug by the way?

I think the reason is that in user code - which does the "retargeting"
- _lock can be defined to be whatever is needed, so in the debugger you
see the contents of the struct. If you use void*, then you have to do
manual casting in debugger to see these contents.

I think this will also help to keep the retargeting code valid - now
the compiler can check whether you use correct types - either _lock or
it's address, while with void* the compiler will happily accept almost
anything.

Regards,
FCh

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-12-14 14:52     ` Thomas Preudhomme
@ 2017-01-09 18:49       ` Freddie Chopin
  2017-01-10 16:50         ` Thomas Preudhomme
  0 siblings, 1 reply; 51+ messages in thread
From: Freddie Chopin @ 2017-01-09 18:49 UTC (permalink / raw)
  To: newlib

Thomas - do you still plan to work on this change?

Regards,
FCh

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2017-01-09 18:49       ` Freddie Chopin
@ 2017-01-10 16:50         ` Thomas Preudhomme
  2017-01-10 17:07           ` Freddie Chopin
  0 siblings, 1 reply; 51+ messages in thread
From: Thomas Preudhomme @ 2017-01-10 16:50 UTC (permalink / raw)
  To: newlib

Yes absolutely. I didn't progress during holidays for obvious reasons but I've 
implemented the changes you requested and am about to start testing.

Best regards,

Thomas

On 09/01/17 18:49, Freddie Chopin wrote:
> Thomas - do you still plan to work on this change?
>
> Regards,
> FCh
>

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2017-01-10 16:50         ` Thomas Preudhomme
@ 2017-01-10 17:07           ` Freddie Chopin
  2017-01-11 16:09             ` Thomas Preudhomme
  0 siblings, 1 reply; 51+ messages in thread
From: Freddie Chopin @ 2017-01-10 17:07 UTC (permalink / raw)
  To: newlib

On Tue, 2017-01-10 at 16:50 +0000, Thomas Preudhomme wrote:
> Yes absolutely.

Great!

> I didn't progress during holidays for obvious reasons

Yeah, I had so many plans for this period and did almost nothing (;

> but I've 
> implemented the changes you requested and am about to start testing.

You can share the patch earlier if you want/can, I could test some of
the features too (;

Regards,
FCh

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-12-14 12:39     ` Freddie Chopin
@ 2017-01-11 13:09       ` Thomas Preudhomme
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Preudhomme @ 2017-01-11 13:09 UTC (permalink / raw)
  To: newlib

Hi Freddie,

On 14/12/16 12:38, Freddie Chopin wrote:
> On Wed, 2016-12-14 at 11:54 +0000, Thomas Preudhomme wrote:
>> On 13/12/16 20:12, Freddie Chopin wrote:
>>> Great!
>>>
>>> I've already managed to compile the toolchain for ARM, now I'm
>>> trying
>>> to implement all these "retargeting" functions and required lock
>>> objects. We'll see how it works (;
>>>
>>> BTW - maybe it would be better to leave the functions undefined and
>>> provide the stubs only in libnosys.a? This would be consistent with
>>> other newlib stubs (like _sbrk_r(), _read_r() and so on)?
>>
>> I need to look into how does that work when not using libnosys
>
> It's worth trying. I think that as long as the project doesn't use any
> code which requires locking, there will be no problem at all.
>
> When the user _DOES_ use some code which requires them, he'll get the
> linking errors (withou libnosys.a). But given the fact that the two
> most "popular" locks which will be used are atexit and malloc, the
> situation is not so bad:
> 1. atexit usually uses malloc anyway,
> 2. malloc requires you to provide _sbrk_r() - if you don't you'll get a
> linking error,
> 3. the fact that the functions are provided as weak symbols probably
> doesn't change much - the user would get linking errors anyway, because
> the storage for locks is not provided.
>
> With item 3 in mind, I guess that if you provide weak functions, some
> dummy storage should also be provided as a weak symbol - either in
> lock.c or in libnosys.a.

I looked into putting lock.c in libnosys.a but then the applications fail to 
link when using rdimon for semihosting. I think I'll go for the weak lock and 
dummy functions always linked in (provided newlib was built with the right 
configure option).

Best regards,

Thomas

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2017-01-10 17:07           ` Freddie Chopin
@ 2017-01-11 16:09             ` Thomas Preudhomme
  2017-01-11 16:46               ` Craig Howland
  0 siblings, 1 reply; 51+ messages in thread
From: Thomas Preudhomme @ 2017-01-11 16:09 UTC (permalink / raw)
  To: newlib

[-- Attachment #1: Type: text/plain, Size: 593 bytes --]

On 10/01/17 17:06, Freddie Chopin wrote:
> On Tue, 2017-01-10 at 16:50 +0000, Thomas Preudhomme wrote:
>> Yes absolutely.
>
> Great!
>
>> I didn't progress during holidays for obvious reasons
>
> Yeah, I had so many plans for this period and did almost nothing (;
>
>> but I've
>> implemented the changes you requested and am about to start testing.
>
> You can share the patch earlier if you want/can, I could test some of
> the features too (;

Here you are. It has worked fine with my limited testing. I welcome all feedback 
about the testing you can throw at this.

Best regards,

Thomas

[-- Attachment #2: newlib_retargetable_locking_routine.patch --]
[-- Type: text/x-patch, Size: 23995 bytes --]

diff --git a/newlib/configure b/newlib/configure
index 30e1d57664302248af9087b0051290e2aff4b382..42b1e13feeda8a5b7ad3cf365393bd4640da4c8c 100755
--- a/newlib/configure
+++ b/newlib/configure
@@ -798,6 +798,7 @@ enable_newlib_nano_malloc
 enable_newlib_unbuf_stream_opt
 enable_lite_exit
 enable_newlib_nano_formatted_io
+enable_newlib_retargetable_locking
 enable_multilib
 enable_target_optspace
 enable_malloc_debugging
@@ -1469,6 +1470,7 @@ Optional Features:
   --disable-newlib-unbuf-stream-opt    disable unbuffered stream optimization in streamio
   --enable-lite-exit	enable light weight exit
   --enable-newlib-nano-formatted-io    Use nano version formatted IO
+  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time
   --enable-multilib         build many library versions (default)
   --enable-target-optspace  optimize for space
   --enable-malloc-debugging indicate malloc debugging requested
@@ -2470,6 +2472,18 @@ else
 fi
 
 
+# Check whether --enable-newlib-retargetable-locking was given.
+if test "${enable_newlib_retargetable_locking+set}" = set; then :
+  enableval=$enable_newlib_retargetable_locking; case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_locking=no ;;
+   *) as_fn_error $? "bad value ${enableval} for newlib-retargetable-locking" "$LINENO" 5 ;;
+ esac
+else
+  newlib_retargetable_locking=no
+fi
+
+
 
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
@@ -11776,7 +11790,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11779 "configure"
+#line 11793 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11882,7 +11896,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11885 "configure"
+#line 11899 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12421,6 +12435,13 @@ _ACEOF
 
 fi
 
+if test "${newlib_retargetable_locking}" = "yes"; then
+cat >>confdefs.h <<_ACEOF
+#define _RETARGETABLE_LOCKING 1
+_ACEOF
+
+fi
+
 
 if test "x${iconv_encodings}" != "x" \
    || test "x${iconv_to_encodings}" != "x" \
diff --git a/newlib/configure.in b/newlib/configure.in
index 01c6367a99cdf6f74a5ad15c8a4eb4a45f206e9d..70cffa76a966f8d9cd1c8888156002e76ea13dc2 100644
--- a/newlib/configure.in
+++ b/newlib/configure.in
@@ -218,6 +218,17 @@ AC_ARG_ENABLE(newlib_nano_formatted_io,
    *) AC_MSG_ERROR(bad value ${enableval} for newlib-nano-formatted-io) ;;
  esac],[newlib_nano_formatted_io=no])
 
+dnl Support --enable-retargetable-locking
+dnl This option is also read in libc/configure.in.  It is repeated
+dnl here so that it shows up in the help text.
+AC_ARG_ENABLE(newlib-retargetable-locking,
+[  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time],
+[case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_locking=no ;;
+   *) AC_MSG_ERROR(bad value ${enableval} for newlib-retargetable-locking) ;;
+ esac],[newlib_retargetable_locking=no])
+
 NEWLIB_CONFIGURE(.)
 
 dnl We have to enable libtool after NEWLIB_CONFIGURE because if we try and
@@ -442,6 +453,10 @@ if test "${newlib_nano_formatted_io}" = "yes"; then
 AC_DEFINE_UNQUOTED(_NANO_FORMATTED_IO)
 fi
 
+if test "${newlib_retargetable_locking}" = "yes"; then
+AC_DEFINE_UNQUOTED(_RETARGETABLE_LOCKING)
+fi
+
 dnl
 dnl Parse --enable-newlib-iconv-encodings option argument
 dnl
diff --git a/newlib/libc/configure b/newlib/libc/configure
index 5dccc852b8cd90d697a90f113ec17982741ecc3a..35077b81550aa999026ff67a7428fec6509a26ce 100755
--- a/newlib/libc/configure
+++ b/newlib/libc/configure
@@ -751,6 +751,8 @@ build
 newlib_basedir
 MAY_SUPPLY_SYSCALLS_FALSE
 MAY_SUPPLY_SYSCALLS_TRUE
+NEWLIB_RETARGETABLE_LOCKING_FALSE
+NEWLIB_RETARGETABLE_LOCKING_TRUE
 NEWLIB_NANO_FORMATTED_IO_FALSE
 NEWLIB_NANO_FORMATTED_IO_TRUE
 target_alias
@@ -797,6 +799,7 @@ enable_option_checking
 enable_newlib_io_pos_args
 enable_newlib_nano_malloc
 enable_newlib_nano_formatted_io
+enable_newlib_retargetable_locking
 enable_multilib
 enable_target_optspace
 enable_malloc_debugging
@@ -1448,6 +1451,7 @@ Optional Features:
   --enable-newlib-io-pos-args enable printf-family positional arg support
   --enable-newlib-nano-malloc    Use small-footprint nano-malloc implementation
   --enable-newlib-nano-formatted-io    Use small-footprint nano-formatted-IO implementation
+  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time
   --enable-multilib         build many library versions (default)
   --enable-target-optspace  optimize for space
   --enable-malloc-debugging indicate malloc debugging requested
@@ -2252,6 +2256,26 @@ else
 fi
 
 
+# Check whether --enable-newlib-retargetable-locking was given.
+if test "${enable_newlib_retargetable_locking+set}" = set; then :
+  enableval=$enable_newlib_retargetable_locking; case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_lock=no ;;
+   *) as_fn_error $? "bad value ${enableval} for newlib-retargetable-locking" "$LINENO" 5 ;;
+ esac
+else
+  newlib_retargetable_locking=no
+fi
+
+ if test x$newlib_retargetable_locking = xyes; then
+  NEWLIB_RETARGETABLE_LOCKING_TRUE=
+  NEWLIB_RETARGETABLE_LOCKING_FALSE='#'
+else
+  NEWLIB_RETARGETABLE_LOCKING_TRUE='#'
+  NEWLIB_RETARGETABLE_LOCKING_FALSE=
+fi
+
+
 
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
@@ -11525,7 +11549,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11528 "configure"
+#line 11552 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11631,7 +11655,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11634 "configure"
+#line 11658 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12248,6 +12272,10 @@ if test -z "${NEWLIB_NANO_FORMATTED_IO_TRUE}" && test -z "${NEWLIB_NANO_FORMATTE
   as_fn_error $? "conditional \"NEWLIB_NANO_FORMATTED_IO\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${NEWLIB_RETARGETABLE_LOCKING_TRUE}" && test -z "${NEWLIB_RETARGETABLE_LOCKING_FALSE}"; then
+  as_fn_error $? "conditional \"NEWLIB_RETARGETABLE_LOCKING\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${MAY_SUPPLY_SYSCALLS_TRUE}" && test -z "${MAY_SUPPLY_SYSCALLS_FALSE}"; then
   as_fn_error $? "conditional \"MAY_SUPPLY_SYSCALLS\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
diff --git a/newlib/libc/configure.in b/newlib/libc/configure.in
index 0a7bb8815be44fb1e92f753fa2c8df2a31b95f94..ac25a3933c4a4794f3cfe291e0275d0ed001b96a 100644
--- a/newlib/libc/configure.in
+++ b/newlib/libc/configure.in
@@ -36,6 +36,16 @@ AC_ARG_ENABLE(newlib_nano_formatted_io,
  esac],[newlib_nano_formatted_io=no])
 AM_CONDITIONAL(NEWLIB_NANO_FORMATTED_IO, test x$newlib_nano_formatted_io = xyes)
 
+dnl Support --enable-retargetable-locking used by libc/sys
+AC_ARG_ENABLE(newlib-retargetable-locking,
+[  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time],
+[case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_lock=no ;;
+   *) AC_MSG_ERROR(bad value ${enableval} for newlib-retargetable-locking) ;;
+ esac],[newlib_retargetable_locking=no])
+AM_CONDITIONAL(NEWLIB_RETARGETABLE_LOCKING, test x$newlib_retargetable_locking = xyes)
+
 NEWLIB_CONFIGURE(..)
 
 AM_CONDITIONAL(NEWLIB_NANO_MALLOC, test x$newlib_nano_malloc = xyes)
diff --git a/newlib/libc/include/sys/lock.h b/newlib/libc/include/sys/lock.h
index 9075e35c9179968031010432515e3a845ff6ca8d..9a8e2528c79a89d5807da8c4bb0e65151870bf42 100644
--- a/newlib/libc/include/sys/lock.h
+++ b/newlib/libc/include/sys/lock.h
@@ -3,10 +3,13 @@
 
 /* dummy lock routines for single-threaded aps */
 
+#include <newlib.h>
+#include <_ansi.h>
+
+#ifndef _RETARGETABLE_LOCKING
+
 typedef int _LOCK_T;
 typedef int _LOCK_RECURSIVE_T;
- 
-#include <_ansi.h>
 
 #define __LOCK_INIT(class,lock) static int lock = 0;
 #define __LOCK_INIT_RECURSIVE(class,lock) static int lock = 0;
@@ -21,4 +24,46 @@ typedef int _LOCK_RECURSIVE_T;
 #define __lock_release(lock) (_CAST_VOID 0)
 #define __lock_release_recursive(lock) (_CAST_VOID 0)
 
+#else
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _lock;
+typedef struct _lock * _LOCK_T;
+#define _LOCK_RECURSIVE_T _LOCK_T
+
+#define __LOCK_INIT(class,lock) extern struct _lock _lock_ ## lock; \
+	class _LOCK_T lock = &_lock_ ## lock
+#define __LOCK_INIT_RECURSIVE(class,lock) __LOCK_INIT(class,lock)
+
+extern void __retarget_lock_init(_LOCK_T *lock);
+#define __lock_init(lock) __retarget_lock_init(&lock)
+extern void __retarget_lock_init_recursive(_LOCK_T *lock);
+#define __lock_init_recursive(lock) __retarget_lock_init_recursive(&lock)
+extern void __retarget_lock_close(_LOCK_T lock);
+#define __lock_close(lock) __retarget_lock_close(lock)
+extern void __retarget_lock_close_recursive(_LOCK_T lock);
+#define __lock_close_recursive(lock) __retarget_lock_close_recursive(lock)
+extern void __retarget_lock_acquire(_LOCK_T lock);
+#define __lock_acquire(lock) __retarget_lock_acquire(lock)
+extern void __retarget_lock_acquire_recursive(_LOCK_T lock);
+#define __lock_acquire_recursive(lock) __retarget_lock_acquire_recursive(lock)
+extern int __retarget_lock_try_acquire(_LOCK_T lock);
+#define __lock_try_acquire(lock) __retarget_lock_try_acquire(lock)
+extern int __retarget_lock_try_acquire_recursive(_LOCK_T lock);
+#define __lock_try_acquire_recursive(lock) \
+  __retarget_lock_try_acquire_recursive(lock)
+extern void __retarget_lock_release(_LOCK_T lock);
+#define __lock_release(lock) __retarget_lock_release(lock)
+extern void __retarget_lock_release_recursive(_LOCK_T lock);
+#define __lock_release_recursive(lock) __retarget_lock_release_recursive(lock)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RETARGETABLE_LOCKING */
+
 #endif /* __SYS_LOCK_H__ */
diff --git a/newlib/libc/stdlib/Makefile.am b/newlib/libc/stdlib/Makefile.am
index 2d45d1029ace8087b57657cbc11feabf76f4206e..76ed8480c28ebfb68e2f48432c0359b11f1522a8 100644
--- a/newlib/libc/stdlib/Makefile.am
+++ b/newlib/libc/stdlib/Makefile.am
@@ -74,6 +74,11 @@ GENERAL_SOURCES += \
 	wcstold.c
 endif # HAVE_LONG_DOUBLE
 
+if NEWLIB_RETARGETABLE_LOCKING
+GENERAL_SOURCES += \
+	lock.c
+endif
+
 if NEWLIB_NANO_MALLOC
 MALIGNR=nano-malignr
 MALLOPTR=nano-malloptr
diff --git a/newlib/libc/stdlib/Makefile.in b/newlib/libc/stdlib/Makefile.in
index 466ab6d1e02ea919f6c8ceed792024955bef1a66..3295e981c87bac3b21a6b72dda148f892fe018d6 100644
--- a/newlib/libc/stdlib/Makefile.in
+++ b/newlib/libc/stdlib/Makefile.in
@@ -57,6 +57,9 @@ host_triplet = @host@
 @HAVE_LONG_DOUBLE_TRUE@	strtold.c \
 @HAVE_LONG_DOUBLE_TRUE@	wcstold.c
 
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@am__append_2 = \
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@	lock.c
+
 DIST_COMMON = $(srcdir)/../../Makefile.shared $(srcdir)/Makefile.in \
 	$(srcdir)/Makefile.am
 subdir = stdlib
@@ -81,7 +84,9 @@ lib_a_AR = $(AR) $(ARFLAGS)
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(ELIX_2_OBJS)
 @HAVE_LONG_DOUBLE_TRUE@am__objects_1 = lib_a-strtold.$(OBJEXT) \
 @HAVE_LONG_DOUBLE_TRUE@	lib_a-wcstold.$(OBJEXT)
-am__objects_2 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@am__objects_2 =  \
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@	lib_a-lock.$(OBJEXT)
+am__objects_3 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \
 	lib_a-__call_atexit.$(OBJEXT) lib_a-__exp10.$(OBJEXT) \
 	lib_a-__ten_mu.$(OBJEXT) lib_a-_Exit.$(OBJEXT) \
 	lib_a-abort.$(OBJEXT) lib_a-abs.$(OBJEXT) \
@@ -112,8 +117,8 @@ am__objects_2 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \
 	lib_a-wcstol.$(OBJEXT) lib_a-wcstoul.$(OBJEXT) \
 	lib_a-wcstombs.$(OBJEXT) lib_a-wcstombs_r.$(OBJEXT) \
 	lib_a-wctomb.$(OBJEXT) lib_a-wctomb_r.$(OBJEXT) \
-	$(am__objects_1)
-am__objects_3 = lib_a-arc4random.$(OBJEXT) \
+	$(am__objects_1) $(am__objects_2)
+am__objects_4 = lib_a-arc4random.$(OBJEXT) \
 	lib_a-arc4random_uniform.$(OBJEXT) lib_a-cxa_atexit.$(OBJEXT) \
 	lib_a-cxa_finalize.$(OBJEXT) lib_a-drand48.$(OBJEXT) \
 	lib_a-ecvtbuf.$(OBJEXT) lib_a-efgcvt.$(OBJEXT) \
@@ -128,7 +133,7 @@ am__objects_3 = lib_a-arc4random.$(OBJEXT) \
 	lib_a-wcstoll_r.$(OBJEXT) lib_a-wcstoull.$(OBJEXT) \
 	lib_a-wcstoull_r.$(OBJEXT) lib_a-atoll.$(OBJEXT) \
 	lib_a-llabs.$(OBJEXT) lib_a-lldiv.$(OBJEXT)
-am__objects_4 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \
+am__objects_5 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \
 	lib_a-getopt.$(OBJEXT) lib_a-getsubopt.$(OBJEXT) \
 	lib_a-l64a.$(OBJEXT) lib_a-malign.$(OBJEXT) \
 	lib_a-mbrlen.$(OBJEXT) lib_a-mbrtowc.$(OBJEXT) \
@@ -137,22 +142,23 @@ am__objects_4 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \
 	lib_a-valloc.$(OBJEXT) lib_a-wcrtomb.$(OBJEXT) \
 	lib_a-wcsnrtombs.$(OBJEXT) lib_a-wcsrtombs.$(OBJEXT) \
 	lib_a-wctob.$(OBJEXT)
-am__objects_5 = lib_a-putenv.$(OBJEXT) lib_a-putenv_r.$(OBJEXT) \
+am__objects_6 = lib_a-putenv.$(OBJEXT) lib_a-putenv_r.$(OBJEXT) \
 	lib_a-setenv.$(OBJEXT) lib_a-setenv_r.$(OBJEXT)
-am__objects_6 = lib_a-rpmatch.$(OBJEXT) lib_a-system.$(OBJEXT)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_7 = $(am__objects_4) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_5) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_6)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_7 = $(am__objects_4) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_5)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_7 =  \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_4)
-@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_2) \
-@USE_LIBTOOL_FALSE@	$(am__objects_3) $(am__objects_7)
+am__objects_7 = lib_a-rpmatch.$(OBJEXT) lib_a-system.$(OBJEXT)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_8 = $(am__objects_5) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_6) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_7)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_8 = $(am__objects_5) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_6)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_8 =  \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_5)
+@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_3) \
+@USE_LIBTOOL_FALSE@	$(am__objects_4) $(am__objects_8)
 lib_a_OBJECTS = $(am_lib_a_OBJECTS)
 LTLIBRARIES = $(noinst_LTLIBRARIES)
-@HAVE_LONG_DOUBLE_TRUE@am__objects_8 = strtold.lo wcstold.lo
-am__objects_9 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \
+@HAVE_LONG_DOUBLE_TRUE@am__objects_9 = strtold.lo wcstold.lo
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@am__objects_10 = lock.lo
+am__objects_11 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \
 	__ten_mu.lo _Exit.lo abort.lo abs.lo aligned_alloc.lo \
 	assert.lo atexit.lo atof.lo atoff.lo atoi.lo atol.lo calloc.lo \
 	div.lo dtoa.lo dtoastub.lo environ.lo envlock.lo eprintf.lo \
@@ -163,28 +169,28 @@ am__objects_9 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \
 	rand_r.lo random.lo realloc.lo reallocf.lo sb_charsets.lo \
 	strtod.lo strtodg.lo strtol.lo strtorx.lo strtoul.lo utoa.lo \
 	wcstod.lo wcstol.lo wcstoul.lo wcstombs.lo wcstombs_r.lo \
-	wctomb.lo wctomb_r.lo $(am__objects_8)
-am__objects_10 = arc4random.lo arc4random_uniform.lo cxa_atexit.lo \
+	wctomb.lo wctomb_r.lo $(am__objects_9) $(am__objects_10)
+am__objects_12 = arc4random.lo arc4random_uniform.lo cxa_atexit.lo \
 	cxa_finalize.lo drand48.lo ecvtbuf.lo efgcvt.lo erand48.lo \
 	jrand48.lo lcong48.lo lrand48.lo mrand48.lo msize.lo mtrim.lo \
 	nrand48.lo rand48.lo seed48.lo srand48.lo strtoll.lo \
 	strtoll_r.lo strtoull.lo strtoull_r.lo wcstoll.lo wcstoll_r.lo \
 	wcstoull.lo wcstoull_r.lo atoll.lo llabs.lo lldiv.lo
-am__objects_11 = a64l.lo btowc.lo getopt.lo getsubopt.lo l64a.lo \
+am__objects_13 = a64l.lo btowc.lo getopt.lo getsubopt.lo l64a.lo \
 	malign.lo mbrlen.lo mbrtowc.lo mbsinit.lo mbsnrtowcs.lo \
 	mbsrtowcs.lo on_exit.lo valloc.lo wcrtomb.lo wcsnrtombs.lo \
 	wcsrtombs.lo wctob.lo
-am__objects_12 = putenv.lo putenv_r.lo setenv.lo setenv_r.lo
-am__objects_13 = rpmatch.lo system.lo
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_14 = $(am__objects_11) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_12) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_13)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_14 = $(am__objects_11) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_12)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_14 =  \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_11)
-@USE_LIBTOOL_TRUE@am_libstdlib_la_OBJECTS = $(am__objects_9) \
-@USE_LIBTOOL_TRUE@	$(am__objects_10) $(am__objects_14)
+am__objects_14 = putenv.lo putenv_r.lo setenv.lo setenv_r.lo
+am__objects_15 = rpmatch.lo system.lo
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_16 = $(am__objects_13) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_14) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_15)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_16 = $(am__objects_13) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_14)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_16 =  \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_13)
+@USE_LIBTOOL_TRUE@am_libstdlib_la_OBJECTS = $(am__objects_11) \
+@USE_LIBTOOL_TRUE@	$(am__objects_12) $(am__objects_16)
 libstdlib_la_OBJECTS = $(am_libstdlib_la_OBJECTS)
 libstdlib_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -367,7 +373,7 @@ GENERAL_SOURCES = __adjust.c __atexit.c __call_atexit.c __exp10.c \
 	quick_exit.c rand.c rand_r.c random.c realloc.c reallocf.c \
 	sb_charsets.c strtod.c strtodg.c strtol.c strtorx.c strtoul.c \
 	utoa.c wcstod.c wcstol.c wcstoul.c wcstombs.c wcstombs_r.c \
-	wctomb.c wctomb_r.c $(am__append_1)
+	wctomb.c wctomb_r.c $(am__append_1) $(am__append_2)
 @NEWLIB_NANO_MALLOC_FALSE@MALIGNR = malignr
 @NEWLIB_NANO_MALLOC_TRUE@MALIGNR = nano-malignr
 @NEWLIB_NANO_MALLOC_FALSE@MALLOPTR = malloptr
@@ -1002,6 +1008,12 @@ lib_a-wcstold.o: wcstold.c
 lib_a-wcstold.obj: wcstold.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcstold.obj `if test -f 'wcstold.c'; then $(CYGPATH_W) 'wcstold.c'; else $(CYGPATH_W) '$(srcdir)/wcstold.c'; fi`
 
+lib_a-lock.o: lock.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lock.o `test -f 'lock.c' || echo '$(srcdir)/'`lock.c
+
+lib_a-lock.obj: lock.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lock.obj `if test -f 'lock.c'; then $(CYGPATH_W) 'lock.c'; else $(CYGPATH_W) '$(srcdir)/lock.c'; fi`
+
 lib_a-arc4random.o: arc4random.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-arc4random.o `test -f 'arc4random.c' || echo '$(srcdir)/'`arc4random.c
 
diff --git a/newlib/libc/stdlib/lock.c b/newlib/libc/stdlib/lock.c
new file mode 100644
index 0000000000000000000000000000000000000000..9d315d13e4fd5c327a57406ea19efc0f7aac756b
--- /dev/null
+++ b/newlib/libc/stdlib/lock.c
@@ -0,0 +1,139 @@
+/*
+FUNCTION
+<<__retarget_lock_init>>, <<__retarget_lock_init_recursive>>, <<__retarget_lock_close>>, <<__retarget_lock_close_recursive>>, <<__retarget_lock_acquire>>, <<__retarget_lock_acquire_recursive>>, <<__retarget_lock_try_acquire>>, <<__retarget_lock_try_acquire_recursive>>, <<__retarget_lock_release>>, <<__retarget_lock_release_recursive>>---locking routines
+
+INDEX
+	__retarget_lock_init
+INDEX
+	__retarget_lock_init_recursive
+INDEX
+	__retarget_lock_close
+INDEX
+	__retarget_lock_close_recursive
+INDEX
+	__retarget_lock_acquire
+INDEX
+	__retarget_lock_acquire_recursive
+INDEX
+	__retarget_lock_try_acquire
+INDEX
+	__retarget_lock_try_acquire_recursive
+INDEX
+	__retarget_lock_release
+INDEX
+	__retarget_lock_release_recursive
+
+ANSI_SYNOPSIS
+	#include <lock.h>
+	void __retarget_lock_init (_LOCK_T * <[lock_ptr]>);
+	void __retarget_lock_init_recursive (_LOCK_T * <[lock_ptr]>);
+	void __retarget_lock_close (_LOCK_T <[lock]>);
+	void __retarget_lock_close_recursive (_LOCK_T <[lock]>);
+	void __retarget_lock_acquire (_LOCK_T <[lock]>);
+	void __retarget_lock_acquire_recursive (_LOCK_T <[lock]>);
+	int __retarget_lock_try_acquire (_LOCK_T <[lock]>);
+	int __retarget_lock_try_acquire_recursive (_LOCK_T <[lock]>);
+	void __retarget_lock_release (_LOCK_T <[lock]>);
+	void __retarget_lock_release_recursive (_LOCK_T <[lock]>);
+
+TRAD_SYNOPSIS
+	void __retarget_lock_init(<[lock_ptr]>)
+	_LOCK_T * <[lock_ptr]>;
+
+	void __retarget_lock_init_recursive(<[lock_ptr]>)
+	_LOCK_T * <[lock_ptr]>;
+
+	void __retarget_lock_close(<[lock]>)
+	_LOCK_T <[lock]>;
+
+	void __retarget_lock_close_recursive(<[lock]>)
+	_LOCK_T <[lock]>;
+
+	void __retarget_lock_acquire(<[lock]>)
+	_LOCK_T <[lock]>;
+
+	void __retarget_lock_acquire_recursive(<[lock]>)
+	_LOCK_T <[lock]>;
+
+	int __retarget_lock_try_acquire(<[lock]>)
+	_LOCK_T <[lock]>;
+
+	int __retarget_lock_try_acquire_recursive(<[lock]>)
+	_LOCK_T <[lock]>;
+
+	void __retarget_lock_release(<[lock]>)
+	_LOCK_T <[lock]>;
+
+	void __retarget_lock_release_recursive(<[lock]>)
+	_LOCK_T <[lock]>;
+
+DESCRIPTION
+These empty functions are used for locking to allow applications to retarget
+them.  They are used in place of the default dummy lock macros when newlib
+is configured with --enable-newlib-retargetable-locking.
+*/
+
+/* dummy lock routines for single-threaded apps */
+
+#include <sys/lock.h>
+
+struct _lock {
+  char unused;
+};
+
+struct _lock _ATTRIBUTE((__weak__)) _lock___sinit_lock;
+struct _lock _ATTRIBUTE((__weak__)) _lock___sfp_lock;
+struct _lock _ATTRIBUTE((__weak__)) _lock___atexit_lock;
+struct _lock _ATTRIBUTE((__weak__)) _lock___malloc_lock_object;
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_init (_LOCK_T *lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_init_recursive(_LOCK_T *lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_close(_LOCK_T lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_close_recursive(_LOCK_T lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_acquire (_LOCK_T lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_acquire_recursive (_LOCK_T lock)
+{
+}
+
+int _ATTRIBUTE((__weak__))
+__retarget_lock_try_acquire(_LOCK_T lock)
+{
+  return 1;
+}
+
+int _ATTRIBUTE((__weak__))
+__retarget_lock_try_acquire_recursive(_LOCK_T lock)
+{
+  return 1;
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_release (_LOCK_T lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_release_recursive (_LOCK_T lock)
+{
+}
diff --git a/newlib/newlib.hin b/newlib/newlib.hin
index d03dfac0eea6a8917a92b8f0f3584c2cd42b9388..397bc9b96eafddace3a75be509157040654b6fde 100644
--- a/newlib/newlib.hin
+++ b/newlib/newlib.hin
@@ -82,6 +82,9 @@
 /* Define if small footprint nano-formatted-IO implementation used.  */
 #undef _NANO_FORMATTED_IO
 
+/* Define if using retargetable functions for default lock routines.  */
+#undef _RETARGETABLE_LOCKING
+
 /*
  * Iconv encodings enabled ("to" direction)
  */

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2017-01-11 16:09             ` Thomas Preudhomme
@ 2017-01-11 16:46               ` Craig Howland
  2017-01-11 17:48                 ` Thomas Preudhomme
  0 siblings, 1 reply; 51+ messages in thread
From: Craig Howland @ 2017-01-11 16:46 UTC (permalink / raw)
  To: newlib

On 01/11/2017 11:09 AM, Thomas Preudhomme wrote:
> Here you are. It has worked fine with my limited testing. I welcome all 
> feedback about the testing you can throw at this.
>
> Best regards,
>
> Thomas

+TRAD_SYNOPSIS
+	void __retarget_lock_init(<[lock_ptr]>)
+	_LOCK_T * <[lock_ptr]>;
+
+	void __retarget_lock_init_recursive(<[lock_ptr]>)
+	_LOCK_T * <[lock_ptr]>;
...
  

Please leave out the TRAD_SYNOPSIS section.  The documentation tools ignore 
them.  It is not worth the time to attempt to maintain them. (While it's not 
necessarily worth the effort to go back and remove them from all the legacy 
files, it makes the most sense to not put them in new things so that going 
forward there is not quite as much clutter.)
Craig

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2017-01-11 16:46               ` Craig Howland
@ 2017-01-11 17:48                 ` Thomas Preudhomme
  2017-01-11 18:08                   ` Craig Howland
  2017-01-11 19:14                   ` Freddie Chopin
  0 siblings, 2 replies; 51+ messages in thread
From: Thomas Preudhomme @ 2017-01-11 17:48 UTC (permalink / raw)
  To: newlib

[-- Attachment #1: Type: text/plain, Size: 875 bytes --]

On 11/01/17 16:46, Craig Howland wrote:
> On 01/11/2017 11:09 AM, Thomas Preudhomme wrote:
>> Here you are. It has worked fine with my limited testing. I welcome all
>> feedback about the testing you can throw at this.
>>
>> Best regards,
>>
>> Thomas
>
> +TRAD_SYNOPSIS
> +    void __retarget_lock_init(<[lock_ptr]>)
> +    _LOCK_T * <[lock_ptr]>;
> +
> +    void __retarget_lock_init_recursive(<[lock_ptr]>)
> +    _LOCK_T * <[lock_ptr]>;
> ...
>
>
> Please leave out the TRAD_SYNOPSIS section.  The documentation tools ignore
> them.  It is not worth the time to attempt to maintain them. (While it's not
> necessarily worth the effort to go back and remove them from all the legacy
> files, it makes the most sense to not put them in new things so that going
> forward there is not quite as much clutter.)

Very well. How about the attached patch?

Best regards,

Thomas

[-- Attachment #2: newlib_retargetable_locking_routine.patch --]
[-- Type: text/x-patch, Size: 23284 bytes --]

diff --git a/newlib/configure b/newlib/configure
index 30e1d57664302248af9087b0051290e2aff4b382..42b1e13feeda8a5b7ad3cf365393bd4640da4c8c 100755
--- a/newlib/configure
+++ b/newlib/configure
@@ -798,6 +798,7 @@ enable_newlib_nano_malloc
 enable_newlib_unbuf_stream_opt
 enable_lite_exit
 enable_newlib_nano_formatted_io
+enable_newlib_retargetable_locking
 enable_multilib
 enable_target_optspace
 enable_malloc_debugging
@@ -1469,6 +1470,7 @@ Optional Features:
   --disable-newlib-unbuf-stream-opt    disable unbuffered stream optimization in streamio
   --enable-lite-exit	enable light weight exit
   --enable-newlib-nano-formatted-io    Use nano version formatted IO
+  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time
   --enable-multilib         build many library versions (default)
   --enable-target-optspace  optimize for space
   --enable-malloc-debugging indicate malloc debugging requested
@@ -2470,6 +2472,18 @@ else
 fi
 
 
+# Check whether --enable-newlib-retargetable-locking was given.
+if test "${enable_newlib_retargetable_locking+set}" = set; then :
+  enableval=$enable_newlib_retargetable_locking; case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_locking=no ;;
+   *) as_fn_error $? "bad value ${enableval} for newlib-retargetable-locking" "$LINENO" 5 ;;
+ esac
+else
+  newlib_retargetable_locking=no
+fi
+
+
 
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
@@ -11776,7 +11790,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11779 "configure"
+#line 11793 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11882,7 +11896,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11885 "configure"
+#line 11899 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12421,6 +12435,13 @@ _ACEOF
 
 fi
 
+if test "${newlib_retargetable_locking}" = "yes"; then
+cat >>confdefs.h <<_ACEOF
+#define _RETARGETABLE_LOCKING 1
+_ACEOF
+
+fi
+
 
 if test "x${iconv_encodings}" != "x" \
    || test "x${iconv_to_encodings}" != "x" \
diff --git a/newlib/configure.in b/newlib/configure.in
index 01c6367a99cdf6f74a5ad15c8a4eb4a45f206e9d..70cffa76a966f8d9cd1c8888156002e76ea13dc2 100644
--- a/newlib/configure.in
+++ b/newlib/configure.in
@@ -218,6 +218,17 @@ AC_ARG_ENABLE(newlib_nano_formatted_io,
    *) AC_MSG_ERROR(bad value ${enableval} for newlib-nano-formatted-io) ;;
  esac],[newlib_nano_formatted_io=no])
 
+dnl Support --enable-retargetable-locking
+dnl This option is also read in libc/configure.in.  It is repeated
+dnl here so that it shows up in the help text.
+AC_ARG_ENABLE(newlib-retargetable-locking,
+[  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time],
+[case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_locking=no ;;
+   *) AC_MSG_ERROR(bad value ${enableval} for newlib-retargetable-locking) ;;
+ esac],[newlib_retargetable_locking=no])
+
 NEWLIB_CONFIGURE(.)
 
 dnl We have to enable libtool after NEWLIB_CONFIGURE because if we try and
@@ -442,6 +453,10 @@ if test "${newlib_nano_formatted_io}" = "yes"; then
 AC_DEFINE_UNQUOTED(_NANO_FORMATTED_IO)
 fi
 
+if test "${newlib_retargetable_locking}" = "yes"; then
+AC_DEFINE_UNQUOTED(_RETARGETABLE_LOCKING)
+fi
+
 dnl
 dnl Parse --enable-newlib-iconv-encodings option argument
 dnl
diff --git a/newlib/libc/configure b/newlib/libc/configure
index 5dccc852b8cd90d697a90f113ec17982741ecc3a..35077b81550aa999026ff67a7428fec6509a26ce 100755
--- a/newlib/libc/configure
+++ b/newlib/libc/configure
@@ -751,6 +751,8 @@ build
 newlib_basedir
 MAY_SUPPLY_SYSCALLS_FALSE
 MAY_SUPPLY_SYSCALLS_TRUE
+NEWLIB_RETARGETABLE_LOCKING_FALSE
+NEWLIB_RETARGETABLE_LOCKING_TRUE
 NEWLIB_NANO_FORMATTED_IO_FALSE
 NEWLIB_NANO_FORMATTED_IO_TRUE
 target_alias
@@ -797,6 +799,7 @@ enable_option_checking
 enable_newlib_io_pos_args
 enable_newlib_nano_malloc
 enable_newlib_nano_formatted_io
+enable_newlib_retargetable_locking
 enable_multilib
 enable_target_optspace
 enable_malloc_debugging
@@ -1448,6 +1451,7 @@ Optional Features:
   --enable-newlib-io-pos-args enable printf-family positional arg support
   --enable-newlib-nano-malloc    Use small-footprint nano-malloc implementation
   --enable-newlib-nano-formatted-io    Use small-footprint nano-formatted-IO implementation
+  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time
   --enable-multilib         build many library versions (default)
   --enable-target-optspace  optimize for space
   --enable-malloc-debugging indicate malloc debugging requested
@@ -2252,6 +2256,26 @@ else
 fi
 
 
+# Check whether --enable-newlib-retargetable-locking was given.
+if test "${enable_newlib_retargetable_locking+set}" = set; then :
+  enableval=$enable_newlib_retargetable_locking; case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_lock=no ;;
+   *) as_fn_error $? "bad value ${enableval} for newlib-retargetable-locking" "$LINENO" 5 ;;
+ esac
+else
+  newlib_retargetable_locking=no
+fi
+
+ if test x$newlib_retargetable_locking = xyes; then
+  NEWLIB_RETARGETABLE_LOCKING_TRUE=
+  NEWLIB_RETARGETABLE_LOCKING_FALSE='#'
+else
+  NEWLIB_RETARGETABLE_LOCKING_TRUE='#'
+  NEWLIB_RETARGETABLE_LOCKING_FALSE=
+fi
+
+
 
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
@@ -11525,7 +11549,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11528 "configure"
+#line 11552 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11631,7 +11655,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11634 "configure"
+#line 11658 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12248,6 +12272,10 @@ if test -z "${NEWLIB_NANO_FORMATTED_IO_TRUE}" && test -z "${NEWLIB_NANO_FORMATTE
   as_fn_error $? "conditional \"NEWLIB_NANO_FORMATTED_IO\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${NEWLIB_RETARGETABLE_LOCKING_TRUE}" && test -z "${NEWLIB_RETARGETABLE_LOCKING_FALSE}"; then
+  as_fn_error $? "conditional \"NEWLIB_RETARGETABLE_LOCKING\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${MAY_SUPPLY_SYSCALLS_TRUE}" && test -z "${MAY_SUPPLY_SYSCALLS_FALSE}"; then
   as_fn_error $? "conditional \"MAY_SUPPLY_SYSCALLS\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
diff --git a/newlib/libc/configure.in b/newlib/libc/configure.in
index 0a7bb8815be44fb1e92f753fa2c8df2a31b95f94..ac25a3933c4a4794f3cfe291e0275d0ed001b96a 100644
--- a/newlib/libc/configure.in
+++ b/newlib/libc/configure.in
@@ -36,6 +36,16 @@ AC_ARG_ENABLE(newlib_nano_formatted_io,
  esac],[newlib_nano_formatted_io=no])
 AM_CONDITIONAL(NEWLIB_NANO_FORMATTED_IO, test x$newlib_nano_formatted_io = xyes)
 
+dnl Support --enable-retargetable-locking used by libc/sys
+AC_ARG_ENABLE(newlib-retargetable-locking,
+[  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time],
+[case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_lock=no ;;
+   *) AC_MSG_ERROR(bad value ${enableval} for newlib-retargetable-locking) ;;
+ esac],[newlib_retargetable_locking=no])
+AM_CONDITIONAL(NEWLIB_RETARGETABLE_LOCKING, test x$newlib_retargetable_locking = xyes)
+
 NEWLIB_CONFIGURE(..)
 
 AM_CONDITIONAL(NEWLIB_NANO_MALLOC, test x$newlib_nano_malloc = xyes)
diff --git a/newlib/libc/include/sys/lock.h b/newlib/libc/include/sys/lock.h
index 9075e35c9179968031010432515e3a845ff6ca8d..9a8e2528c79a89d5807da8c4bb0e65151870bf42 100644
--- a/newlib/libc/include/sys/lock.h
+++ b/newlib/libc/include/sys/lock.h
@@ -3,10 +3,13 @@
 
 /* dummy lock routines for single-threaded aps */
 
+#include <newlib.h>
+#include <_ansi.h>
+
+#ifndef _RETARGETABLE_LOCKING
+
 typedef int _LOCK_T;
 typedef int _LOCK_RECURSIVE_T;
- 
-#include <_ansi.h>
 
 #define __LOCK_INIT(class,lock) static int lock = 0;
 #define __LOCK_INIT_RECURSIVE(class,lock) static int lock = 0;
@@ -21,4 +24,46 @@ typedef int _LOCK_RECURSIVE_T;
 #define __lock_release(lock) (_CAST_VOID 0)
 #define __lock_release_recursive(lock) (_CAST_VOID 0)
 
+#else
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _lock;
+typedef struct _lock * _LOCK_T;
+#define _LOCK_RECURSIVE_T _LOCK_T
+
+#define __LOCK_INIT(class,lock) extern struct _lock _lock_ ## lock; \
+	class _LOCK_T lock = &_lock_ ## lock
+#define __LOCK_INIT_RECURSIVE(class,lock) __LOCK_INIT(class,lock)
+
+extern void __retarget_lock_init(_LOCK_T *lock);
+#define __lock_init(lock) __retarget_lock_init(&lock)
+extern void __retarget_lock_init_recursive(_LOCK_T *lock);
+#define __lock_init_recursive(lock) __retarget_lock_init_recursive(&lock)
+extern void __retarget_lock_close(_LOCK_T lock);
+#define __lock_close(lock) __retarget_lock_close(lock)
+extern void __retarget_lock_close_recursive(_LOCK_T lock);
+#define __lock_close_recursive(lock) __retarget_lock_close_recursive(lock)
+extern void __retarget_lock_acquire(_LOCK_T lock);
+#define __lock_acquire(lock) __retarget_lock_acquire(lock)
+extern void __retarget_lock_acquire_recursive(_LOCK_T lock);
+#define __lock_acquire_recursive(lock) __retarget_lock_acquire_recursive(lock)
+extern int __retarget_lock_try_acquire(_LOCK_T lock);
+#define __lock_try_acquire(lock) __retarget_lock_try_acquire(lock)
+extern int __retarget_lock_try_acquire_recursive(_LOCK_T lock);
+#define __lock_try_acquire_recursive(lock) \
+  __retarget_lock_try_acquire_recursive(lock)
+extern void __retarget_lock_release(_LOCK_T lock);
+#define __lock_release(lock) __retarget_lock_release(lock)
+extern void __retarget_lock_release_recursive(_LOCK_T lock);
+#define __lock_release_recursive(lock) __retarget_lock_release_recursive(lock)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RETARGETABLE_LOCKING */
+
 #endif /* __SYS_LOCK_H__ */
diff --git a/newlib/libc/stdlib/Makefile.am b/newlib/libc/stdlib/Makefile.am
index 2d45d1029ace8087b57657cbc11feabf76f4206e..76ed8480c28ebfb68e2f48432c0359b11f1522a8 100644
--- a/newlib/libc/stdlib/Makefile.am
+++ b/newlib/libc/stdlib/Makefile.am
@@ -74,6 +74,11 @@ GENERAL_SOURCES += \
 	wcstold.c
 endif # HAVE_LONG_DOUBLE
 
+if NEWLIB_RETARGETABLE_LOCKING
+GENERAL_SOURCES += \
+	lock.c
+endif
+
 if NEWLIB_NANO_MALLOC
 MALIGNR=nano-malignr
 MALLOPTR=nano-malloptr
diff --git a/newlib/libc/stdlib/Makefile.in b/newlib/libc/stdlib/Makefile.in
index 466ab6d1e02ea919f6c8ceed792024955bef1a66..3295e981c87bac3b21a6b72dda148f892fe018d6 100644
--- a/newlib/libc/stdlib/Makefile.in
+++ b/newlib/libc/stdlib/Makefile.in
@@ -57,6 +57,9 @@ host_triplet = @host@
 @HAVE_LONG_DOUBLE_TRUE@	strtold.c \
 @HAVE_LONG_DOUBLE_TRUE@	wcstold.c
 
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@am__append_2 = \
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@	lock.c
+
 DIST_COMMON = $(srcdir)/../../Makefile.shared $(srcdir)/Makefile.in \
 	$(srcdir)/Makefile.am
 subdir = stdlib
@@ -81,7 +84,9 @@ lib_a_AR = $(AR) $(ARFLAGS)
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(ELIX_2_OBJS)
 @HAVE_LONG_DOUBLE_TRUE@am__objects_1 = lib_a-strtold.$(OBJEXT) \
 @HAVE_LONG_DOUBLE_TRUE@	lib_a-wcstold.$(OBJEXT)
-am__objects_2 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@am__objects_2 =  \
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@	lib_a-lock.$(OBJEXT)
+am__objects_3 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \
 	lib_a-__call_atexit.$(OBJEXT) lib_a-__exp10.$(OBJEXT) \
 	lib_a-__ten_mu.$(OBJEXT) lib_a-_Exit.$(OBJEXT) \
 	lib_a-abort.$(OBJEXT) lib_a-abs.$(OBJEXT) \
@@ -112,8 +117,8 @@ am__objects_2 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \
 	lib_a-wcstol.$(OBJEXT) lib_a-wcstoul.$(OBJEXT) \
 	lib_a-wcstombs.$(OBJEXT) lib_a-wcstombs_r.$(OBJEXT) \
 	lib_a-wctomb.$(OBJEXT) lib_a-wctomb_r.$(OBJEXT) \
-	$(am__objects_1)
-am__objects_3 = lib_a-arc4random.$(OBJEXT) \
+	$(am__objects_1) $(am__objects_2)
+am__objects_4 = lib_a-arc4random.$(OBJEXT) \
 	lib_a-arc4random_uniform.$(OBJEXT) lib_a-cxa_atexit.$(OBJEXT) \
 	lib_a-cxa_finalize.$(OBJEXT) lib_a-drand48.$(OBJEXT) \
 	lib_a-ecvtbuf.$(OBJEXT) lib_a-efgcvt.$(OBJEXT) \
@@ -128,7 +133,7 @@ am__objects_3 = lib_a-arc4random.$(OBJEXT) \
 	lib_a-wcstoll_r.$(OBJEXT) lib_a-wcstoull.$(OBJEXT) \
 	lib_a-wcstoull_r.$(OBJEXT) lib_a-atoll.$(OBJEXT) \
 	lib_a-llabs.$(OBJEXT) lib_a-lldiv.$(OBJEXT)
-am__objects_4 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \
+am__objects_5 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \
 	lib_a-getopt.$(OBJEXT) lib_a-getsubopt.$(OBJEXT) \
 	lib_a-l64a.$(OBJEXT) lib_a-malign.$(OBJEXT) \
 	lib_a-mbrlen.$(OBJEXT) lib_a-mbrtowc.$(OBJEXT) \
@@ -137,22 +142,23 @@ am__objects_4 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \
 	lib_a-valloc.$(OBJEXT) lib_a-wcrtomb.$(OBJEXT) \
 	lib_a-wcsnrtombs.$(OBJEXT) lib_a-wcsrtombs.$(OBJEXT) \
 	lib_a-wctob.$(OBJEXT)
-am__objects_5 = lib_a-putenv.$(OBJEXT) lib_a-putenv_r.$(OBJEXT) \
+am__objects_6 = lib_a-putenv.$(OBJEXT) lib_a-putenv_r.$(OBJEXT) \
 	lib_a-setenv.$(OBJEXT) lib_a-setenv_r.$(OBJEXT)
-am__objects_6 = lib_a-rpmatch.$(OBJEXT) lib_a-system.$(OBJEXT)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_7 = $(am__objects_4) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_5) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_6)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_7 = $(am__objects_4) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_5)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_7 =  \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_4)
-@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_2) \
-@USE_LIBTOOL_FALSE@	$(am__objects_3) $(am__objects_7)
+am__objects_7 = lib_a-rpmatch.$(OBJEXT) lib_a-system.$(OBJEXT)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_8 = $(am__objects_5) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_6) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_7)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_8 = $(am__objects_5) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_6)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_8 =  \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_5)
+@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_3) \
+@USE_LIBTOOL_FALSE@	$(am__objects_4) $(am__objects_8)
 lib_a_OBJECTS = $(am_lib_a_OBJECTS)
 LTLIBRARIES = $(noinst_LTLIBRARIES)
-@HAVE_LONG_DOUBLE_TRUE@am__objects_8 = strtold.lo wcstold.lo
-am__objects_9 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \
+@HAVE_LONG_DOUBLE_TRUE@am__objects_9 = strtold.lo wcstold.lo
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@am__objects_10 = lock.lo
+am__objects_11 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \
 	__ten_mu.lo _Exit.lo abort.lo abs.lo aligned_alloc.lo \
 	assert.lo atexit.lo atof.lo atoff.lo atoi.lo atol.lo calloc.lo \
 	div.lo dtoa.lo dtoastub.lo environ.lo envlock.lo eprintf.lo \
@@ -163,28 +169,28 @@ am__objects_9 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \
 	rand_r.lo random.lo realloc.lo reallocf.lo sb_charsets.lo \
 	strtod.lo strtodg.lo strtol.lo strtorx.lo strtoul.lo utoa.lo \
 	wcstod.lo wcstol.lo wcstoul.lo wcstombs.lo wcstombs_r.lo \
-	wctomb.lo wctomb_r.lo $(am__objects_8)
-am__objects_10 = arc4random.lo arc4random_uniform.lo cxa_atexit.lo \
+	wctomb.lo wctomb_r.lo $(am__objects_9) $(am__objects_10)
+am__objects_12 = arc4random.lo arc4random_uniform.lo cxa_atexit.lo \
 	cxa_finalize.lo drand48.lo ecvtbuf.lo efgcvt.lo erand48.lo \
 	jrand48.lo lcong48.lo lrand48.lo mrand48.lo msize.lo mtrim.lo \
 	nrand48.lo rand48.lo seed48.lo srand48.lo strtoll.lo \
 	strtoll_r.lo strtoull.lo strtoull_r.lo wcstoll.lo wcstoll_r.lo \
 	wcstoull.lo wcstoull_r.lo atoll.lo llabs.lo lldiv.lo
-am__objects_11 = a64l.lo btowc.lo getopt.lo getsubopt.lo l64a.lo \
+am__objects_13 = a64l.lo btowc.lo getopt.lo getsubopt.lo l64a.lo \
 	malign.lo mbrlen.lo mbrtowc.lo mbsinit.lo mbsnrtowcs.lo \
 	mbsrtowcs.lo on_exit.lo valloc.lo wcrtomb.lo wcsnrtombs.lo \
 	wcsrtombs.lo wctob.lo
-am__objects_12 = putenv.lo putenv_r.lo setenv.lo setenv_r.lo
-am__objects_13 = rpmatch.lo system.lo
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_14 = $(am__objects_11) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_12) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_13)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_14 = $(am__objects_11) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_12)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_14 =  \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_11)
-@USE_LIBTOOL_TRUE@am_libstdlib_la_OBJECTS = $(am__objects_9) \
-@USE_LIBTOOL_TRUE@	$(am__objects_10) $(am__objects_14)
+am__objects_14 = putenv.lo putenv_r.lo setenv.lo setenv_r.lo
+am__objects_15 = rpmatch.lo system.lo
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_16 = $(am__objects_13) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_14) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_15)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_16 = $(am__objects_13) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_14)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_16 =  \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_13)
+@USE_LIBTOOL_TRUE@am_libstdlib_la_OBJECTS = $(am__objects_11) \
+@USE_LIBTOOL_TRUE@	$(am__objects_12) $(am__objects_16)
 libstdlib_la_OBJECTS = $(am_libstdlib_la_OBJECTS)
 libstdlib_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -367,7 +373,7 @@ GENERAL_SOURCES = __adjust.c __atexit.c __call_atexit.c __exp10.c \
 	quick_exit.c rand.c rand_r.c random.c realloc.c reallocf.c \
 	sb_charsets.c strtod.c strtodg.c strtol.c strtorx.c strtoul.c \
 	utoa.c wcstod.c wcstol.c wcstoul.c wcstombs.c wcstombs_r.c \
-	wctomb.c wctomb_r.c $(am__append_1)
+	wctomb.c wctomb_r.c $(am__append_1) $(am__append_2)
 @NEWLIB_NANO_MALLOC_FALSE@MALIGNR = malignr
 @NEWLIB_NANO_MALLOC_TRUE@MALIGNR = nano-malignr
 @NEWLIB_NANO_MALLOC_FALSE@MALLOPTR = malloptr
@@ -1002,6 +1008,12 @@ lib_a-wcstold.o: wcstold.c
 lib_a-wcstold.obj: wcstold.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcstold.obj `if test -f 'wcstold.c'; then $(CYGPATH_W) 'wcstold.c'; else $(CYGPATH_W) '$(srcdir)/wcstold.c'; fi`
 
+lib_a-lock.o: lock.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lock.o `test -f 'lock.c' || echo '$(srcdir)/'`lock.c
+
+lib_a-lock.obj: lock.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lock.obj `if test -f 'lock.c'; then $(CYGPATH_W) 'lock.c'; else $(CYGPATH_W) '$(srcdir)/lock.c'; fi`
+
 lib_a-arc4random.o: arc4random.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-arc4random.o `test -f 'arc4random.c' || echo '$(srcdir)/'`arc4random.c
 
diff --git a/newlib/libc/stdlib/lock.c b/newlib/libc/stdlib/lock.c
new file mode 100644
index 0000000000000000000000000000000000000000..c0b8a173a3bae16cd91d231dff7de2b4bb8cd9e3
--- /dev/null
+++ b/newlib/libc/stdlib/lock.c
@@ -0,0 +1,108 @@
+/*
+FUNCTION
+<<__retarget_lock_init>>, <<__retarget_lock_init_recursive>>, <<__retarget_lock_close>>, <<__retarget_lock_close_recursive>>, <<__retarget_lock_acquire>>, <<__retarget_lock_acquire_recursive>>, <<__retarget_lock_try_acquire>>, <<__retarget_lock_try_acquire_recursive>>, <<__retarget_lock_release>>, <<__retarget_lock_release_recursive>>---locking routines
+
+INDEX
+	__retarget_lock_init
+INDEX
+	__retarget_lock_init_recursive
+INDEX
+	__retarget_lock_close
+INDEX
+	__retarget_lock_close_recursive
+INDEX
+	__retarget_lock_acquire
+INDEX
+	__retarget_lock_acquire_recursive
+INDEX
+	__retarget_lock_try_acquire
+INDEX
+	__retarget_lock_try_acquire_recursive
+INDEX
+	__retarget_lock_release
+INDEX
+	__retarget_lock_release_recursive
+
+ANSI_SYNOPSIS
+	#include <lock.h>
+	void __retarget_lock_init (_LOCK_T * <[lock_ptr]>);
+	void __retarget_lock_init_recursive (_LOCK_T * <[lock_ptr]>);
+	void __retarget_lock_close (_LOCK_T <[lock]>);
+	void __retarget_lock_close_recursive (_LOCK_T <[lock]>);
+	void __retarget_lock_acquire (_LOCK_T <[lock]>);
+	void __retarget_lock_acquire_recursive (_LOCK_T <[lock]>);
+	int __retarget_lock_try_acquire (_LOCK_T <[lock]>);
+	int __retarget_lock_try_acquire_recursive (_LOCK_T <[lock]>);
+	void __retarget_lock_release (_LOCK_T <[lock]>);
+	void __retarget_lock_release_recursive (_LOCK_T <[lock]>);
+
+DESCRIPTION
+These empty functions are used for locking to allow applications to retarget
+them.  They are used in place of the default dummy lock macros when newlib
+is configured with --enable-newlib-retargetable-locking.
+*/
+
+/* dummy lock routines for single-threaded apps */
+
+#include <sys/lock.h>
+
+struct _lock {
+  char unused;
+};
+
+struct _lock _ATTRIBUTE((__weak__)) _lock___sinit_lock;
+struct _lock _ATTRIBUTE((__weak__)) _lock___sfp_lock;
+struct _lock _ATTRIBUTE((__weak__)) _lock___atexit_lock;
+struct _lock _ATTRIBUTE((__weak__)) _lock___malloc_lock_object;
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_init (_LOCK_T *lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_init_recursive(_LOCK_T *lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_close(_LOCK_T lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_close_recursive(_LOCK_T lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_acquire (_LOCK_T lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_acquire_recursive (_LOCK_T lock)
+{
+}
+
+int _ATTRIBUTE((__weak__))
+__retarget_lock_try_acquire(_LOCK_T lock)
+{
+  return 1;
+}
+
+int _ATTRIBUTE((__weak__))
+__retarget_lock_try_acquire_recursive(_LOCK_T lock)
+{
+  return 1;
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_release (_LOCK_T lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_release_recursive (_LOCK_T lock)
+{
+}
diff --git a/newlib/newlib.hin b/newlib/newlib.hin
index d03dfac0eea6a8917a92b8f0f3584c2cd42b9388..397bc9b96eafddace3a75be509157040654b6fde 100644
--- a/newlib/newlib.hin
+++ b/newlib/newlib.hin
@@ -82,6 +82,9 @@
 /* Define if small footprint nano-formatted-IO implementation used.  */
 #undef _NANO_FORMATTED_IO
 
+/* Define if using retargetable functions for default lock routines.  */
+#undef _RETARGETABLE_LOCKING
+
 /*
  * Iconv encodings enabled ("to" direction)
  */

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2017-01-11 17:48                 ` Thomas Preudhomme
@ 2017-01-11 18:08                   ` Craig Howland
  2017-01-11 19:14                   ` Freddie Chopin
  1 sibling, 0 replies; 51+ messages in thread
From: Craig Howland @ 2017-01-11 18:08 UTC (permalink / raw)
  To: newlib

On 01/11/2017 12:48 PM, Thomas Preudhomme wrote:
> On 11/01/17 16:46, Craig Howland wrote:
>> On 01/11/2017 11:09 AM, Thomas Preudhomme wrote:
>>> Here you are. It has worked fine with my limited testing. I welcome all
>>> feedback about the testing you can throw at this.
>>>
>>> Best regards,
>>>
>>> Thomas
>>
>> +TRAD_SYNOPSIS
>> +    void __retarget_lock_init(<[lock_ptr]>)
>> +    _LOCK_T * <[lock_ptr]>;
>> +
>> +    void __retarget_lock_init_recursive(<[lock_ptr]>)
>> +    _LOCK_T * <[lock_ptr]>;
>> ...
>>
>>
>> Please leave out the TRAD_SYNOPSIS section.  The documentation tools ignore
>> them.  It is not worth the time to attempt to maintain them. (While it's not
>> necessarily worth the effort to go back and remove them from all the legacy
>> files, it makes the most sense to not put them in new things so that going
>> forward there is not quite as much clutter.)
>
> Very well. How about the attached patch?
>
> Best regards,
>
> Thomas
That aspect of it looks good.  Thank you.
Someone else is better suited for commenting on the real contents of the patch, 
however.
Craig

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2017-01-11 17:48                 ` Thomas Preudhomme
  2017-01-11 18:08                   ` Craig Howland
@ 2017-01-11 19:14                   ` Freddie Chopin
  2017-01-12 10:52                     ` Thomas Preudhomme
  1 sibling, 1 reply; 51+ messages in thread
From: Freddie Chopin @ 2017-01-11 19:14 UTC (permalink / raw)
  To: newlib

On Wed, 2017-01-11 at 17:48 +0000, Thomas Preudhomme wrote:
> Very well. How about the attached patch?

Hmm... Trying to apply that to newlib-2.5.0 fails with:

(Stripping trailing CRs from patch; use --binary to disable.)
patching file newlib/configure
Hunk #1 succeeded at 802 (offset 4 lines).
Hunk #2 succeeded at 1474 (offset 4 lines).
Hunk #3 succeeded at 2476 (offset 4 lines).
Hunk #4 FAILED at 11790.
Hunk #5 FAILED at 11896.
Hunk #6 succeeded at 12469 (offset 34 lines).
2 out of 6 hunks FAILED -- saving rejects to file newlib/configure.rej
(Stripping trailing CRs from patch; use --binary to disable.)
patching file newlib/configure.in
Hunk #2 succeeded at 469 (offset 16 lines).
(Stripping trailing CRs from patch; use --binary to disable.)
patching file newlib/libc/configure
(Stripping trailing CRs from patch; use --binary to disable.)
patching file newlib/libc/configure.in
(Stripping trailing CRs from patch; use --binary to disable.)
patching file newlib/libc/include/sys/lock.h
Hunk #1 FAILED at 3.
1 out of 2 hunks FAILED -- saving rejects to file
newlib/libc/include/sys/lock.h.rej
(Stripping trailing CRs from patch; use --binary to disable.)
patching file newlib/libc/stdlib/Makefile.am
(Stripping trailing CRs from patch; use --binary to disable.)
patching file newlib/libc/stdlib/Makefile.in
(Stripping trailing CRs from patch; use --binary to disable.)
patching file newlib/libc/stdlib/lock.c
(Stripping trailing CRs from patch; use --binary to disable.)
patching file newlib/newlib.hin

I'm not sure what version of newlib is your patched based on, maybe you
could rebase it on top of the HEAD of the repository?

Regards,
FCh

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2017-01-11 19:14                   ` Freddie Chopin
@ 2017-01-12 10:52                     ` Thomas Preudhomme
  2017-01-12 16:20                       ` Freddie Chopin
  0 siblings, 1 reply; 51+ messages in thread
From: Thomas Preudhomme @ 2017-01-12 10:52 UTC (permalink / raw)
  To: newlib

[-- Attachment #1: Type: text/plain, Size: 725 bytes --]



On 11/01/17 19:14, Freddie Chopin wrote:
> On Wed, 2017-01-11 at 17:48 +0000, Thomas Preudhomme wrote:
>> Very well. How about the attached patch?
>
> Hmm... Trying to apply that to newlib-2.5.0 fails with:
>
> (Stripping trailing CRs from patch; use --binary to disable.)
> patching file newlib/configure
> Hunk #1 succeeded at 802 (offset 4 lines).
> Hunk #2 succeeded at 1474 (offset 4 lines).
> Hunk #3 succeeded at 2476 (offset 4 lines).
> Hunk #4 FAILED at 11790.
> Hunk #5 FAILED at 11896.
> Hunk #6 succeeded at 12469 (offset 34 lines).
> 2 out of 6 hunks FAILED -- saving rejects to file newlib/configure.rej

My bad. I've rebased it on latest master branch. Please find the patch attached.

Best regards,

Thomas

[-- Attachment #2: newlib_retargetable_locking_routine.patch --]
[-- Type: text/x-patch, Size: 23284 bytes --]

diff --git a/newlib/configure b/newlib/configure
index 2ac07fe06bfc795d94ba36d0061e4f8135146125..de28c25b3c4aaeed14b6d0ee8354fdd5c5c3115a 100755
--- a/newlib/configure
+++ b/newlib/configure
@@ -802,6 +802,7 @@ enable_newlib_nano_malloc
 enable_newlib_unbuf_stream_opt
 enable_lite_exit
 enable_newlib_nano_formatted_io
+enable_newlib_retargetable_locking
 enable_multilib
 enable_target_optspace
 enable_malloc_debugging
@@ -1473,6 +1474,7 @@ Optional Features:
   --disable-newlib-unbuf-stream-opt    disable unbuffered stream optimization in streamio
   --enable-lite-exit	enable light weight exit
   --enable-newlib-nano-formatted-io    Use nano version formatted IO
+  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time
   --enable-multilib         build many library versions (default)
   --enable-target-optspace  optimize for space
   --enable-malloc-debugging indicate malloc debugging requested
@@ -2474,6 +2476,18 @@ else
 fi
 
 
+# Check whether --enable-newlib-retargetable-locking was given.
+if test "${enable_newlib_retargetable_locking+set}" = set; then :
+  enableval=$enable_newlib_retargetable_locking; case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_locking=no ;;
+   *) as_fn_error $? "bad value ${enableval} for newlib-retargetable-locking" "$LINENO" 5 ;;
+ esac
+else
+  newlib_retargetable_locking=no
+fi
+
+
 
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
@@ -11780,7 +11794,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11783 "configure"
+#line 11797 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11886,7 +11900,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11889 "configure"
+#line 11903 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12455,6 +12469,13 @@ _ACEOF
 
 fi
 
+if test "${newlib_retargetable_locking}" = "yes"; then
+cat >>confdefs.h <<_ACEOF
+#define _RETARGETABLE_LOCKING 1
+_ACEOF
+
+fi
+
 
 if test "x${iconv_encodings}" != "x" \
    || test "x${iconv_to_encodings}" != "x" \
diff --git a/newlib/configure.in b/newlib/configure.in
index bfaf038c7f495d32d05ae8caff0172f464895ffe..354c07ca580edf75da59fb858ca2c434e0b1a4e9 100644
--- a/newlib/configure.in
+++ b/newlib/configure.in
@@ -218,6 +218,17 @@ AC_ARG_ENABLE(newlib_nano_formatted_io,
    *) AC_MSG_ERROR(bad value ${enableval} for newlib-nano-formatted-io) ;;
  esac],[newlib_nano_formatted_io=no])
 
+dnl Support --enable-retargetable-locking
+dnl This option is also read in libc/configure.in.  It is repeated
+dnl here so that it shows up in the help text.
+AC_ARG_ENABLE(newlib-retargetable-locking,
+[  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time],
+[case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_locking=no ;;
+   *) AC_MSG_ERROR(bad value ${enableval} for newlib-retargetable-locking) ;;
+ esac],[newlib_retargetable_locking=no])
+
 NEWLIB_CONFIGURE(.)
 
 dnl We have to enable libtool after NEWLIB_CONFIGURE because if we try and
@@ -458,6 +469,10 @@ if test "${newlib_nano_formatted_io}" = "yes"; then
 AC_DEFINE_UNQUOTED(_NANO_FORMATTED_IO)
 fi
 
+if test "${newlib_retargetable_locking}" = "yes"; then
+AC_DEFINE_UNQUOTED(_RETARGETABLE_LOCKING)
+fi
+
 dnl
 dnl Parse --enable-newlib-iconv-encodings option argument
 dnl
diff --git a/newlib/libc/configure b/newlib/libc/configure
index 4dc4d1bf703f388ecd3b4e0d8bef6786f7995021..dabe44fd98d74a2e029a22a217953dd52575736f 100755
--- a/newlib/libc/configure
+++ b/newlib/libc/configure
@@ -751,6 +751,8 @@ build
 newlib_basedir
 MAY_SUPPLY_SYSCALLS_FALSE
 MAY_SUPPLY_SYSCALLS_TRUE
+NEWLIB_RETARGETABLE_LOCKING_FALSE
+NEWLIB_RETARGETABLE_LOCKING_TRUE
 NEWLIB_NANO_FORMATTED_IO_FALSE
 NEWLIB_NANO_FORMATTED_IO_TRUE
 target_alias
@@ -797,6 +799,7 @@ enable_option_checking
 enable_newlib_io_pos_args
 enable_newlib_nano_malloc
 enable_newlib_nano_formatted_io
+enable_newlib_retargetable_locking
 enable_multilib
 enable_target_optspace
 enable_malloc_debugging
@@ -1448,6 +1451,7 @@ Optional Features:
   --enable-newlib-io-pos-args enable printf-family positional arg support
   --enable-newlib-nano-malloc    Use small-footprint nano-malloc implementation
   --enable-newlib-nano-formatted-io    Use small-footprint nano-formatted-IO implementation
+  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time
   --enable-multilib         build many library versions (default)
   --enable-target-optspace  optimize for space
   --enable-malloc-debugging indicate malloc debugging requested
@@ -2252,6 +2256,26 @@ else
 fi
 
 
+# Check whether --enable-newlib-retargetable-locking was given.
+if test "${enable_newlib_retargetable_locking+set}" = set; then :
+  enableval=$enable_newlib_retargetable_locking; case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_lock=no ;;
+   *) as_fn_error $? "bad value ${enableval} for newlib-retargetable-locking" "$LINENO" 5 ;;
+ esac
+else
+  newlib_retargetable_locking=no
+fi
+
+ if test x$newlib_retargetable_locking = xyes; then
+  NEWLIB_RETARGETABLE_LOCKING_TRUE=
+  NEWLIB_RETARGETABLE_LOCKING_FALSE='#'
+else
+  NEWLIB_RETARGETABLE_LOCKING_TRUE='#'
+  NEWLIB_RETARGETABLE_LOCKING_FALSE=
+fi
+
+
 
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
@@ -11525,7 +11549,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11528 "configure"
+#line 11552 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11631,7 +11655,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11634 "configure"
+#line 11658 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12248,6 +12272,10 @@ if test -z "${NEWLIB_NANO_FORMATTED_IO_TRUE}" && test -z "${NEWLIB_NANO_FORMATTE
   as_fn_error $? "conditional \"NEWLIB_NANO_FORMATTED_IO\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${NEWLIB_RETARGETABLE_LOCKING_TRUE}" && test -z "${NEWLIB_RETARGETABLE_LOCKING_FALSE}"; then
+  as_fn_error $? "conditional \"NEWLIB_RETARGETABLE_LOCKING\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${MAY_SUPPLY_SYSCALLS_TRUE}" && test -z "${MAY_SUPPLY_SYSCALLS_FALSE}"; then
   as_fn_error $? "conditional \"MAY_SUPPLY_SYSCALLS\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
diff --git a/newlib/libc/configure.in b/newlib/libc/configure.in
index 0a7bb8815be44fb1e92f753fa2c8df2a31b95f94..ac25a3933c4a4794f3cfe291e0275d0ed001b96a 100644
--- a/newlib/libc/configure.in
+++ b/newlib/libc/configure.in
@@ -36,6 +36,16 @@ AC_ARG_ENABLE(newlib_nano_formatted_io,
  esac],[newlib_nano_formatted_io=no])
 AM_CONDITIONAL(NEWLIB_NANO_FORMATTED_IO, test x$newlib_nano_formatted_io = xyes)
 
+dnl Support --enable-retargetable-locking used by libc/sys
+AC_ARG_ENABLE(newlib-retargetable-locking,
+[  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time],
+[case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_lock=no ;;
+   *) AC_MSG_ERROR(bad value ${enableval} for newlib-retargetable-locking) ;;
+ esac],[newlib_retargetable_locking=no])
+AM_CONDITIONAL(NEWLIB_RETARGETABLE_LOCKING, test x$newlib_retargetable_locking = xyes)
+
 NEWLIB_CONFIGURE(..)
 
 AM_CONDITIONAL(NEWLIB_NANO_MALLOC, test x$newlib_nano_malloc = xyes)
diff --git a/newlib/libc/include/sys/lock.h b/newlib/libc/include/sys/lock.h
index 9075e35c9179968031010432515e3a845ff6ca8d..9a8e2528c79a89d5807da8c4bb0e65151870bf42 100644
--- a/newlib/libc/include/sys/lock.h
+++ b/newlib/libc/include/sys/lock.h
@@ -3,10 +3,13 @@
 
 /* dummy lock routines for single-threaded aps */
 
+#include <newlib.h>
+#include <_ansi.h>
+
+#ifndef _RETARGETABLE_LOCKING
+
 typedef int _LOCK_T;
 typedef int _LOCK_RECURSIVE_T;
- 
-#include <_ansi.h>
 
 #define __LOCK_INIT(class,lock) static int lock = 0;
 #define __LOCK_INIT_RECURSIVE(class,lock) static int lock = 0;
@@ -21,4 +24,46 @@ typedef int _LOCK_RECURSIVE_T;
 #define __lock_release(lock) (_CAST_VOID 0)
 #define __lock_release_recursive(lock) (_CAST_VOID 0)
 
+#else
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _lock;
+typedef struct _lock * _LOCK_T;
+#define _LOCK_RECURSIVE_T _LOCK_T
+
+#define __LOCK_INIT(class,lock) extern struct _lock _lock_ ## lock; \
+	class _LOCK_T lock = &_lock_ ## lock
+#define __LOCK_INIT_RECURSIVE(class,lock) __LOCK_INIT(class,lock)
+
+extern void __retarget_lock_init(_LOCK_T *lock);
+#define __lock_init(lock) __retarget_lock_init(&lock)
+extern void __retarget_lock_init_recursive(_LOCK_T *lock);
+#define __lock_init_recursive(lock) __retarget_lock_init_recursive(&lock)
+extern void __retarget_lock_close(_LOCK_T lock);
+#define __lock_close(lock) __retarget_lock_close(lock)
+extern void __retarget_lock_close_recursive(_LOCK_T lock);
+#define __lock_close_recursive(lock) __retarget_lock_close_recursive(lock)
+extern void __retarget_lock_acquire(_LOCK_T lock);
+#define __lock_acquire(lock) __retarget_lock_acquire(lock)
+extern void __retarget_lock_acquire_recursive(_LOCK_T lock);
+#define __lock_acquire_recursive(lock) __retarget_lock_acquire_recursive(lock)
+extern int __retarget_lock_try_acquire(_LOCK_T lock);
+#define __lock_try_acquire(lock) __retarget_lock_try_acquire(lock)
+extern int __retarget_lock_try_acquire_recursive(_LOCK_T lock);
+#define __lock_try_acquire_recursive(lock) \
+  __retarget_lock_try_acquire_recursive(lock)
+extern void __retarget_lock_release(_LOCK_T lock);
+#define __lock_release(lock) __retarget_lock_release(lock)
+extern void __retarget_lock_release_recursive(_LOCK_T lock);
+#define __lock_release_recursive(lock) __retarget_lock_release_recursive(lock)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RETARGETABLE_LOCKING */
+
 #endif /* __SYS_LOCK_H__ */
diff --git a/newlib/libc/stdlib/Makefile.am b/newlib/libc/stdlib/Makefile.am
index 2d45d1029ace8087b57657cbc11feabf76f4206e..76ed8480c28ebfb68e2f48432c0359b11f1522a8 100644
--- a/newlib/libc/stdlib/Makefile.am
+++ b/newlib/libc/stdlib/Makefile.am
@@ -74,6 +74,11 @@ GENERAL_SOURCES += \
 	wcstold.c
 endif # HAVE_LONG_DOUBLE
 
+if NEWLIB_RETARGETABLE_LOCKING
+GENERAL_SOURCES += \
+	lock.c
+endif
+
 if NEWLIB_NANO_MALLOC
 MALIGNR=nano-malignr
 MALLOPTR=nano-malloptr
diff --git a/newlib/libc/stdlib/Makefile.in b/newlib/libc/stdlib/Makefile.in
index 466ab6d1e02ea919f6c8ceed792024955bef1a66..3295e981c87bac3b21a6b72dda148f892fe018d6 100644
--- a/newlib/libc/stdlib/Makefile.in
+++ b/newlib/libc/stdlib/Makefile.in
@@ -57,6 +57,9 @@ host_triplet = @host@
 @HAVE_LONG_DOUBLE_TRUE@	strtold.c \
 @HAVE_LONG_DOUBLE_TRUE@	wcstold.c
 
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@am__append_2 = \
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@	lock.c
+
 DIST_COMMON = $(srcdir)/../../Makefile.shared $(srcdir)/Makefile.in \
 	$(srcdir)/Makefile.am
 subdir = stdlib
@@ -81,7 +84,9 @@ lib_a_AR = $(AR) $(ARFLAGS)
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(ELIX_2_OBJS)
 @HAVE_LONG_DOUBLE_TRUE@am__objects_1 = lib_a-strtold.$(OBJEXT) \
 @HAVE_LONG_DOUBLE_TRUE@	lib_a-wcstold.$(OBJEXT)
-am__objects_2 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@am__objects_2 =  \
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@	lib_a-lock.$(OBJEXT)
+am__objects_3 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \
 	lib_a-__call_atexit.$(OBJEXT) lib_a-__exp10.$(OBJEXT) \
 	lib_a-__ten_mu.$(OBJEXT) lib_a-_Exit.$(OBJEXT) \
 	lib_a-abort.$(OBJEXT) lib_a-abs.$(OBJEXT) \
@@ -112,8 +117,8 @@ am__objects_2 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \
 	lib_a-wcstol.$(OBJEXT) lib_a-wcstoul.$(OBJEXT) \
 	lib_a-wcstombs.$(OBJEXT) lib_a-wcstombs_r.$(OBJEXT) \
 	lib_a-wctomb.$(OBJEXT) lib_a-wctomb_r.$(OBJEXT) \
-	$(am__objects_1)
-am__objects_3 = lib_a-arc4random.$(OBJEXT) \
+	$(am__objects_1) $(am__objects_2)
+am__objects_4 = lib_a-arc4random.$(OBJEXT) \
 	lib_a-arc4random_uniform.$(OBJEXT) lib_a-cxa_atexit.$(OBJEXT) \
 	lib_a-cxa_finalize.$(OBJEXT) lib_a-drand48.$(OBJEXT) \
 	lib_a-ecvtbuf.$(OBJEXT) lib_a-efgcvt.$(OBJEXT) \
@@ -128,7 +133,7 @@ am__objects_3 = lib_a-arc4random.$(OBJEXT) \
 	lib_a-wcstoll_r.$(OBJEXT) lib_a-wcstoull.$(OBJEXT) \
 	lib_a-wcstoull_r.$(OBJEXT) lib_a-atoll.$(OBJEXT) \
 	lib_a-llabs.$(OBJEXT) lib_a-lldiv.$(OBJEXT)
-am__objects_4 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \
+am__objects_5 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \
 	lib_a-getopt.$(OBJEXT) lib_a-getsubopt.$(OBJEXT) \
 	lib_a-l64a.$(OBJEXT) lib_a-malign.$(OBJEXT) \
 	lib_a-mbrlen.$(OBJEXT) lib_a-mbrtowc.$(OBJEXT) \
@@ -137,22 +142,23 @@ am__objects_4 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \
 	lib_a-valloc.$(OBJEXT) lib_a-wcrtomb.$(OBJEXT) \
 	lib_a-wcsnrtombs.$(OBJEXT) lib_a-wcsrtombs.$(OBJEXT) \
 	lib_a-wctob.$(OBJEXT)
-am__objects_5 = lib_a-putenv.$(OBJEXT) lib_a-putenv_r.$(OBJEXT) \
+am__objects_6 = lib_a-putenv.$(OBJEXT) lib_a-putenv_r.$(OBJEXT) \
 	lib_a-setenv.$(OBJEXT) lib_a-setenv_r.$(OBJEXT)
-am__objects_6 = lib_a-rpmatch.$(OBJEXT) lib_a-system.$(OBJEXT)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_7 = $(am__objects_4) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_5) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_6)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_7 = $(am__objects_4) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_5)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_7 =  \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_4)
-@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_2) \
-@USE_LIBTOOL_FALSE@	$(am__objects_3) $(am__objects_7)
+am__objects_7 = lib_a-rpmatch.$(OBJEXT) lib_a-system.$(OBJEXT)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_8 = $(am__objects_5) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_6) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_7)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_8 = $(am__objects_5) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_6)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_8 =  \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_5)
+@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_3) \
+@USE_LIBTOOL_FALSE@	$(am__objects_4) $(am__objects_8)
 lib_a_OBJECTS = $(am_lib_a_OBJECTS)
 LTLIBRARIES = $(noinst_LTLIBRARIES)
-@HAVE_LONG_DOUBLE_TRUE@am__objects_8 = strtold.lo wcstold.lo
-am__objects_9 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \
+@HAVE_LONG_DOUBLE_TRUE@am__objects_9 = strtold.lo wcstold.lo
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@am__objects_10 = lock.lo
+am__objects_11 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \
 	__ten_mu.lo _Exit.lo abort.lo abs.lo aligned_alloc.lo \
 	assert.lo atexit.lo atof.lo atoff.lo atoi.lo atol.lo calloc.lo \
 	div.lo dtoa.lo dtoastub.lo environ.lo envlock.lo eprintf.lo \
@@ -163,28 +169,28 @@ am__objects_9 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \
 	rand_r.lo random.lo realloc.lo reallocf.lo sb_charsets.lo \
 	strtod.lo strtodg.lo strtol.lo strtorx.lo strtoul.lo utoa.lo \
 	wcstod.lo wcstol.lo wcstoul.lo wcstombs.lo wcstombs_r.lo \
-	wctomb.lo wctomb_r.lo $(am__objects_8)
-am__objects_10 = arc4random.lo arc4random_uniform.lo cxa_atexit.lo \
+	wctomb.lo wctomb_r.lo $(am__objects_9) $(am__objects_10)
+am__objects_12 = arc4random.lo arc4random_uniform.lo cxa_atexit.lo \
 	cxa_finalize.lo drand48.lo ecvtbuf.lo efgcvt.lo erand48.lo \
 	jrand48.lo lcong48.lo lrand48.lo mrand48.lo msize.lo mtrim.lo \
 	nrand48.lo rand48.lo seed48.lo srand48.lo strtoll.lo \
 	strtoll_r.lo strtoull.lo strtoull_r.lo wcstoll.lo wcstoll_r.lo \
 	wcstoull.lo wcstoull_r.lo atoll.lo llabs.lo lldiv.lo
-am__objects_11 = a64l.lo btowc.lo getopt.lo getsubopt.lo l64a.lo \
+am__objects_13 = a64l.lo btowc.lo getopt.lo getsubopt.lo l64a.lo \
 	malign.lo mbrlen.lo mbrtowc.lo mbsinit.lo mbsnrtowcs.lo \
 	mbsrtowcs.lo on_exit.lo valloc.lo wcrtomb.lo wcsnrtombs.lo \
 	wcsrtombs.lo wctob.lo
-am__objects_12 = putenv.lo putenv_r.lo setenv.lo setenv_r.lo
-am__objects_13 = rpmatch.lo system.lo
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_14 = $(am__objects_11) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_12) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_13)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_14 = $(am__objects_11) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_12)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_14 =  \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_11)
-@USE_LIBTOOL_TRUE@am_libstdlib_la_OBJECTS = $(am__objects_9) \
-@USE_LIBTOOL_TRUE@	$(am__objects_10) $(am__objects_14)
+am__objects_14 = putenv.lo putenv_r.lo setenv.lo setenv_r.lo
+am__objects_15 = rpmatch.lo system.lo
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_16 = $(am__objects_13) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_14) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_15)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_16 = $(am__objects_13) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_14)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_16 =  \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_13)
+@USE_LIBTOOL_TRUE@am_libstdlib_la_OBJECTS = $(am__objects_11) \
+@USE_LIBTOOL_TRUE@	$(am__objects_12) $(am__objects_16)
 libstdlib_la_OBJECTS = $(am_libstdlib_la_OBJECTS)
 libstdlib_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -367,7 +373,7 @@ GENERAL_SOURCES = __adjust.c __atexit.c __call_atexit.c __exp10.c \
 	quick_exit.c rand.c rand_r.c random.c realloc.c reallocf.c \
 	sb_charsets.c strtod.c strtodg.c strtol.c strtorx.c strtoul.c \
 	utoa.c wcstod.c wcstol.c wcstoul.c wcstombs.c wcstombs_r.c \
-	wctomb.c wctomb_r.c $(am__append_1)
+	wctomb.c wctomb_r.c $(am__append_1) $(am__append_2)
 @NEWLIB_NANO_MALLOC_FALSE@MALIGNR = malignr
 @NEWLIB_NANO_MALLOC_TRUE@MALIGNR = nano-malignr
 @NEWLIB_NANO_MALLOC_FALSE@MALLOPTR = malloptr
@@ -1002,6 +1008,12 @@ lib_a-wcstold.o: wcstold.c
 lib_a-wcstold.obj: wcstold.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcstold.obj `if test -f 'wcstold.c'; then $(CYGPATH_W) 'wcstold.c'; else $(CYGPATH_W) '$(srcdir)/wcstold.c'; fi`
 
+lib_a-lock.o: lock.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lock.o `test -f 'lock.c' || echo '$(srcdir)/'`lock.c
+
+lib_a-lock.obj: lock.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lock.obj `if test -f 'lock.c'; then $(CYGPATH_W) 'lock.c'; else $(CYGPATH_W) '$(srcdir)/lock.c'; fi`
+
 lib_a-arc4random.o: arc4random.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-arc4random.o `test -f 'arc4random.c' || echo '$(srcdir)/'`arc4random.c
 
diff --git a/newlib/libc/stdlib/lock.c b/newlib/libc/stdlib/lock.c
new file mode 100644
index 0000000000000000000000000000000000000000..c0b8a173a3bae16cd91d231dff7de2b4bb8cd9e3
--- /dev/null
+++ b/newlib/libc/stdlib/lock.c
@@ -0,0 +1,108 @@
+/*
+FUNCTION
+<<__retarget_lock_init>>, <<__retarget_lock_init_recursive>>, <<__retarget_lock_close>>, <<__retarget_lock_close_recursive>>, <<__retarget_lock_acquire>>, <<__retarget_lock_acquire_recursive>>, <<__retarget_lock_try_acquire>>, <<__retarget_lock_try_acquire_recursive>>, <<__retarget_lock_release>>, <<__retarget_lock_release_recursive>>---locking routines
+
+INDEX
+	__retarget_lock_init
+INDEX
+	__retarget_lock_init_recursive
+INDEX
+	__retarget_lock_close
+INDEX
+	__retarget_lock_close_recursive
+INDEX
+	__retarget_lock_acquire
+INDEX
+	__retarget_lock_acquire_recursive
+INDEX
+	__retarget_lock_try_acquire
+INDEX
+	__retarget_lock_try_acquire_recursive
+INDEX
+	__retarget_lock_release
+INDEX
+	__retarget_lock_release_recursive
+
+ANSI_SYNOPSIS
+	#include <lock.h>
+	void __retarget_lock_init (_LOCK_T * <[lock_ptr]>);
+	void __retarget_lock_init_recursive (_LOCK_T * <[lock_ptr]>);
+	void __retarget_lock_close (_LOCK_T <[lock]>);
+	void __retarget_lock_close_recursive (_LOCK_T <[lock]>);
+	void __retarget_lock_acquire (_LOCK_T <[lock]>);
+	void __retarget_lock_acquire_recursive (_LOCK_T <[lock]>);
+	int __retarget_lock_try_acquire (_LOCK_T <[lock]>);
+	int __retarget_lock_try_acquire_recursive (_LOCK_T <[lock]>);
+	void __retarget_lock_release (_LOCK_T <[lock]>);
+	void __retarget_lock_release_recursive (_LOCK_T <[lock]>);
+
+DESCRIPTION
+These empty functions are used for locking to allow applications to retarget
+them.  They are used in place of the default dummy lock macros when newlib
+is configured with --enable-newlib-retargetable-locking.
+*/
+
+/* dummy lock routines for single-threaded apps */
+
+#include <sys/lock.h>
+
+struct _lock {
+  char unused;
+};
+
+struct _lock _ATTRIBUTE((__weak__)) _lock___sinit_lock;
+struct _lock _ATTRIBUTE((__weak__)) _lock___sfp_lock;
+struct _lock _ATTRIBUTE((__weak__)) _lock___atexit_lock;
+struct _lock _ATTRIBUTE((__weak__)) _lock___malloc_lock_object;
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_init (_LOCK_T *lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_init_recursive(_LOCK_T *lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_close(_LOCK_T lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_close_recursive(_LOCK_T lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_acquire (_LOCK_T lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_acquire_recursive (_LOCK_T lock)
+{
+}
+
+int _ATTRIBUTE((__weak__))
+__retarget_lock_try_acquire(_LOCK_T lock)
+{
+  return 1;
+}
+
+int _ATTRIBUTE((__weak__))
+__retarget_lock_try_acquire_recursive(_LOCK_T lock)
+{
+  return 1;
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_release (_LOCK_T lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__retarget_lock_release_recursive (_LOCK_T lock)
+{
+}
diff --git a/newlib/newlib.hin b/newlib/newlib.hin
index d03dfac0eea6a8917a92b8f0f3584c2cd42b9388..397bc9b96eafddace3a75be509157040654b6fde 100644
--- a/newlib/newlib.hin
+++ b/newlib/newlib.hin
@@ -82,6 +82,9 @@
 /* Define if small footprint nano-formatted-IO implementation used.  */
 #undef _NANO_FORMATTED_IO
 
+/* Define if using retargetable functions for default lock routines.  */
+#undef _RETARGETABLE_LOCKING
+
 /*
  * Iconv encodings enabled ("to" direction)
  */

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2017-01-12 10:52                     ` Thomas Preudhomme
@ 2017-01-12 16:20                       ` Freddie Chopin
  2017-01-12 16:55                         ` Thomas Preudhomme
  0 siblings, 1 reply; 51+ messages in thread
From: Freddie Chopin @ 2017-01-12 16:20 UTC (permalink / raw)
  To: newlib

On Thu, 2017-01-12 at 10:51 +0000, Thomas Preudhomme wrote:
> My bad. I've rebased it on latest master branch. Please find the
> patch attached.

Thanks! Now it builds fine (;

In my very limited testing it seems to work very nicely and the idea of
using "struct _lock;" is very clever, as it allows me to do the
retargeting in a very clean way:

--- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 ---

struct _lock : public distortos::Mutex
{
	using Mutex::Mutex;
};

_lock _lock___sinit_lock {distortos::Mutex::Type::recursive, distortos::Mutex::Protocol::priorityInheritance};
_lock _lock___sfp_lock {distortos::Mutex::Type::recursive, distortos::Mutex::Protocol::priorityInheritance};
_lock _lock___atexit_lock {distortos::Mutex::Type::recursive, distortos::Mutex::Protocol::priorityInheritance};
_lock _lock___malloc_lock_object {distortos::Mutex::Type::recursive, distortos::Mutex::Protocol::priorityInheritance};

void __retarget_lock_init (_LOCK_T *lock)
{
	*lock = new _lock {distortos::Mutex::Type::normal, distortos::Mutex::Protocol::priorityInheritance};
}

void __retarget_lock_close(_LOCK_T lock)
{
	delete lock;
}

void __retarget_lock_acquire (_LOCK_T lock)
{
	lock->lock();
}

void __retarget_lock_release (_LOCK_T lock)
{
	lock->unlock();
}

...

--- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 ---

But I still see a big issue with the weak objects that you provided in
lock.c... The problem here is that now the user can redefine just 3 of
them, so the last one will be taken from the weak definition that you
provided. There will be no error/warning during compilation or linking.
This will of course fail terribly during run-time due to mismatched
types... While this may seem a bit unlikely at the first glance, the
possible scenario that would lead to that is:
1. today newlib adds this very cool feature and adds weak objects for
all used locks.
2. after some time RTOS developers start to support it and also provide
their own versions of the locks needed by newlib.
3. after some more time newlib adds another lock somewhere, along with
the object.
At this moment all users of code created during step 2 linked with
newlib version from step 3 will result in undefined behaviour whenever
the new lock is used...

You also missed some of the locks that are used by newlib:
newlib/libc/posix/telldir.c:__LOCK_INIT(static, dd_hash_lock);
newlib/libc/time/tzlock.c:__LOCK_INIT(static, __tz_lock_object);
newlib/libc/stdlib/quick_exit.c:__LOCK_INIT(static, atexit_mutex);
newlib/libc/stdlib/envlock.c:__LOCK_INIT_RECURSIVE(static, __env_lock_object);

Maybe it would be somehow possible to bind all of the objects (and
maybe even functions) together, so that when user provides just one
definition, all other weak definitions will be immediately disabled?
This way the user would either have to provide all or none, without an
option to only provide some of the objects/functions. This is my only
concern - I have nothing against providing weak definitions, but the
possibility of overriding only some of the objects is a bit disturbing.

Regards,
FCh

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2017-01-12 16:20                       ` Freddie Chopin
@ 2017-01-12 16:55                         ` Thomas Preudhomme
  2017-01-13 11:25                           ` Thomas Preudhomme
  0 siblings, 1 reply; 51+ messages in thread
From: Thomas Preudhomme @ 2017-01-12 16:55 UTC (permalink / raw)
  To: newlib

Hi Freddie,

On 12/01/17 16:20, Freddie Chopin wrote:
> On Thu, 2017-01-12 at 10:51 +0000, Thomas Preudhomme wrote:
>> My bad. I've rebased it on latest master branch. Please find the
>> patch attached.
>
> Thanks! Now it builds fine (;
>
> In my very limited testing it seems to work very nicely and the idea of
> using "struct _lock;" is very clever, as it allows me to do the
> retargeting in a very clean way:
>
> --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 ---
>
> struct _lock : public distortos::Mutex
> {
> 	using Mutex::Mutex;
> };
>
> _lock _lock___sinit_lock {distortos::Mutex::Type::recursive, distortos::Mutex::Protocol::priorityInheritance};
> _lock _lock___sfp_lock {distortos::Mutex::Type::recursive, distortos::Mutex::Protocol::priorityInheritance};
> _lock _lock___atexit_lock {distortos::Mutex::Type::recursive, distortos::Mutex::Protocol::priorityInheritance};
> _lock _lock___malloc_lock_object {distortos::Mutex::Type::recursive, distortos::Mutex::Protocol::priorityInheritance};
>
> void __retarget_lock_init (_LOCK_T *lock)
> {
> 	*lock = new _lock {distortos::Mutex::Type::normal, distortos::Mutex::Protocol::priorityInheritance};
> }
>
> void __retarget_lock_close(_LOCK_T lock)
> {
> 	delete lock;
> }
>
> void __retarget_lock_acquire (_LOCK_T lock)
> {
> 	lock->lock();
> }
>
> void __retarget_lock_release (_LOCK_T lock)
> {
> 	lock->unlock();
> }
>
> ...
>
> --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 ---
>
> But I still see a big issue with the weak objects that you provided in
> lock.c... The problem here is that now the user can redefine just 3 of
> them, so the last one will be taken from the weak definition that you
> provided. There will be no error/warning during compilation or linking.
> This will of course fail terribly during run-time due to mismatched
> types... While this may seem a bit unlikely at the first glance, the
> possible scenario that would lead to that is:
> 1. today newlib adds this very cool feature and adds weak objects for
> all used locks.
> 2. after some time RTOS developers start to support it and also provide
> their own versions of the locks needed by newlib.
> 3. after some more time newlib adds another lock somewhere, along with
> the object.
> At this moment all users of code created during step 2 linked with
> newlib version from step 3 will result in undefined behaviour whenever
> the new lock is used...
>
> You also missed some of the locks that are used by newlib:
> newlib/libc/posix/telldir.c:__LOCK_INIT(static, dd_hash_lock);
> newlib/libc/time/tzlock.c:__LOCK_INIT(static, __tz_lock_object);
> newlib/libc/stdlib/quick_exit.c:__LOCK_INIT(static, atexit_mutex);
> newlib/libc/stdlib/envlock.c:__LOCK_INIT_RECURSIVE(static, __env_lock_object);
>
> Maybe it would be somehow possible to bind all of the objects (and
> maybe even functions) together, so that when user provides just one
> definition, all other weak definitions will be immediately disabled?
> This way the user would either have to provide all or none, without an
> option to only provide some of the objects/functions. This is my only
> concern - I have nothing against providing weak definitions, but the
> possibility of overriding only some of the objects is a bit disturbing.

That's a very valid concern indeed. Thanks a lot for this feedback. I'll think 
about it and see if I can come up with a solution.

Best regards,

Thomas

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2017-01-12 16:55                         ` Thomas Preudhomme
@ 2017-01-13 11:25                           ` Thomas Preudhomme
  2017-01-13 13:24                             ` Thomas Preudhomme
  0 siblings, 1 reply; 51+ messages in thread
From: Thomas Preudhomme @ 2017-01-13 11:25 UTC (permalink / raw)
  To: newlib



On 12/01/17 16:55, Thomas Preudhomme wrote:
> Hi Freddie,
>
> On 12/01/17 16:20, Freddie Chopin wrote:
>> On Thu, 2017-01-12 at 10:51 +0000, Thomas Preudhomme wrote:
>>> My bad. I've rebased it on latest master branch. Please find the
>>> patch attached.
>>
>> Thanks! Now it builds fine (;
>>
>> In my very limited testing it seems to work very nicely and the idea of
>> using "struct _lock;" is very clever, as it allows me to do the
>> retargeting in a very clean way:
>>
>> --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 ---
>>
>> struct _lock : public distortos::Mutex
>> {
>>     using Mutex::Mutex;
>> };
>>
>> _lock _lock___sinit_lock {distortos::Mutex::Type::recursive,
>> distortos::Mutex::Protocol::priorityInheritance};
>> _lock _lock___sfp_lock {distortos::Mutex::Type::recursive,
>> distortos::Mutex::Protocol::priorityInheritance};
>> _lock _lock___atexit_lock {distortos::Mutex::Type::recursive,
>> distortos::Mutex::Protocol::priorityInheritance};
>> _lock _lock___malloc_lock_object {distortos::Mutex::Type::recursive,
>> distortos::Mutex::Protocol::priorityInheritance};
>>
>> void __retarget_lock_init (_LOCK_T *lock)
>> {
>>     *lock = new _lock {distortos::Mutex::Type::normal,
>> distortos::Mutex::Protocol::priorityInheritance};
>> }
>>
>> void __retarget_lock_close(_LOCK_T lock)
>> {
>>     delete lock;
>> }
>>
>> void __retarget_lock_acquire (_LOCK_T lock)
>> {
>>     lock->lock();
>> }
>>
>> void __retarget_lock_release (_LOCK_T lock)
>> {
>>     lock->unlock();
>> }
>>
>> ...
>>
>> --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 ---
>>
>> But I still see a big issue with the weak objects that you provided in
>> lock.c... The problem here is that now the user can redefine just 3 of
>> them, so the last one will be taken from the weak definition that you
>> provided. There will be no error/warning during compilation or linking.
>> This will of course fail terribly during run-time due to mismatched
>> types... While this may seem a bit unlikely at the first glance, the
>> possible scenario that would lead to that is:
>> 1. today newlib adds this very cool feature and adds weak objects for
>> all used locks.
>> 2. after some time RTOS developers start to support it and also provide
>> their own versions of the locks needed by newlib.
>> 3. after some more time newlib adds another lock somewhere, along with
>> the object.
>> At this moment all users of code created during step 2 linked with
>> newlib version from step 3 will result in undefined behaviour whenever
>> the new lock is used...
>>
>> You also missed some of the locks that are used by newlib:
>> newlib/libc/posix/telldir.c:__LOCK_INIT(static, dd_hash_lock);
>> newlib/libc/time/tzlock.c:__LOCK_INIT(static, __tz_lock_object);
>> newlib/libc/stdlib/quick_exit.c:__LOCK_INIT(static, atexit_mutex);
>> newlib/libc/stdlib/envlock.c:__LOCK_INIT_RECURSIVE(static, __env_lock_object);
>>
>> Maybe it would be somehow possible to bind all of the objects (and
>> maybe even functions) together, so that when user provides just one
>> definition, all other weak definitions will be immediately disabled?
>> This way the user would either have to provide all or none, without an
>> option to only provide some of the objects/functions. This is my only
>> concern - I have nothing against providing weak definitions, but the
>> possibility of overriding only some of the objects is a bit disturbing.
>
> That's a very valid concern indeed. Thanks a lot for this feedback. I'll think
> about it and see if I can come up with a solution.

Actually the dummy function and lock do not have to be weakly defined to be able 
to be retargeted. Members of a static library only gets pulled if they solve an 
undefined reference. Otherwise, they are ignored.

All we need is for the retargeted functions and locks provided by a platform to 
be linked before newlib. Then if all functions and locks are retargeted the 
lock.o member with all dummy definitions in newlib static library is ignored, 
otherwise it would be pulled in during the link and ld would give a linking 
error because some of the lock and function would be defined twice.

How does that sounds?

Best regards,

Thomas

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2017-01-13 11:25                           ` Thomas Preudhomme
@ 2017-01-13 13:24                             ` Thomas Preudhomme
  2017-01-13 18:05                               ` Freddie Chopin
  0 siblings, 1 reply; 51+ messages in thread
From: Thomas Preudhomme @ 2017-01-13 13:24 UTC (permalink / raw)
  To: newlib

[-- Attachment #1: Type: text/plain, Size: 4514 bytes --]

And here's the patch. Tested with full and partial retargeting as well as no 
retargeting. Newlib testsuite shows no regression either.

Best regards,

Thomas

On 13/01/17 11:25, Thomas Preudhomme wrote:
>
>
> On 12/01/17 16:55, Thomas Preudhomme wrote:
>> Hi Freddie,
>>
>> On 12/01/17 16:20, Freddie Chopin wrote:
>>> On Thu, 2017-01-12 at 10:51 +0000, Thomas Preudhomme wrote:
>>>> My bad. I've rebased it on latest master branch. Please find the
>>>> patch attached.
>>>
>>> Thanks! Now it builds fine (;
>>>
>>> In my very limited testing it seems to work very nicely and the idea of
>>> using "struct _lock;" is very clever, as it allows me to do the
>>> retargeting in a very clean way:
>>>
>>> --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 ---
>>>
>>> struct _lock : public distortos::Mutex
>>> {
>>>     using Mutex::Mutex;
>>> };
>>>
>>> _lock _lock___sinit_lock {distortos::Mutex::Type::recursive,
>>> distortos::Mutex::Protocol::priorityInheritance};
>>> _lock _lock___sfp_lock {distortos::Mutex::Type::recursive,
>>> distortos::Mutex::Protocol::priorityInheritance};
>>> _lock _lock___atexit_lock {distortos::Mutex::Type::recursive,
>>> distortos::Mutex::Protocol::priorityInheritance};
>>> _lock _lock___malloc_lock_object {distortos::Mutex::Type::recursive,
>>> distortos::Mutex::Protocol::priorityInheritance};
>>>
>>> void __retarget_lock_init (_LOCK_T *lock)
>>> {
>>>     *lock = new _lock {distortos::Mutex::Type::normal,
>>> distortos::Mutex::Protocol::priorityInheritance};
>>> }
>>>
>>> void __retarget_lock_close(_LOCK_T lock)
>>> {
>>>     delete lock;
>>> }
>>>
>>> void __retarget_lock_acquire (_LOCK_T lock)
>>> {
>>>     lock->lock();
>>> }
>>>
>>> void __retarget_lock_release (_LOCK_T lock)
>>> {
>>>     lock->unlock();
>>> }
>>>
>>> ...
>>>
>>> --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 --- >8 ---
>>>
>>> But I still see a big issue with the weak objects that you provided in
>>> lock.c... The problem here is that now the user can redefine just 3 of
>>> them, so the last one will be taken from the weak definition that you
>>> provided. There will be no error/warning during compilation or linking.
>>> This will of course fail terribly during run-time due to mismatched
>>> types... While this may seem a bit unlikely at the first glance, the
>>> possible scenario that would lead to that is:
>>> 1. today newlib adds this very cool feature and adds weak objects for
>>> all used locks.
>>> 2. after some time RTOS developers start to support it and also provide
>>> their own versions of the locks needed by newlib.
>>> 3. after some more time newlib adds another lock somewhere, along with
>>> the object.
>>> At this moment all users of code created during step 2 linked with
>>> newlib version from step 3 will result in undefined behaviour whenever
>>> the new lock is used...
>>>
>>> You also missed some of the locks that are used by newlib:
>>> newlib/libc/posix/telldir.c:__LOCK_INIT(static, dd_hash_lock);
>>> newlib/libc/time/tzlock.c:__LOCK_INIT(static, __tz_lock_object);
>>> newlib/libc/stdlib/quick_exit.c:__LOCK_INIT(static, atexit_mutex);
>>> newlib/libc/stdlib/envlock.c:__LOCK_INIT_RECURSIVE(static, __env_lock_object);
>>>
>>> Maybe it would be somehow possible to bind all of the objects (and
>>> maybe even functions) together, so that when user provides just one
>>> definition, all other weak definitions will be immediately disabled?
>>> This way the user would either have to provide all or none, without an
>>> option to only provide some of the objects/functions. This is my only
>>> concern - I have nothing against providing weak definitions, but the
>>> possibility of overriding only some of the objects is a bit disturbing.
>>
>> That's a very valid concern indeed. Thanks a lot for this feedback. I'll think
>> about it and see if I can come up with a solution.
>
> Actually the dummy function and lock do not have to be weakly defined to be able
> to be retargeted. Members of a static library only gets pulled if they solve an
> undefined reference. Otherwise, they are ignored.
>
> All we need is for the retargeted functions and locks provided by a platform to
> be linked before newlib. Then if all functions and locks are retargeted the
> lock.o member with all dummy definitions in newlib static library is ignored,
> otherwise it would be pulled in during the link and ld would give a linking
> error because some of the lock and function would be defined twice.
>
> How does that sounds?
>
> Best regards,
>
> Thomas

[-- Attachment #2: newlib_retargetable_locking_routine.patch --]
[-- Type: text/x-patch, Size: 22962 bytes --]

diff --git a/newlib/configure b/newlib/configure
index 2ac07fe06bfc795d94ba36d0061e4f8135146125..de28c25b3c4aaeed14b6d0ee8354fdd5c5c3115a 100755
--- a/newlib/configure
+++ b/newlib/configure
@@ -802,6 +802,7 @@ enable_newlib_nano_malloc
 enable_newlib_unbuf_stream_opt
 enable_lite_exit
 enable_newlib_nano_formatted_io
+enable_newlib_retargetable_locking
 enable_multilib
 enable_target_optspace
 enable_malloc_debugging
@@ -1473,6 +1474,7 @@ Optional Features:
   --disable-newlib-unbuf-stream-opt    disable unbuffered stream optimization in streamio
   --enable-lite-exit	enable light weight exit
   --enable-newlib-nano-formatted-io    Use nano version formatted IO
+  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time
   --enable-multilib         build many library versions (default)
   --enable-target-optspace  optimize for space
   --enable-malloc-debugging indicate malloc debugging requested
@@ -2474,6 +2476,18 @@ else
 fi
 
 
+# Check whether --enable-newlib-retargetable-locking was given.
+if test "${enable_newlib_retargetable_locking+set}" = set; then :
+  enableval=$enable_newlib_retargetable_locking; case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_locking=no ;;
+   *) as_fn_error $? "bad value ${enableval} for newlib-retargetable-locking" "$LINENO" 5 ;;
+ esac
+else
+  newlib_retargetable_locking=no
+fi
+
+
 
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
@@ -11780,7 +11794,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11783 "configure"
+#line 11797 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11886,7 +11900,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11889 "configure"
+#line 11903 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12455,6 +12469,13 @@ _ACEOF
 
 fi
 
+if test "${newlib_retargetable_locking}" = "yes"; then
+cat >>confdefs.h <<_ACEOF
+#define _RETARGETABLE_LOCKING 1
+_ACEOF
+
+fi
+
 
 if test "x${iconv_encodings}" != "x" \
    || test "x${iconv_to_encodings}" != "x" \
diff --git a/newlib/configure.in b/newlib/configure.in
index bfaf038c7f495d32d05ae8caff0172f464895ffe..354c07ca580edf75da59fb858ca2c434e0b1a4e9 100644
--- a/newlib/configure.in
+++ b/newlib/configure.in
@@ -218,6 +218,17 @@ AC_ARG_ENABLE(newlib_nano_formatted_io,
    *) AC_MSG_ERROR(bad value ${enableval} for newlib-nano-formatted-io) ;;
  esac],[newlib_nano_formatted_io=no])
 
+dnl Support --enable-retargetable-locking
+dnl This option is also read in libc/configure.in.  It is repeated
+dnl here so that it shows up in the help text.
+AC_ARG_ENABLE(newlib-retargetable-locking,
+[  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time],
+[case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_locking=no ;;
+   *) AC_MSG_ERROR(bad value ${enableval} for newlib-retargetable-locking) ;;
+ esac],[newlib_retargetable_locking=no])
+
 NEWLIB_CONFIGURE(.)
 
 dnl We have to enable libtool after NEWLIB_CONFIGURE because if we try and
@@ -458,6 +469,10 @@ if test "${newlib_nano_formatted_io}" = "yes"; then
 AC_DEFINE_UNQUOTED(_NANO_FORMATTED_IO)
 fi
 
+if test "${newlib_retargetable_locking}" = "yes"; then
+AC_DEFINE_UNQUOTED(_RETARGETABLE_LOCKING)
+fi
+
 dnl
 dnl Parse --enable-newlib-iconv-encodings option argument
 dnl
diff --git a/newlib/libc/configure b/newlib/libc/configure
index 4dc4d1bf703f388ecd3b4e0d8bef6786f7995021..dabe44fd98d74a2e029a22a217953dd52575736f 100755
--- a/newlib/libc/configure
+++ b/newlib/libc/configure
@@ -751,6 +751,8 @@ build
 newlib_basedir
 MAY_SUPPLY_SYSCALLS_FALSE
 MAY_SUPPLY_SYSCALLS_TRUE
+NEWLIB_RETARGETABLE_LOCKING_FALSE
+NEWLIB_RETARGETABLE_LOCKING_TRUE
 NEWLIB_NANO_FORMATTED_IO_FALSE
 NEWLIB_NANO_FORMATTED_IO_TRUE
 target_alias
@@ -797,6 +799,7 @@ enable_option_checking
 enable_newlib_io_pos_args
 enable_newlib_nano_malloc
 enable_newlib_nano_formatted_io
+enable_newlib_retargetable_locking
 enable_multilib
 enable_target_optspace
 enable_malloc_debugging
@@ -1448,6 +1451,7 @@ Optional Features:
   --enable-newlib-io-pos-args enable printf-family positional arg support
   --enable-newlib-nano-malloc    Use small-footprint nano-malloc implementation
   --enable-newlib-nano-formatted-io    Use small-footprint nano-formatted-IO implementation
+  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time
   --enable-multilib         build many library versions (default)
   --enable-target-optspace  optimize for space
   --enable-malloc-debugging indicate malloc debugging requested
@@ -2252,6 +2256,26 @@ else
 fi
 
 
+# Check whether --enable-newlib-retargetable-locking was given.
+if test "${enable_newlib_retargetable_locking+set}" = set; then :
+  enableval=$enable_newlib_retargetable_locking; case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_lock=no ;;
+   *) as_fn_error $? "bad value ${enableval} for newlib-retargetable-locking" "$LINENO" 5 ;;
+ esac
+else
+  newlib_retargetable_locking=no
+fi
+
+ if test x$newlib_retargetable_locking = xyes; then
+  NEWLIB_RETARGETABLE_LOCKING_TRUE=
+  NEWLIB_RETARGETABLE_LOCKING_FALSE='#'
+else
+  NEWLIB_RETARGETABLE_LOCKING_TRUE='#'
+  NEWLIB_RETARGETABLE_LOCKING_FALSE=
+fi
+
+
 
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
@@ -11525,7 +11549,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11528 "configure"
+#line 11552 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11631,7 +11655,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11634 "configure"
+#line 11658 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12248,6 +12272,10 @@ if test -z "${NEWLIB_NANO_FORMATTED_IO_TRUE}" && test -z "${NEWLIB_NANO_FORMATTE
   as_fn_error $? "conditional \"NEWLIB_NANO_FORMATTED_IO\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${NEWLIB_RETARGETABLE_LOCKING_TRUE}" && test -z "${NEWLIB_RETARGETABLE_LOCKING_FALSE}"; then
+  as_fn_error $? "conditional \"NEWLIB_RETARGETABLE_LOCKING\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${MAY_SUPPLY_SYSCALLS_TRUE}" && test -z "${MAY_SUPPLY_SYSCALLS_FALSE}"; then
   as_fn_error $? "conditional \"MAY_SUPPLY_SYSCALLS\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
diff --git a/newlib/libc/configure.in b/newlib/libc/configure.in
index 0a7bb8815be44fb1e92f753fa2c8df2a31b95f94..ac25a3933c4a4794f3cfe291e0275d0ed001b96a 100644
--- a/newlib/libc/configure.in
+++ b/newlib/libc/configure.in
@@ -36,6 +36,16 @@ AC_ARG_ENABLE(newlib_nano_formatted_io,
  esac],[newlib_nano_formatted_io=no])
 AM_CONDITIONAL(NEWLIB_NANO_FORMATTED_IO, test x$newlib_nano_formatted_io = xyes)
 
+dnl Support --enable-retargetable-locking used by libc/sys
+AC_ARG_ENABLE(newlib-retargetable-locking,
+[  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time],
+[case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_lock=no ;;
+   *) AC_MSG_ERROR(bad value ${enableval} for newlib-retargetable-locking) ;;
+ esac],[newlib_retargetable_locking=no])
+AM_CONDITIONAL(NEWLIB_RETARGETABLE_LOCKING, test x$newlib_retargetable_locking = xyes)
+
 NEWLIB_CONFIGURE(..)
 
 AM_CONDITIONAL(NEWLIB_NANO_MALLOC, test x$newlib_nano_malloc = xyes)
diff --git a/newlib/libc/include/sys/lock.h b/newlib/libc/include/sys/lock.h
index 9075e35c9179968031010432515e3a845ff6ca8d..9a8e2528c79a89d5807da8c4bb0e65151870bf42 100644
--- a/newlib/libc/include/sys/lock.h
+++ b/newlib/libc/include/sys/lock.h
@@ -3,10 +3,13 @@
 
 /* dummy lock routines for single-threaded aps */
 
+#include <newlib.h>
+#include <_ansi.h>
+
+#ifndef _RETARGETABLE_LOCKING
+
 typedef int _LOCK_T;
 typedef int _LOCK_RECURSIVE_T;
- 
-#include <_ansi.h>
 
 #define __LOCK_INIT(class,lock) static int lock = 0;
 #define __LOCK_INIT_RECURSIVE(class,lock) static int lock = 0;
@@ -21,4 +24,46 @@ typedef int _LOCK_RECURSIVE_T;
 #define __lock_release(lock) (_CAST_VOID 0)
 #define __lock_release_recursive(lock) (_CAST_VOID 0)
 
+#else
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _lock;
+typedef struct _lock * _LOCK_T;
+#define _LOCK_RECURSIVE_T _LOCK_T
+
+#define __LOCK_INIT(class,lock) extern struct _lock _lock_ ## lock; \
+	class _LOCK_T lock = &_lock_ ## lock
+#define __LOCK_INIT_RECURSIVE(class,lock) __LOCK_INIT(class,lock)
+
+extern void __retarget_lock_init(_LOCK_T *lock);
+#define __lock_init(lock) __retarget_lock_init(&lock)
+extern void __retarget_lock_init_recursive(_LOCK_T *lock);
+#define __lock_init_recursive(lock) __retarget_lock_init_recursive(&lock)
+extern void __retarget_lock_close(_LOCK_T lock);
+#define __lock_close(lock) __retarget_lock_close(lock)
+extern void __retarget_lock_close_recursive(_LOCK_T lock);
+#define __lock_close_recursive(lock) __retarget_lock_close_recursive(lock)
+extern void __retarget_lock_acquire(_LOCK_T lock);
+#define __lock_acquire(lock) __retarget_lock_acquire(lock)
+extern void __retarget_lock_acquire_recursive(_LOCK_T lock);
+#define __lock_acquire_recursive(lock) __retarget_lock_acquire_recursive(lock)
+extern int __retarget_lock_try_acquire(_LOCK_T lock);
+#define __lock_try_acquire(lock) __retarget_lock_try_acquire(lock)
+extern int __retarget_lock_try_acquire_recursive(_LOCK_T lock);
+#define __lock_try_acquire_recursive(lock) \
+  __retarget_lock_try_acquire_recursive(lock)
+extern void __retarget_lock_release(_LOCK_T lock);
+#define __lock_release(lock) __retarget_lock_release(lock)
+extern void __retarget_lock_release_recursive(_LOCK_T lock);
+#define __lock_release_recursive(lock) __retarget_lock_release_recursive(lock)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RETARGETABLE_LOCKING */
+
 #endif /* __SYS_LOCK_H__ */
diff --git a/newlib/libc/stdlib/Makefile.am b/newlib/libc/stdlib/Makefile.am
index 2d45d1029ace8087b57657cbc11feabf76f4206e..76ed8480c28ebfb68e2f48432c0359b11f1522a8 100644
--- a/newlib/libc/stdlib/Makefile.am
+++ b/newlib/libc/stdlib/Makefile.am
@@ -74,6 +74,11 @@ GENERAL_SOURCES += \
 	wcstold.c
 endif # HAVE_LONG_DOUBLE
 
+if NEWLIB_RETARGETABLE_LOCKING
+GENERAL_SOURCES += \
+	lock.c
+endif
+
 if NEWLIB_NANO_MALLOC
 MALIGNR=nano-malignr
 MALLOPTR=nano-malloptr
diff --git a/newlib/libc/stdlib/Makefile.in b/newlib/libc/stdlib/Makefile.in
index 466ab6d1e02ea919f6c8ceed792024955bef1a66..3295e981c87bac3b21a6b72dda148f892fe018d6 100644
--- a/newlib/libc/stdlib/Makefile.in
+++ b/newlib/libc/stdlib/Makefile.in
@@ -57,6 +57,9 @@ host_triplet = @host@
 @HAVE_LONG_DOUBLE_TRUE@	strtold.c \
 @HAVE_LONG_DOUBLE_TRUE@	wcstold.c
 
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@am__append_2 = \
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@	lock.c
+
 DIST_COMMON = $(srcdir)/../../Makefile.shared $(srcdir)/Makefile.in \
 	$(srcdir)/Makefile.am
 subdir = stdlib
@@ -81,7 +84,9 @@ lib_a_AR = $(AR) $(ARFLAGS)
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(ELIX_2_OBJS)
 @HAVE_LONG_DOUBLE_TRUE@am__objects_1 = lib_a-strtold.$(OBJEXT) \
 @HAVE_LONG_DOUBLE_TRUE@	lib_a-wcstold.$(OBJEXT)
-am__objects_2 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@am__objects_2 =  \
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@	lib_a-lock.$(OBJEXT)
+am__objects_3 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \
 	lib_a-__call_atexit.$(OBJEXT) lib_a-__exp10.$(OBJEXT) \
 	lib_a-__ten_mu.$(OBJEXT) lib_a-_Exit.$(OBJEXT) \
 	lib_a-abort.$(OBJEXT) lib_a-abs.$(OBJEXT) \
@@ -112,8 +117,8 @@ am__objects_2 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \
 	lib_a-wcstol.$(OBJEXT) lib_a-wcstoul.$(OBJEXT) \
 	lib_a-wcstombs.$(OBJEXT) lib_a-wcstombs_r.$(OBJEXT) \
 	lib_a-wctomb.$(OBJEXT) lib_a-wctomb_r.$(OBJEXT) \
-	$(am__objects_1)
-am__objects_3 = lib_a-arc4random.$(OBJEXT) \
+	$(am__objects_1) $(am__objects_2)
+am__objects_4 = lib_a-arc4random.$(OBJEXT) \
 	lib_a-arc4random_uniform.$(OBJEXT) lib_a-cxa_atexit.$(OBJEXT) \
 	lib_a-cxa_finalize.$(OBJEXT) lib_a-drand48.$(OBJEXT) \
 	lib_a-ecvtbuf.$(OBJEXT) lib_a-efgcvt.$(OBJEXT) \
@@ -128,7 +133,7 @@ am__objects_3 = lib_a-arc4random.$(OBJEXT) \
 	lib_a-wcstoll_r.$(OBJEXT) lib_a-wcstoull.$(OBJEXT) \
 	lib_a-wcstoull_r.$(OBJEXT) lib_a-atoll.$(OBJEXT) \
 	lib_a-llabs.$(OBJEXT) lib_a-lldiv.$(OBJEXT)
-am__objects_4 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \
+am__objects_5 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \
 	lib_a-getopt.$(OBJEXT) lib_a-getsubopt.$(OBJEXT) \
 	lib_a-l64a.$(OBJEXT) lib_a-malign.$(OBJEXT) \
 	lib_a-mbrlen.$(OBJEXT) lib_a-mbrtowc.$(OBJEXT) \
@@ -137,22 +142,23 @@ am__objects_4 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \
 	lib_a-valloc.$(OBJEXT) lib_a-wcrtomb.$(OBJEXT) \
 	lib_a-wcsnrtombs.$(OBJEXT) lib_a-wcsrtombs.$(OBJEXT) \
 	lib_a-wctob.$(OBJEXT)
-am__objects_5 = lib_a-putenv.$(OBJEXT) lib_a-putenv_r.$(OBJEXT) \
+am__objects_6 = lib_a-putenv.$(OBJEXT) lib_a-putenv_r.$(OBJEXT) \
 	lib_a-setenv.$(OBJEXT) lib_a-setenv_r.$(OBJEXT)
-am__objects_6 = lib_a-rpmatch.$(OBJEXT) lib_a-system.$(OBJEXT)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_7 = $(am__objects_4) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_5) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_6)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_7 = $(am__objects_4) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_5)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_7 =  \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_4)
-@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_2) \
-@USE_LIBTOOL_FALSE@	$(am__objects_3) $(am__objects_7)
+am__objects_7 = lib_a-rpmatch.$(OBJEXT) lib_a-system.$(OBJEXT)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_8 = $(am__objects_5) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_6) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_7)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_8 = $(am__objects_5) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_6)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_8 =  \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_5)
+@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_3) \
+@USE_LIBTOOL_FALSE@	$(am__objects_4) $(am__objects_8)
 lib_a_OBJECTS = $(am_lib_a_OBJECTS)
 LTLIBRARIES = $(noinst_LTLIBRARIES)
-@HAVE_LONG_DOUBLE_TRUE@am__objects_8 = strtold.lo wcstold.lo
-am__objects_9 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \
+@HAVE_LONG_DOUBLE_TRUE@am__objects_9 = strtold.lo wcstold.lo
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@am__objects_10 = lock.lo
+am__objects_11 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \
 	__ten_mu.lo _Exit.lo abort.lo abs.lo aligned_alloc.lo \
 	assert.lo atexit.lo atof.lo atoff.lo atoi.lo atol.lo calloc.lo \
 	div.lo dtoa.lo dtoastub.lo environ.lo envlock.lo eprintf.lo \
@@ -163,28 +169,28 @@ am__objects_9 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \
 	rand_r.lo random.lo realloc.lo reallocf.lo sb_charsets.lo \
 	strtod.lo strtodg.lo strtol.lo strtorx.lo strtoul.lo utoa.lo \
 	wcstod.lo wcstol.lo wcstoul.lo wcstombs.lo wcstombs_r.lo \
-	wctomb.lo wctomb_r.lo $(am__objects_8)
-am__objects_10 = arc4random.lo arc4random_uniform.lo cxa_atexit.lo \
+	wctomb.lo wctomb_r.lo $(am__objects_9) $(am__objects_10)
+am__objects_12 = arc4random.lo arc4random_uniform.lo cxa_atexit.lo \
 	cxa_finalize.lo drand48.lo ecvtbuf.lo efgcvt.lo erand48.lo \
 	jrand48.lo lcong48.lo lrand48.lo mrand48.lo msize.lo mtrim.lo \
 	nrand48.lo rand48.lo seed48.lo srand48.lo strtoll.lo \
 	strtoll_r.lo strtoull.lo strtoull_r.lo wcstoll.lo wcstoll_r.lo \
 	wcstoull.lo wcstoull_r.lo atoll.lo llabs.lo lldiv.lo
-am__objects_11 = a64l.lo btowc.lo getopt.lo getsubopt.lo l64a.lo \
+am__objects_13 = a64l.lo btowc.lo getopt.lo getsubopt.lo l64a.lo \
 	malign.lo mbrlen.lo mbrtowc.lo mbsinit.lo mbsnrtowcs.lo \
 	mbsrtowcs.lo on_exit.lo valloc.lo wcrtomb.lo wcsnrtombs.lo \
 	wcsrtombs.lo wctob.lo
-am__objects_12 = putenv.lo putenv_r.lo setenv.lo setenv_r.lo
-am__objects_13 = rpmatch.lo system.lo
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_14 = $(am__objects_11) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_12) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_13)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_14 = $(am__objects_11) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_12)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_14 =  \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_11)
-@USE_LIBTOOL_TRUE@am_libstdlib_la_OBJECTS = $(am__objects_9) \
-@USE_LIBTOOL_TRUE@	$(am__objects_10) $(am__objects_14)
+am__objects_14 = putenv.lo putenv_r.lo setenv.lo setenv_r.lo
+am__objects_15 = rpmatch.lo system.lo
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_16 = $(am__objects_13) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_14) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_15)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_16 = $(am__objects_13) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_14)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_16 =  \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_13)
+@USE_LIBTOOL_TRUE@am_libstdlib_la_OBJECTS = $(am__objects_11) \
+@USE_LIBTOOL_TRUE@	$(am__objects_12) $(am__objects_16)
 libstdlib_la_OBJECTS = $(am_libstdlib_la_OBJECTS)
 libstdlib_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -367,7 +373,7 @@ GENERAL_SOURCES = __adjust.c __atexit.c __call_atexit.c __exp10.c \
 	quick_exit.c rand.c rand_r.c random.c realloc.c reallocf.c \
 	sb_charsets.c strtod.c strtodg.c strtol.c strtorx.c strtoul.c \
 	utoa.c wcstod.c wcstol.c wcstoul.c wcstombs.c wcstombs_r.c \
-	wctomb.c wctomb_r.c $(am__append_1)
+	wctomb.c wctomb_r.c $(am__append_1) $(am__append_2)
 @NEWLIB_NANO_MALLOC_FALSE@MALIGNR = malignr
 @NEWLIB_NANO_MALLOC_TRUE@MALIGNR = nano-malignr
 @NEWLIB_NANO_MALLOC_FALSE@MALLOPTR = malloptr
@@ -1002,6 +1008,12 @@ lib_a-wcstold.o: wcstold.c
 lib_a-wcstold.obj: wcstold.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcstold.obj `if test -f 'wcstold.c'; then $(CYGPATH_W) 'wcstold.c'; else $(CYGPATH_W) '$(srcdir)/wcstold.c'; fi`
 
+lib_a-lock.o: lock.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lock.o `test -f 'lock.c' || echo '$(srcdir)/'`lock.c
+
+lib_a-lock.obj: lock.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lock.obj `if test -f 'lock.c'; then $(CYGPATH_W) 'lock.c'; else $(CYGPATH_W) '$(srcdir)/lock.c'; fi`
+
 lib_a-arc4random.o: arc4random.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-arc4random.o `test -f 'arc4random.c' || echo '$(srcdir)/'`arc4random.c
 
diff --git a/newlib/libc/stdlib/lock.c b/newlib/libc/stdlib/lock.c
new file mode 100644
index 0000000000000000000000000000000000000000..64947635ad79c9e9502677d3786d8a00919f0eb4
--- /dev/null
+++ b/newlib/libc/stdlib/lock.c
@@ -0,0 +1,108 @@
+/*
+FUNCTION
+<<__retarget_lock_init>>, <<__retarget_lock_init_recursive>>, <<__retarget_lock_close>>, <<__retarget_lock_close_recursive>>, <<__retarget_lock_acquire>>, <<__retarget_lock_acquire_recursive>>, <<__retarget_lock_try_acquire>>, <<__retarget_lock_try_acquire_recursive>>, <<__retarget_lock_release>>, <<__retarget_lock_release_recursive>>---locking routines
+
+INDEX
+	__retarget_lock_init
+INDEX
+	__retarget_lock_init_recursive
+INDEX
+	__retarget_lock_close
+INDEX
+	__retarget_lock_close_recursive
+INDEX
+	__retarget_lock_acquire
+INDEX
+	__retarget_lock_acquire_recursive
+INDEX
+	__retarget_lock_try_acquire
+INDEX
+	__retarget_lock_try_acquire_recursive
+INDEX
+	__retarget_lock_release
+INDEX
+	__retarget_lock_release_recursive
+
+ANSI_SYNOPSIS
+	#include <lock.h>
+	void __retarget_lock_init (_LOCK_T * <[lock_ptr]>);
+	void __retarget_lock_init_recursive (_LOCK_T * <[lock_ptr]>);
+	void __retarget_lock_close (_LOCK_T <[lock]>);
+	void __retarget_lock_close_recursive (_LOCK_T <[lock]>);
+	void __retarget_lock_acquire (_LOCK_T <[lock]>);
+	void __retarget_lock_acquire_recursive (_LOCK_T <[lock]>);
+	int __retarget_lock_try_acquire (_LOCK_T <[lock]>);
+	int __retarget_lock_try_acquire_recursive (_LOCK_T <[lock]>);
+	void __retarget_lock_release (_LOCK_T <[lock]>);
+	void __retarget_lock_release_recursive (_LOCK_T <[lock]>);
+
+DESCRIPTION
+These empty functions are used for locking to allow applications to retarget
+them.  They are used in place of the default dummy lock macros when newlib
+is configured with --enable-newlib-retargetable-locking.
+*/
+
+/* dummy lock routines for single-threaded apps */
+
+#include <sys/lock.h>
+
+struct _lock {
+  char unused;
+};
+
+struct _lock _lock___sinit_lock;
+struct _lock _lock___sfp_lock;
+struct _lock _lock___atexit_lock;
+struct _lock _lock___malloc_lock_object;
+
+void
+__retarget_lock_init (_LOCK_T *lock)
+{
+}
+
+void
+__retarget_lock_init_recursive(_LOCK_T *lock)
+{
+}
+
+void
+__retarget_lock_close(_LOCK_T lock)
+{
+}
+
+void
+__retarget_lock_close_recursive(_LOCK_T lock)
+{
+}
+
+void
+__retarget_lock_acquire (_LOCK_T lock)
+{
+}
+
+void
+__retarget_lock_acquire_recursive (_LOCK_T lock)
+{
+}
+
+int
+__retarget_lock_try_acquire(_LOCK_T lock)
+{
+  return 1;
+}
+
+int
+__retarget_lock_try_acquire_recursive(_LOCK_T lock)
+{
+  return 1;
+}
+
+void
+__retarget_lock_release (_LOCK_T lock)
+{
+}
+
+void
+__retarget_lock_release_recursive (_LOCK_T lock)
+{
+}
diff --git a/newlib/newlib.hin b/newlib/newlib.hin
index d03dfac0eea6a8917a92b8f0f3584c2cd42b9388..397bc9b96eafddace3a75be509157040654b6fde 100644
--- a/newlib/newlib.hin
+++ b/newlib/newlib.hin
@@ -82,6 +82,9 @@
 /* Define if small footprint nano-formatted-IO implementation used.  */
 #undef _NANO_FORMATTED_IO
 
+/* Define if using retargetable functions for default lock routines.  */
+#undef _RETARGETABLE_LOCKING
+
 /*
  * Iconv encodings enabled ("to" direction)
  */

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2017-01-13 13:24                             ` Thomas Preudhomme
@ 2017-01-13 18:05                               ` Freddie Chopin
  2017-01-13 18:16                                 ` Thomas Preudhomme
  0 siblings, 1 reply; 51+ messages in thread
From: Freddie Chopin @ 2017-01-13 18:05 UTC (permalink / raw)
  To: newlib

On Fri, 2017-01-13 at 13:24 +0000, Thomas Preudhomme wrote:
> And here's the patch. Tested with full and partial retargeting as
> well as no 
> retargeting.

I confirm - if I provide just some of the functions/objects, the
linking will fail with "multiple definition" error. Great!

Any chance for adding all locks used by newlib internally? These 4 are
missing from what I've seen:
newlib/libc/posix/telldir.c:__LOCK_INIT(static, dd_hash_lock);
newlib/libc/time/tzlock.c:__LOCK_INIT(static, __tz_lock_object);
newlib/libc/stdlib/quick_exit.c:__LOCK_INIT(static, atexit_mutex);
newlib/libc/stdlib/envlock.c:__LOCK_INIT_RECURSIVE(static, __env_lock_object);

I know these are not "popular", but nevertheless required. For example
time-zone locking is pulled by any function dealing with "local" time,
like a very useful mktime(). 4 bytes here or there is not such a big
deal (;

Regards,
FCh

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2017-01-13 18:05                               ` Freddie Chopin
@ 2017-01-13 18:16                                 ` Thomas Preudhomme
  2017-01-16 15:59                                   ` Thomas Preudhomme
  0 siblings, 1 reply; 51+ messages in thread
From: Thomas Preudhomme @ 2017-01-13 18:16 UTC (permalink / raw)
  To: newlib



On 13/01/17 18:05, Freddie Chopin wrote:
> On Fri, 2017-01-13 at 13:24 +0000, Thomas Preudhomme wrote:
>> And here's the patch. Tested with full and partial retargeting as
>> well as no
>> retargeting.
>
> I confirm - if I provide just some of the functions/objects, the
> linking will fail with "multiple definition" error. Great!
>
> Any chance for adding all locks used by newlib internally? These 4 are
> missing from what I've seen:
> newlib/libc/posix/telldir.c:__LOCK_INIT(static, dd_hash_lock);
> newlib/libc/time/tzlock.c:__LOCK_INIT(static, __tz_lock_object);
> newlib/libc/stdlib/quick_exit.c:__LOCK_INIT(static, atexit_mutex);
> newlib/libc/stdlib/envlock.c:__LOCK_INIT_RECURSIVE(static, __env_lock_object);
>
> I know these are not "popular", but nevertheless required. For example
> time-zone locking is pulled by any function dealing with "local" time,
> like a very useful mktime(). 4 bytes here or there is not such a big
> deal (;

Oh yes absolutely. I forgot that I added the lock only based on testing rather 
than analysis of the code. Thanks for pointing that out.

Best regards,

Thomas

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2017-01-13 18:16                                 ` Thomas Preudhomme
@ 2017-01-16 15:59                                   ` Thomas Preudhomme
  2017-01-20 13:37                                     ` Thomas Preudhomme
  0 siblings, 1 reply; 51+ messages in thread
From: Thomas Preudhomme @ 2017-01-16 15:59 UTC (permalink / raw)
  To: newlib

[-- Attachment #1: Type: text/plain, Size: 1411 bytes --]

Please find attached the updated patch.

I've noticed that there is also some target and OS specific locks: 
_arc4random_mutex and many Linux/rtems/tirtos specific locks.

I haven't included those.

Best regards,

Thomas

On 13/01/17 18:16, Thomas Preudhomme wrote:
>
>
> On 13/01/17 18:05, Freddie Chopin wrote:
>> On Fri, 2017-01-13 at 13:24 +0000, Thomas Preudhomme wrote:
>>> And here's the patch. Tested with full and partial retargeting as
>>> well as no
>>> retargeting.
>>
>> I confirm - if I provide just some of the functions/objects, the
>> linking will fail with "multiple definition" error. Great!
>>
>> Any chance for adding all locks used by newlib internally? These 4 are
>> missing from what I've seen:
>> newlib/libc/posix/telldir.c:__LOCK_INIT(static, dd_hash_lock);
>> newlib/libc/time/tzlock.c:__LOCK_INIT(static, __tz_lock_object);
>> newlib/libc/stdlib/quick_exit.c:__LOCK_INIT(static, atexit_mutex);
>> newlib/libc/stdlib/envlock.c:__LOCK_INIT_RECURSIVE(static, __env_lock_object);
>>
>> I know these are not "popular", but nevertheless required. For example
>> time-zone locking is pulled by any function dealing with "local" time,
>> like a very useful mktime(). 4 bytes here or there is not such a big
>> deal (;
>
> Oh yes absolutely. I forgot that I added the lock only based on testing rather
> than analysis of the code. Thanks for pointing that out.
>
> Best regards,
>
> Thomas

[-- Attachment #2: newlib_retargetable_locking_routine.patch --]
[-- Type: text/x-patch, Size: 23107 bytes --]

diff --git a/newlib/configure b/newlib/configure
index 2ac07fe06bfc795d94ba36d0061e4f8135146125..de28c25b3c4aaeed14b6d0ee8354fdd5c5c3115a 100755
--- a/newlib/configure
+++ b/newlib/configure
@@ -802,6 +802,7 @@ enable_newlib_nano_malloc
 enable_newlib_unbuf_stream_opt
 enable_lite_exit
 enable_newlib_nano_formatted_io
+enable_newlib_retargetable_locking
 enable_multilib
 enable_target_optspace
 enable_malloc_debugging
@@ -1473,6 +1474,7 @@ Optional Features:
   --disable-newlib-unbuf-stream-opt    disable unbuffered stream optimization in streamio
   --enable-lite-exit	enable light weight exit
   --enable-newlib-nano-formatted-io    Use nano version formatted IO
+  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time
   --enable-multilib         build many library versions (default)
   --enable-target-optspace  optimize for space
   --enable-malloc-debugging indicate malloc debugging requested
@@ -2474,6 +2476,18 @@ else
 fi
 
 
+# Check whether --enable-newlib-retargetable-locking was given.
+if test "${enable_newlib_retargetable_locking+set}" = set; then :
+  enableval=$enable_newlib_retargetable_locking; case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_locking=no ;;
+   *) as_fn_error $? "bad value ${enableval} for newlib-retargetable-locking" "$LINENO" 5 ;;
+ esac
+else
+  newlib_retargetable_locking=no
+fi
+
+
 
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
@@ -11780,7 +11794,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11783 "configure"
+#line 11797 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11886,7 +11900,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11889 "configure"
+#line 11903 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12455,6 +12469,13 @@ _ACEOF
 
 fi
 
+if test "${newlib_retargetable_locking}" = "yes"; then
+cat >>confdefs.h <<_ACEOF
+#define _RETARGETABLE_LOCKING 1
+_ACEOF
+
+fi
+
 
 if test "x${iconv_encodings}" != "x" \
    || test "x${iconv_to_encodings}" != "x" \
diff --git a/newlib/configure.in b/newlib/configure.in
index bfaf038c7f495d32d05ae8caff0172f464895ffe..354c07ca580edf75da59fb858ca2c434e0b1a4e9 100644
--- a/newlib/configure.in
+++ b/newlib/configure.in
@@ -218,6 +218,17 @@ AC_ARG_ENABLE(newlib_nano_formatted_io,
    *) AC_MSG_ERROR(bad value ${enableval} for newlib-nano-formatted-io) ;;
  esac],[newlib_nano_formatted_io=no])
 
+dnl Support --enable-retargetable-locking
+dnl This option is also read in libc/configure.in.  It is repeated
+dnl here so that it shows up in the help text.
+AC_ARG_ENABLE(newlib-retargetable-locking,
+[  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time],
+[case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_locking=no ;;
+   *) AC_MSG_ERROR(bad value ${enableval} for newlib-retargetable-locking) ;;
+ esac],[newlib_retargetable_locking=no])
+
 NEWLIB_CONFIGURE(.)
 
 dnl We have to enable libtool after NEWLIB_CONFIGURE because if we try and
@@ -458,6 +469,10 @@ if test "${newlib_nano_formatted_io}" = "yes"; then
 AC_DEFINE_UNQUOTED(_NANO_FORMATTED_IO)
 fi
 
+if test "${newlib_retargetable_locking}" = "yes"; then
+AC_DEFINE_UNQUOTED(_RETARGETABLE_LOCKING)
+fi
+
 dnl
 dnl Parse --enable-newlib-iconv-encodings option argument
 dnl
diff --git a/newlib/libc/configure b/newlib/libc/configure
index 4dc4d1bf703f388ecd3b4e0d8bef6786f7995021..dabe44fd98d74a2e029a22a217953dd52575736f 100755
--- a/newlib/libc/configure
+++ b/newlib/libc/configure
@@ -751,6 +751,8 @@ build
 newlib_basedir
 MAY_SUPPLY_SYSCALLS_FALSE
 MAY_SUPPLY_SYSCALLS_TRUE
+NEWLIB_RETARGETABLE_LOCKING_FALSE
+NEWLIB_RETARGETABLE_LOCKING_TRUE
 NEWLIB_NANO_FORMATTED_IO_FALSE
 NEWLIB_NANO_FORMATTED_IO_TRUE
 target_alias
@@ -797,6 +799,7 @@ enable_option_checking
 enable_newlib_io_pos_args
 enable_newlib_nano_malloc
 enable_newlib_nano_formatted_io
+enable_newlib_retargetable_locking
 enable_multilib
 enable_target_optspace
 enable_malloc_debugging
@@ -1448,6 +1451,7 @@ Optional Features:
   --enable-newlib-io-pos-args enable printf-family positional arg support
   --enable-newlib-nano-malloc    Use small-footprint nano-malloc implementation
   --enable-newlib-nano-formatted-io    Use small-footprint nano-formatted-IO implementation
+  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time
   --enable-multilib         build many library versions (default)
   --enable-target-optspace  optimize for space
   --enable-malloc-debugging indicate malloc debugging requested
@@ -2252,6 +2256,26 @@ else
 fi
 
 
+# Check whether --enable-newlib-retargetable-locking was given.
+if test "${enable_newlib_retargetable_locking+set}" = set; then :
+  enableval=$enable_newlib_retargetable_locking; case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_lock=no ;;
+   *) as_fn_error $? "bad value ${enableval} for newlib-retargetable-locking" "$LINENO" 5 ;;
+ esac
+else
+  newlib_retargetable_locking=no
+fi
+
+ if test x$newlib_retargetable_locking = xyes; then
+  NEWLIB_RETARGETABLE_LOCKING_TRUE=
+  NEWLIB_RETARGETABLE_LOCKING_FALSE='#'
+else
+  NEWLIB_RETARGETABLE_LOCKING_TRUE='#'
+  NEWLIB_RETARGETABLE_LOCKING_FALSE=
+fi
+
+
 
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
@@ -11525,7 +11549,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11528 "configure"
+#line 11552 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11631,7 +11655,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11634 "configure"
+#line 11658 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12248,6 +12272,10 @@ if test -z "${NEWLIB_NANO_FORMATTED_IO_TRUE}" && test -z "${NEWLIB_NANO_FORMATTE
   as_fn_error $? "conditional \"NEWLIB_NANO_FORMATTED_IO\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${NEWLIB_RETARGETABLE_LOCKING_TRUE}" && test -z "${NEWLIB_RETARGETABLE_LOCKING_FALSE}"; then
+  as_fn_error $? "conditional \"NEWLIB_RETARGETABLE_LOCKING\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${MAY_SUPPLY_SYSCALLS_TRUE}" && test -z "${MAY_SUPPLY_SYSCALLS_FALSE}"; then
   as_fn_error $? "conditional \"MAY_SUPPLY_SYSCALLS\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
diff --git a/newlib/libc/configure.in b/newlib/libc/configure.in
index 0a7bb8815be44fb1e92f753fa2c8df2a31b95f94..ac25a3933c4a4794f3cfe291e0275d0ed001b96a 100644
--- a/newlib/libc/configure.in
+++ b/newlib/libc/configure.in
@@ -36,6 +36,16 @@ AC_ARG_ENABLE(newlib_nano_formatted_io,
  esac],[newlib_nano_formatted_io=no])
 AM_CONDITIONAL(NEWLIB_NANO_FORMATTED_IO, test x$newlib_nano_formatted_io = xyes)
 
+dnl Support --enable-retargetable-locking used by libc/sys
+AC_ARG_ENABLE(newlib-retargetable-locking,
+[  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time],
+[case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_lock=no ;;
+   *) AC_MSG_ERROR(bad value ${enableval} for newlib-retargetable-locking) ;;
+ esac],[newlib_retargetable_locking=no])
+AM_CONDITIONAL(NEWLIB_RETARGETABLE_LOCKING, test x$newlib_retargetable_locking = xyes)
+
 NEWLIB_CONFIGURE(..)
 
 AM_CONDITIONAL(NEWLIB_NANO_MALLOC, test x$newlib_nano_malloc = xyes)
diff --git a/newlib/libc/include/sys/lock.h b/newlib/libc/include/sys/lock.h
index 9075e35c9179968031010432515e3a845ff6ca8d..9a8e2528c79a89d5807da8c4bb0e65151870bf42 100644
--- a/newlib/libc/include/sys/lock.h
+++ b/newlib/libc/include/sys/lock.h
@@ -3,10 +3,13 @@
 
 /* dummy lock routines for single-threaded aps */
 
+#include <newlib.h>
+#include <_ansi.h>
+
+#ifndef _RETARGETABLE_LOCKING
+
 typedef int _LOCK_T;
 typedef int _LOCK_RECURSIVE_T;
- 
-#include <_ansi.h>
 
 #define __LOCK_INIT(class,lock) static int lock = 0;
 #define __LOCK_INIT_RECURSIVE(class,lock) static int lock = 0;
@@ -21,4 +24,46 @@ typedef int _LOCK_RECURSIVE_T;
 #define __lock_release(lock) (_CAST_VOID 0)
 #define __lock_release_recursive(lock) (_CAST_VOID 0)
 
+#else
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct _lock;
+typedef struct _lock * _LOCK_T;
+#define _LOCK_RECURSIVE_T _LOCK_T
+
+#define __LOCK_INIT(class,lock) extern struct _lock _lock_ ## lock; \
+	class _LOCK_T lock = &_lock_ ## lock
+#define __LOCK_INIT_RECURSIVE(class,lock) __LOCK_INIT(class,lock)
+
+extern void __retarget_lock_init(_LOCK_T *lock);
+#define __lock_init(lock) __retarget_lock_init(&lock)
+extern void __retarget_lock_init_recursive(_LOCK_T *lock);
+#define __lock_init_recursive(lock) __retarget_lock_init_recursive(&lock)
+extern void __retarget_lock_close(_LOCK_T lock);
+#define __lock_close(lock) __retarget_lock_close(lock)
+extern void __retarget_lock_close_recursive(_LOCK_T lock);
+#define __lock_close_recursive(lock) __retarget_lock_close_recursive(lock)
+extern void __retarget_lock_acquire(_LOCK_T lock);
+#define __lock_acquire(lock) __retarget_lock_acquire(lock)
+extern void __retarget_lock_acquire_recursive(_LOCK_T lock);
+#define __lock_acquire_recursive(lock) __retarget_lock_acquire_recursive(lock)
+extern int __retarget_lock_try_acquire(_LOCK_T lock);
+#define __lock_try_acquire(lock) __retarget_lock_try_acquire(lock)
+extern int __retarget_lock_try_acquire_recursive(_LOCK_T lock);
+#define __lock_try_acquire_recursive(lock) \
+  __retarget_lock_try_acquire_recursive(lock)
+extern void __retarget_lock_release(_LOCK_T lock);
+#define __lock_release(lock) __retarget_lock_release(lock)
+extern void __retarget_lock_release_recursive(_LOCK_T lock);
+#define __lock_release_recursive(lock) __retarget_lock_release_recursive(lock)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RETARGETABLE_LOCKING */
+
 #endif /* __SYS_LOCK_H__ */
diff --git a/newlib/libc/stdlib/Makefile.am b/newlib/libc/stdlib/Makefile.am
index 2d45d1029ace8087b57657cbc11feabf76f4206e..76ed8480c28ebfb68e2f48432c0359b11f1522a8 100644
--- a/newlib/libc/stdlib/Makefile.am
+++ b/newlib/libc/stdlib/Makefile.am
@@ -74,6 +74,11 @@ GENERAL_SOURCES += \
 	wcstold.c
 endif # HAVE_LONG_DOUBLE
 
+if NEWLIB_RETARGETABLE_LOCKING
+GENERAL_SOURCES += \
+	lock.c
+endif
+
 if NEWLIB_NANO_MALLOC
 MALIGNR=nano-malignr
 MALLOPTR=nano-malloptr
diff --git a/newlib/libc/stdlib/Makefile.in b/newlib/libc/stdlib/Makefile.in
index 466ab6d1e02ea919f6c8ceed792024955bef1a66..3295e981c87bac3b21a6b72dda148f892fe018d6 100644
--- a/newlib/libc/stdlib/Makefile.in
+++ b/newlib/libc/stdlib/Makefile.in
@@ -57,6 +57,9 @@ host_triplet = @host@
 @HAVE_LONG_DOUBLE_TRUE@	strtold.c \
 @HAVE_LONG_DOUBLE_TRUE@	wcstold.c
 
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@am__append_2 = \
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@	lock.c
+
 DIST_COMMON = $(srcdir)/../../Makefile.shared $(srcdir)/Makefile.in \
 	$(srcdir)/Makefile.am
 subdir = stdlib
@@ -81,7 +84,9 @@ lib_a_AR = $(AR) $(ARFLAGS)
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(ELIX_2_OBJS)
 @HAVE_LONG_DOUBLE_TRUE@am__objects_1 = lib_a-strtold.$(OBJEXT) \
 @HAVE_LONG_DOUBLE_TRUE@	lib_a-wcstold.$(OBJEXT)
-am__objects_2 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@am__objects_2 =  \
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@	lib_a-lock.$(OBJEXT)
+am__objects_3 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \
 	lib_a-__call_atexit.$(OBJEXT) lib_a-__exp10.$(OBJEXT) \
 	lib_a-__ten_mu.$(OBJEXT) lib_a-_Exit.$(OBJEXT) \
 	lib_a-abort.$(OBJEXT) lib_a-abs.$(OBJEXT) \
@@ -112,8 +117,8 @@ am__objects_2 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \
 	lib_a-wcstol.$(OBJEXT) lib_a-wcstoul.$(OBJEXT) \
 	lib_a-wcstombs.$(OBJEXT) lib_a-wcstombs_r.$(OBJEXT) \
 	lib_a-wctomb.$(OBJEXT) lib_a-wctomb_r.$(OBJEXT) \
-	$(am__objects_1)
-am__objects_3 = lib_a-arc4random.$(OBJEXT) \
+	$(am__objects_1) $(am__objects_2)
+am__objects_4 = lib_a-arc4random.$(OBJEXT) \
 	lib_a-arc4random_uniform.$(OBJEXT) lib_a-cxa_atexit.$(OBJEXT) \
 	lib_a-cxa_finalize.$(OBJEXT) lib_a-drand48.$(OBJEXT) \
 	lib_a-ecvtbuf.$(OBJEXT) lib_a-efgcvt.$(OBJEXT) \
@@ -128,7 +133,7 @@ am__objects_3 = lib_a-arc4random.$(OBJEXT) \
 	lib_a-wcstoll_r.$(OBJEXT) lib_a-wcstoull.$(OBJEXT) \
 	lib_a-wcstoull_r.$(OBJEXT) lib_a-atoll.$(OBJEXT) \
 	lib_a-llabs.$(OBJEXT) lib_a-lldiv.$(OBJEXT)
-am__objects_4 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \
+am__objects_5 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \
 	lib_a-getopt.$(OBJEXT) lib_a-getsubopt.$(OBJEXT) \
 	lib_a-l64a.$(OBJEXT) lib_a-malign.$(OBJEXT) \
 	lib_a-mbrlen.$(OBJEXT) lib_a-mbrtowc.$(OBJEXT) \
@@ -137,22 +142,23 @@ am__objects_4 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \
 	lib_a-valloc.$(OBJEXT) lib_a-wcrtomb.$(OBJEXT) \
 	lib_a-wcsnrtombs.$(OBJEXT) lib_a-wcsrtombs.$(OBJEXT) \
 	lib_a-wctob.$(OBJEXT)
-am__objects_5 = lib_a-putenv.$(OBJEXT) lib_a-putenv_r.$(OBJEXT) \
+am__objects_6 = lib_a-putenv.$(OBJEXT) lib_a-putenv_r.$(OBJEXT) \
 	lib_a-setenv.$(OBJEXT) lib_a-setenv_r.$(OBJEXT)
-am__objects_6 = lib_a-rpmatch.$(OBJEXT) lib_a-system.$(OBJEXT)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_7 = $(am__objects_4) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_5) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_6)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_7 = $(am__objects_4) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_5)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_7 =  \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_4)
-@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_2) \
-@USE_LIBTOOL_FALSE@	$(am__objects_3) $(am__objects_7)
+am__objects_7 = lib_a-rpmatch.$(OBJEXT) lib_a-system.$(OBJEXT)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_8 = $(am__objects_5) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_6) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_7)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_8 = $(am__objects_5) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_6)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_8 =  \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_5)
+@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_3) \
+@USE_LIBTOOL_FALSE@	$(am__objects_4) $(am__objects_8)
 lib_a_OBJECTS = $(am_lib_a_OBJECTS)
 LTLIBRARIES = $(noinst_LTLIBRARIES)
-@HAVE_LONG_DOUBLE_TRUE@am__objects_8 = strtold.lo wcstold.lo
-am__objects_9 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \
+@HAVE_LONG_DOUBLE_TRUE@am__objects_9 = strtold.lo wcstold.lo
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@am__objects_10 = lock.lo
+am__objects_11 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \
 	__ten_mu.lo _Exit.lo abort.lo abs.lo aligned_alloc.lo \
 	assert.lo atexit.lo atof.lo atoff.lo atoi.lo atol.lo calloc.lo \
 	div.lo dtoa.lo dtoastub.lo environ.lo envlock.lo eprintf.lo \
@@ -163,28 +169,28 @@ am__objects_9 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \
 	rand_r.lo random.lo realloc.lo reallocf.lo sb_charsets.lo \
 	strtod.lo strtodg.lo strtol.lo strtorx.lo strtoul.lo utoa.lo \
 	wcstod.lo wcstol.lo wcstoul.lo wcstombs.lo wcstombs_r.lo \
-	wctomb.lo wctomb_r.lo $(am__objects_8)
-am__objects_10 = arc4random.lo arc4random_uniform.lo cxa_atexit.lo \
+	wctomb.lo wctomb_r.lo $(am__objects_9) $(am__objects_10)
+am__objects_12 = arc4random.lo arc4random_uniform.lo cxa_atexit.lo \
 	cxa_finalize.lo drand48.lo ecvtbuf.lo efgcvt.lo erand48.lo \
 	jrand48.lo lcong48.lo lrand48.lo mrand48.lo msize.lo mtrim.lo \
 	nrand48.lo rand48.lo seed48.lo srand48.lo strtoll.lo \
 	strtoll_r.lo strtoull.lo strtoull_r.lo wcstoll.lo wcstoll_r.lo \
 	wcstoull.lo wcstoull_r.lo atoll.lo llabs.lo lldiv.lo
-am__objects_11 = a64l.lo btowc.lo getopt.lo getsubopt.lo l64a.lo \
+am__objects_13 = a64l.lo btowc.lo getopt.lo getsubopt.lo l64a.lo \
 	malign.lo mbrlen.lo mbrtowc.lo mbsinit.lo mbsnrtowcs.lo \
 	mbsrtowcs.lo on_exit.lo valloc.lo wcrtomb.lo wcsnrtombs.lo \
 	wcsrtombs.lo wctob.lo
-am__objects_12 = putenv.lo putenv_r.lo setenv.lo setenv_r.lo
-am__objects_13 = rpmatch.lo system.lo
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_14 = $(am__objects_11) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_12) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_13)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_14 = $(am__objects_11) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_12)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_14 =  \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_11)
-@USE_LIBTOOL_TRUE@am_libstdlib_la_OBJECTS = $(am__objects_9) \
-@USE_LIBTOOL_TRUE@	$(am__objects_10) $(am__objects_14)
+am__objects_14 = putenv.lo putenv_r.lo setenv.lo setenv_r.lo
+am__objects_15 = rpmatch.lo system.lo
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_16 = $(am__objects_13) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_14) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_15)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_16 = $(am__objects_13) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_14)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_16 =  \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_13)
+@USE_LIBTOOL_TRUE@am_libstdlib_la_OBJECTS = $(am__objects_11) \
+@USE_LIBTOOL_TRUE@	$(am__objects_12) $(am__objects_16)
 libstdlib_la_OBJECTS = $(am_libstdlib_la_OBJECTS)
 libstdlib_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -367,7 +373,7 @@ GENERAL_SOURCES = __adjust.c __atexit.c __call_atexit.c __exp10.c \
 	quick_exit.c rand.c rand_r.c random.c realloc.c reallocf.c \
 	sb_charsets.c strtod.c strtodg.c strtol.c strtorx.c strtoul.c \
 	utoa.c wcstod.c wcstol.c wcstoul.c wcstombs.c wcstombs_r.c \
-	wctomb.c wctomb_r.c $(am__append_1)
+	wctomb.c wctomb_r.c $(am__append_1) $(am__append_2)
 @NEWLIB_NANO_MALLOC_FALSE@MALIGNR = malignr
 @NEWLIB_NANO_MALLOC_TRUE@MALIGNR = nano-malignr
 @NEWLIB_NANO_MALLOC_FALSE@MALLOPTR = malloptr
@@ -1002,6 +1008,12 @@ lib_a-wcstold.o: wcstold.c
 lib_a-wcstold.obj: wcstold.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcstold.obj `if test -f 'wcstold.c'; then $(CYGPATH_W) 'wcstold.c'; else $(CYGPATH_W) '$(srcdir)/wcstold.c'; fi`
 
+lib_a-lock.o: lock.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lock.o `test -f 'lock.c' || echo '$(srcdir)/'`lock.c
+
+lib_a-lock.obj: lock.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lock.obj `if test -f 'lock.c'; then $(CYGPATH_W) 'lock.c'; else $(CYGPATH_W) '$(srcdir)/lock.c'; fi`
+
 lib_a-arc4random.o: arc4random.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-arc4random.o `test -f 'arc4random.c' || echo '$(srcdir)/'`arc4random.c
 
diff --git a/newlib/libc/stdlib/lock.c b/newlib/libc/stdlib/lock.c
new file mode 100644
index 0000000000000000000000000000000000000000..5a5005b96d8b501c2d68b7fd3bccf37798a81d6a
--- /dev/null
+++ b/newlib/libc/stdlib/lock.c
@@ -0,0 +1,112 @@
+/*
+FUNCTION
+<<__retarget_lock_init>>, <<__retarget_lock_init_recursive>>, <<__retarget_lock_close>>, <<__retarget_lock_close_recursive>>, <<__retarget_lock_acquire>>, <<__retarget_lock_acquire_recursive>>, <<__retarget_lock_try_acquire>>, <<__retarget_lock_try_acquire_recursive>>, <<__retarget_lock_release>>, <<__retarget_lock_release_recursive>>---locking routines
+
+INDEX
+	__retarget_lock_init
+INDEX
+	__retarget_lock_init_recursive
+INDEX
+	__retarget_lock_close
+INDEX
+	__retarget_lock_close_recursive
+INDEX
+	__retarget_lock_acquire
+INDEX
+	__retarget_lock_acquire_recursive
+INDEX
+	__retarget_lock_try_acquire
+INDEX
+	__retarget_lock_try_acquire_recursive
+INDEX
+	__retarget_lock_release
+INDEX
+	__retarget_lock_release_recursive
+
+ANSI_SYNOPSIS
+	#include <lock.h>
+	void __retarget_lock_init (_LOCK_T * <[lock_ptr]>);
+	void __retarget_lock_init_recursive (_LOCK_T * <[lock_ptr]>);
+	void __retarget_lock_close (_LOCK_T <[lock]>);
+	void __retarget_lock_close_recursive (_LOCK_T <[lock]>);
+	void __retarget_lock_acquire (_LOCK_T <[lock]>);
+	void __retarget_lock_acquire_recursive (_LOCK_T <[lock]>);
+	int __retarget_lock_try_acquire (_LOCK_T <[lock]>);
+	int __retarget_lock_try_acquire_recursive (_LOCK_T <[lock]>);
+	void __retarget_lock_release (_LOCK_T <[lock]>);
+	void __retarget_lock_release_recursive (_LOCK_T <[lock]>);
+
+DESCRIPTION
+These empty functions are used for locking to allow applications to retarget
+them.  They are used in place of the default dummy lock macros when newlib
+is configured with --enable-newlib-retargetable-locking.
+*/
+
+/* dummy lock routines for single-threaded apps */
+
+#include <sys/lock.h>
+
+struct _lock {
+  char unused;
+};
+
+struct _lock _lock___sinit_lock;
+struct _lock _lock___sfp_lock;
+struct _lock _lock___atexit_lock;
+struct _lock _lock_atexit_mutex;
+struct _lock _lock___malloc_lock_object;
+struct _lock _lock___env_lock_object;
+struct _lock _lock___tz_lock_object;
+struct _lock _lock_dd_hash_lock;
+
+void
+__retarget_lock_init (_LOCK_T *lock)
+{
+}
+
+void
+__retarget_lock_init_recursive(_LOCK_T *lock)
+{
+}
+
+void
+__retarget_lock_close(_LOCK_T lock)
+{
+}
+
+void
+__retarget_lock_close_recursive(_LOCK_T lock)
+{
+}
+
+void
+__retarget_lock_acquire (_LOCK_T lock)
+{
+}
+
+void
+__retarget_lock_acquire_recursive (_LOCK_T lock)
+{
+}
+
+int
+__retarget_lock_try_acquire(_LOCK_T lock)
+{
+  return 1;
+}
+
+int
+__retarget_lock_try_acquire_recursive(_LOCK_T lock)
+{
+  return 1;
+}
+
+void
+__retarget_lock_release (_LOCK_T lock)
+{
+}
+
+void
+__retarget_lock_release_recursive (_LOCK_T lock)
+{
+}
diff --git a/newlib/newlib.hin b/newlib/newlib.hin
index d03dfac0eea6a8917a92b8f0f3584c2cd42b9388..397bc9b96eafddace3a75be509157040654b6fde 100644
--- a/newlib/newlib.hin
+++ b/newlib/newlib.hin
@@ -82,6 +82,9 @@
 /* Define if small footprint nano-formatted-IO implementation used.  */
 #undef _NANO_FORMATTED_IO
 
+/* Define if using retargetable functions for default lock routines.  */
+#undef _RETARGETABLE_LOCKING
+
 /*
  * Iconv encodings enabled ("to" direction)
  */

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2017-01-16 15:59                                   ` Thomas Preudhomme
@ 2017-01-20 13:37                                     ` Thomas Preudhomme
  2017-01-20 13:55                                       ` Freddie Chopin
  2017-01-24 10:00                                       ` Freddie Chopin
  0 siblings, 2 replies; 51+ messages in thread
From: Thomas Preudhomme @ 2017-01-20 13:37 UTC (permalink / raw)
  To: newlib, Freddie Chopin

Hi Freddie,

Have you had time to work on the last version of the patch?

Best regards,

Thomas

On 16/01/17 15:59, Thomas Preudhomme wrote:
> Please find attached the updated patch.
>
> I've noticed that there is also some target and OS specific locks:
> _arc4random_mutex and many Linux/rtems/tirtos specific locks.
>
> I haven't included those.
>
> Best regards,
>
> Thomas
>
> On 13/01/17 18:16, Thomas Preudhomme wrote:
>>
>>
>> On 13/01/17 18:05, Freddie Chopin wrote:
>>> On Fri, 2017-01-13 at 13:24 +0000, Thomas Preudhomme wrote:
>>>> And here's the patch. Tested with full and partial retargeting as
>>>> well as no
>>>> retargeting.
>>>
>>> I confirm - if I provide just some of the functions/objects, the
>>> linking will fail with "multiple definition" error. Great!
>>>
>>> Any chance for adding all locks used by newlib internally? These 4 are
>>> missing from what I've seen:
>>> newlib/libc/posix/telldir.c:__LOCK_INIT(static, dd_hash_lock);
>>> newlib/libc/time/tzlock.c:__LOCK_INIT(static, __tz_lock_object);
>>> newlib/libc/stdlib/quick_exit.c:__LOCK_INIT(static, atexit_mutex);
>>> newlib/libc/stdlib/envlock.c:__LOCK_INIT_RECURSIVE(static, __env_lock_object);
>>>
>>> I know these are not "popular", but nevertheless required. For example
>>> time-zone locking is pulled by any function dealing with "local" time,
>>> like a very useful mktime(). 4 bytes here or there is not such a big
>>> deal (;
>>
>> Oh yes absolutely. I forgot that I added the lock only based on testing rather
>> than analysis of the code. Thanks for pointing that out.
>>
>> Best regards,
>>
>> Thomas

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2017-01-20 13:37                                     ` Thomas Preudhomme
@ 2017-01-20 13:55                                       ` Freddie Chopin
  2017-01-24 10:00                                       ` Freddie Chopin
  1 sibling, 0 replies; 51+ messages in thread
From: Freddie Chopin @ 2017-01-20 13:55 UTC (permalink / raw)
  To: Thomas Preudhomme, newlib

On Fri, 2017-01-20 at 13:37 +0000, Thomas Preudhomme wrote:
> Hi Freddie,
> 
> Have you had time to work on the last version of the patch?

Hi Thomas!

I did not hae time this week to try it again - I've planned to do that
on the weekend. But from what I've seen the only difference between the
new version and the one I tested last week is the addition of 4 missing
lock objects.

I think that the patch will work, but - as I've said - I'll compile the
toolchain on the weekend and give it a try (;

BTW - maybe it would be possible to make the names of the locks
consistent (in a separate patch)? Internally this changes nothing for
newlib, but for this particular patch it would be nice to have names
like this:

+struct _lock _lock___sinit_recursive_lock;
+struct _lock _lock___sfp_recursive_lock;
+struct _lock _lock___atexit_recursive_lock;
+struct _lock _lock___quick_exit_lock;
+struct _lock _lock___malloc_recursive_lock;
+struct _lock _lock___env_recursive_lock;
+struct _lock _lock___tz_lock;
+struct _lock _lock___dd_hash_lock;

instead of this:

struct _lock _lock___sinit_lock;
struct _lock _lock___sfp_lock;
struct _lock _lock___atexit_lock;
struct _lock _lock_atexit_mutex;
struct _lock _lock___malloc_lock_object;
struct _lock _lock___env_lock_object;
struct _lock _lock___tz_lock_object;
struct _lock _lock_dd_hash_lock;

It's better to change it now than in the future. Exact format does not
matter much, it would be nice to just keep them similar and maybe have
the recursive/normal distinction in the name.

I'll investigate whether or not all locks are always needed, as I think
that some of them are needed only with specific newlib configurations.

Regards,
FCh

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2017-01-20 13:37                                     ` Thomas Preudhomme
  2017-01-20 13:55                                       ` Freddie Chopin
@ 2017-01-24 10:00                                       ` Freddie Chopin
  2017-01-25 12:31                                         ` Corinna Vinschen
  2017-01-30 10:51                                         ` Thomas Preudhomme
  1 sibling, 2 replies; 51+ messages in thread
From: Freddie Chopin @ 2017-01-24 10:00 UTC (permalink / raw)
  To: newlib

On Fri, 2017-01-20 at 13:37 +0000, Thomas Preudhomme wrote:
> Have you had time to work on the last version of the patch?

OK, I finally got down to it.

The toolchain builds, but this is obvious.

Some of the locks are not always needed:

1. dd_hash_lock from posix/telldir.c is defined only if HAVE_DD_LOCK is
defined. It seems that only linux and phoenix define that macro, but it
would be OK to have this lock conditional.

2. __sfp_lock and __sinit_lock from stdio/findfp.c, __tz_lock_object
from time/tzlock.c, __malloc_lock_object from stdlib/mlock.c and
__env_lock_object from stdlib/envlock.c are defined only when
__SINGLE_THREAD__ is _NOT_ defined. However __atexit_lock in
stdlib/__call_atexit.c is defined in case of __SINGLE_THREAD__
configuration, but it is not used, as all uses are conditional anyway.
On the other hand dd_hash_lock and atexit_mutex are not protected with
that macro. Maybe all locks should be conditional on this macro? I have
no idea where does this macro come from, as grepping for it in newlib,
gcc or binutils gives no definition... Maybe this is some obsolete
macro which can be just removed?

Regards,
FCh

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2017-01-24 10:00                                       ` Freddie Chopin
@ 2017-01-25 12:31                                         ` Corinna Vinschen
  2017-01-30 10:51                                         ` Thomas Preudhomme
  1 sibling, 0 replies; 51+ messages in thread
From: Corinna Vinschen @ 2017-01-25 12:31 UTC (permalink / raw)
  To: newlib

[-- Attachment #1: Type: text/plain, Size: 1400 bytes --]

On Jan 24 10:58, Freddie Chopin wrote:
> On Fri, 2017-01-20 at 13:37 +0000, Thomas Preudhomme wrote:
> > Have you had time to work on the last version of the patch?
> 
> OK, I finally got down to it.
> 
> The toolchain builds, but this is obvious.
> 
> Some of the locks are not always needed:
> 
> 1. dd_hash_lock from posix/telldir.c is defined only if HAVE_DD_LOCK is
> defined. It seems that only linux and phoenix define that macro, but it
> would be OK to have this lock conditional.
> 
> 2. __sfp_lock and __sinit_lock from stdio/findfp.c, __tz_lock_object
> from time/tzlock.c, __malloc_lock_object from stdlib/mlock.c and
> __env_lock_object from stdlib/envlock.c are defined only when
> __SINGLE_THREAD__ is _NOT_ defined. However __atexit_lock in
> stdlib/__call_atexit.c is defined in case of __SINGLE_THREAD__
> configuration, but it is not used, as all uses are conditional anyway.
> On the other hand dd_hash_lock and atexit_mutex are not protected with
> that macro. Maybe all locks should be conditional on this macro? I have
> no idea where does this macro come from, as grepping for it in newlib,
> gcc or binutils gives no definition... Maybe this is some obsolete
> macro which can be just removed?

__SINGLE_THREAD__ gets set with --enable-newlib-multithread=no,
see configure.host.


Corinna

-- 
Corinna Vinschen
Cygwin Maintainer
Red Hat

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2017-01-24 10:00                                       ` Freddie Chopin
  2017-01-25 12:31                                         ` Corinna Vinschen
@ 2017-01-30 10:51                                         ` Thomas Preudhomme
  1 sibling, 0 replies; 51+ messages in thread
From: Thomas Preudhomme @ 2017-01-30 10:51 UTC (permalink / raw)
  To: newlib



On 24/01/17 09:58, Freddie Chopin wrote:
> On Fri, 2017-01-20 at 13:37 +0000, Thomas Preudhomme wrote:
>> Have you had time to work on the last version of the patch?
>
> OK, I finally got down to it.
>
> The toolchain builds, but this is obvious.
>
> Some of the locks are not always needed:
>
> 1. dd_hash_lock from posix/telldir.c is defined only if HAVE_DD_LOCK is
> defined. It seems that only linux and phoenix define that macro, but it
> would be OK to have this lock conditional.
>
> 2. __sfp_lock and __sinit_lock from stdio/findfp.c, __tz_lock_object
> from time/tzlock.c, __malloc_lock_object from stdlib/mlock.c and
> __env_lock_object from stdlib/envlock.c are defined only when
> __SINGLE_THREAD__ is _NOT_ defined.

> However __atexit_lock in
> stdlib/__call_atexit.c is defined in case of __SINGLE_THREAD__
> configuration, but it is not used, as all uses are conditional anyway.

I think it's fragile to rely on how it's used. Someone could add a new use and 
will not think of changing the definition of the __lock_ counterpart unless they 
are testing the retargetable lock feature.

> On the other hand dd_hash_lock and atexit_mutex are not protected with
> that macro. Maybe all locks should be conditional on this macro?

That sounds like a reasonable thing to do. Why would one need a lock in a single 
threaded environment? In that case I think the __SINGLE_THREAD__ guard should be 
right in lock.h which would clean up the code nicely.

I'll look into doing that.

Best regards,

Thomas

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-11-25 12:35                   ` Sebastian Huber
@ 2016-12-13 17:20                     ` Thomas Preudhomme
  0 siblings, 0 replies; 51+ messages in thread
From: Thomas Preudhomme @ 2016-12-13 17:20 UTC (permalink / raw)
  To: newlib

Hi Sebastian,

I've just followed your comments and respinned[1] the patch to enable 
retargetable locking routines in newlib. Hopes this one will be useful to you as 
well.

[1] https://sourceware.org/ml/newlib/2016/msg01165.html

Best regards,

Thomas



On 25/11/16 12:35, Sebastian Huber wrote:
>
>
> On 25/11/16 13:04, Thomas Preudhomme wrote:
>>
>>
>> On 25/11/16 10:21, Thomas Preudhomme wrote:
>>>
>>>
>>> On 24/11/16 07:44, Sebastian Huber wrote:
>>>> Hello Thomas,
>>>>
>>>> On 23/11/16 15:38, Thomas Preudhomme wrote:
>>>>> Hi Sebastian,
>>>>>
>>>>> I was thinking on how to solve this issue and found two possible solutions:
>>>>>
>>>>> 1) select size of lock at configure time
>>>>>
>>>>> Instead of being an enable/disable option the configure option could take an
>>>>> integer value N that determine the size of lock, default being the size of a
>>>>> pointer. The lock would then be defined as an array of N integers.
>>>>>
>>>>> Pro: LOCK_INIT works, simpler & smaller change
>>>>> Cons: lock needs to be as big as the biggest lock among all the platforms you
>>>>> want to target wasting a bit of space.
>>>>>
>>>>> 2) Remove static initialization of locks
>>>>>
>>>>> Remove all LOCK_INIT and add code as required to call lock_initialize at start
>>>>> up time.
>>>>>
>>>>> Pro: you only pay the size for the lock you need (ie nothing except empty
>>>>> functions in the single threaded case)
>>>>> Cons: much bigger work, start up cannot support multithread
>>>>
>>>> 3)
>>>>
>>>> struct _lock;
>>>>
>>>> typedef struct _lock *_LOCK_T;
>>>>
>>>> #define __LOCK_INIT(class, lock) extern struct _lock _lock_ ## lock; class
>>>> _LOCK_T lock = &_lock_ ## lock;
>>>>
>>>> The OS must then provide struct _lock and storage for all statically
>>>> initialized
>>>> locks.
>>>
>>> Oh nice, clever. I've check whether there is name collision in the source where
>>> this would lead them to use the same lock and found:
>>>
>>> newlib/libc/sys/linux/iconv/gconv_db.c: __LOCK_INIT(static, lock);
>>> newlib/libc/sys/linux/iconv/gconv_trans.c: __LOCK_INIT(static, lock);
>>>
>>> The one thing I worry is the risk of new lock being added with the same name.
>>> Fortunately this could be detected at link time by looking for relocation to
>>> "_lock_.*" in newlib library and check that there is no duplicate.
>>
>> One issue though, this means the OS needs to be updated each time a statically
>> initialized lock is added to newlib. That seems to be a bit too much coupling.
>> Or am I misunderstanding how this should be used?
>
> Yes, but how many locks per minute are added to Newlib?
>

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-11-25 12:04                 ` Thomas Preudhomme
  2016-11-25 12:35                   ` Sebastian Huber
@ 2016-11-25 14:12                   ` Freddie Chopin
  1 sibling, 0 replies; 51+ messages in thread
From: Freddie Chopin @ 2016-11-25 14:12 UTC (permalink / raw)
  To: newlib

On Fri, 2016-11-25 at 12:04 +0000, Thomas Preudhomme wrote:
> > Oh nice, clever. I've check whether there is name collision in the
> > source where
> > this would lead them to use the same lock and found:
> > 
> > newlib/libc/sys/linux/iconv/gconv_db.c: __LOCK_INIT(static, lock);
> > newlib/libc/sys/linux/iconv/gconv_trans.c: __LOCK_INIT(static,
> > lock);
> > 
> > The one thing I worry is the risk of new lock being added with the
> > same name.
> > Fortunately this could be detected at link time by looking for
> > relocation to
> > "_lock_.*" in newlib library and check that there is no duplicate.
> 
> One issue though, this means the OS needs to be updated each time a
> statically 
> initialized lock is added to newlib. That seems to be a bit too much
> coupling. 
> Or am I misunderstanding how this should be used?

The solution with array and function - which is basically very similar
to this one - solves both these issues. But this has a downside of
exposing all the locks, even if they are considered to be file-local
"static" in newlib.

The second issue in Sebastian's solution can also be solved with a
special header - a source file fragment really - with declaration of
storage for all locks. Sth like:

struct _lock _lock_malloc;
struct _lock _lock_tz;
struct _lock _lock_whatever;
struct _lock _lock_xxx;

The OS would then just need to include this file _AFTER_ the _lock
struct is defined. And you would see all name collisions then.

Regards,
FCh

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-11-25 12:04                 ` Thomas Preudhomme
@ 2016-11-25 12:35                   ` Sebastian Huber
  2016-12-13 17:20                     ` Thomas Preudhomme
  2016-11-25 14:12                   ` Freddie Chopin
  1 sibling, 1 reply; 51+ messages in thread
From: Sebastian Huber @ 2016-11-25 12:35 UTC (permalink / raw)
  To: Thomas Preudhomme, newlib



On 25/11/16 13:04, Thomas Preudhomme wrote:
>
>
> On 25/11/16 10:21, Thomas Preudhomme wrote:
>>
>>
>> On 24/11/16 07:44, Sebastian Huber wrote:
>>> Hello Thomas,
>>>
>>> On 23/11/16 15:38, Thomas Preudhomme wrote:
>>>> Hi Sebastian,
>>>>
>>>> I was thinking on how to solve this issue and found two possible 
>>>> solutions:
>>>>
>>>> 1) select size of lock at configure time
>>>>
>>>> Instead of being an enable/disable option the configure option 
>>>> could take an
>>>> integer value N that determine the size of lock, default being the 
>>>> size of a
>>>> pointer. The lock would then be defined as an array of N integers.
>>>>
>>>> Pro: LOCK_INIT works, simpler & smaller change
>>>> Cons: lock needs to be as big as the biggest lock among all the 
>>>> platforms you
>>>> want to target wasting a bit of space.
>>>>
>>>> 2) Remove static initialization of locks
>>>>
>>>> Remove all LOCK_INIT and add code as required to call 
>>>> lock_initialize at start
>>>> up time.
>>>>
>>>> Pro: you only pay the size for the lock you need (ie nothing except 
>>>> empty
>>>> functions in the single threaded case)
>>>> Cons: much bigger work, start up cannot support multithread
>>>
>>> 3)
>>>
>>> struct _lock;
>>>
>>> typedef struct _lock *_LOCK_T;
>>>
>>> #define __LOCK_INIT(class, lock) extern struct _lock _lock_ ## lock; 
>>> class
>>> _LOCK_T lock = &_lock_ ## lock;
>>>
>>> The OS must then provide struct _lock and storage for all statically 
>>> initialized
>>> locks.
>>
>> Oh nice, clever. I've check whether there is name collision in the 
>> source where
>> this would lead them to use the same lock and found:
>>
>> newlib/libc/sys/linux/iconv/gconv_db.c: __LOCK_INIT(static, lock);
>> newlib/libc/sys/linux/iconv/gconv_trans.c: __LOCK_INIT(static, lock);
>>
>> The one thing I worry is the risk of new lock being added with the 
>> same name.
>> Fortunately this could be detected at link time by looking for 
>> relocation to
>> "_lock_.*" in newlib library and check that there is no duplicate.
>
> One issue though, this means the OS needs to be updated each time a 
> statically initialized lock is added to newlib. That seems to be a bit 
> too much coupling. Or am I misunderstanding how this should be used?

Yes, but how many locks per minute are added to Newlib?

-- 
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
E-Mail  : sebastian.huber@embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-11-25 10:21               ` Thomas Preudhomme
@ 2016-11-25 12:04                 ` Thomas Preudhomme
  2016-11-25 12:35                   ` Sebastian Huber
  2016-11-25 14:12                   ` Freddie Chopin
  0 siblings, 2 replies; 51+ messages in thread
From: Thomas Preudhomme @ 2016-11-25 12:04 UTC (permalink / raw)
  To: Sebastian Huber, newlib



On 25/11/16 10:21, Thomas Preudhomme wrote:
>
>
> On 24/11/16 07:44, Sebastian Huber wrote:
>> Hello Thomas,
>>
>> On 23/11/16 15:38, Thomas Preudhomme wrote:
>>> Hi Sebastian,
>>>
>>> I was thinking on how to solve this issue and found two possible solutions:
>>>
>>> 1) select size of lock at configure time
>>>
>>> Instead of being an enable/disable option the configure option could take an
>>> integer value N that determine the size of lock, default being the size of a
>>> pointer. The lock would then be defined as an array of N integers.
>>>
>>> Pro: LOCK_INIT works, simpler & smaller change
>>> Cons: lock needs to be as big as the biggest lock among all the platforms you
>>> want to target wasting a bit of space.
>>>
>>> 2) Remove static initialization of locks
>>>
>>> Remove all LOCK_INIT and add code as required to call lock_initialize at start
>>> up time.
>>>
>>> Pro: you only pay the size for the lock you need (ie nothing except empty
>>> functions in the single threaded case)
>>> Cons: much bigger work, start up cannot support multithread
>>
>> 3)
>>
>> struct _lock;
>>
>> typedef struct _lock *_LOCK_T;
>>
>> #define __LOCK_INIT(class, lock) extern struct _lock _lock_ ## lock; class
>> _LOCK_T lock = &_lock_ ## lock;
>>
>> The OS must then provide struct _lock and storage for all statically initialized
>> locks.
>
> Oh nice, clever. I've check whether there is name collision in the source where
> this would lead them to use the same lock and found:
>
> newlib/libc/sys/linux/iconv/gconv_db.c: __LOCK_INIT(static, lock);
> newlib/libc/sys/linux/iconv/gconv_trans.c: __LOCK_INIT(static, lock);
>
> The one thing I worry is the risk of new lock being added with the same name.
> Fortunately this could be detected at link time by looking for relocation to
> "_lock_.*" in newlib library and check that there is no duplicate.

One issue though, this means the OS needs to be updated each time a statically 
initialized lock is added to newlib. That seems to be a bit too much coupling. 
Or am I misunderstanding how this should be used?

Best regards,

Thomas

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-11-24  7:44             ` Sebastian Huber
  2016-11-24  8:29               ` Freddie Chopin
@ 2016-11-25 10:21               ` Thomas Preudhomme
  2016-11-25 12:04                 ` Thomas Preudhomme
  1 sibling, 1 reply; 51+ messages in thread
From: Thomas Preudhomme @ 2016-11-25 10:21 UTC (permalink / raw)
  To: Sebastian Huber, newlib



On 24/11/16 07:44, Sebastian Huber wrote:
> Hello Thomas,
>
> On 23/11/16 15:38, Thomas Preudhomme wrote:
>> Hi Sebastian,
>>
>> I was thinking on how to solve this issue and found two possible solutions:
>>
>> 1) select size of lock at configure time
>>
>> Instead of being an enable/disable option the configure option could take an
>> integer value N that determine the size of lock, default being the size of a
>> pointer. The lock would then be defined as an array of N integers.
>>
>> Pro: LOCK_INIT works, simpler & smaller change
>> Cons: lock needs to be as big as the biggest lock among all the platforms you
>> want to target wasting a bit of space.
>>
>> 2) Remove static initialization of locks
>>
>> Remove all LOCK_INIT and add code as required to call lock_initialize at start
>> up time.
>>
>> Pro: you only pay the size for the lock you need (ie nothing except empty
>> functions in the single threaded case)
>> Cons: much bigger work, start up cannot support multithread
>
> 3)
>
> struct _lock;
>
> typedef struct _lock *_LOCK_T;
>
> #define __LOCK_INIT(class, lock) extern struct _lock _lock_ ## lock; class
> _LOCK_T lock = &_lock_ ## lock;
>
> The OS must then provide struct _lock and storage for all statically initialized
> locks.

Oh nice, clever. I've check whether there is name collision in the source where 
this would lead them to use the same lock and found:

newlib/libc/sys/linux/iconv/gconv_db.c: __LOCK_INIT(static, lock);
newlib/libc/sys/linux/iconv/gconv_trans.c: __LOCK_INIT(static, lock);

The one thing I worry is the risk of new lock being added with the same name. 
Fortunately this could be detected at link time by looking for relocation to 
"_lock_.*" in newlib library and check that there is no duplicate.

Best regards,

Thomas

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-11-24  7:44             ` Sebastian Huber
@ 2016-11-24  8:29               ` Freddie Chopin
  2016-11-25 10:21               ` Thomas Preudhomme
  1 sibling, 0 replies; 51+ messages in thread
From: Freddie Chopin @ 2016-11-24  8:29 UTC (permalink / raw)
  To: newlib

On Thu, 2016-11-24 at 08:44 +0100, Sebastian Huber wrote:
> 3)
> 
> struct _lock;
> 
> typedef struct _lock *_LOCK_T;
> 
> #define __LOCK_INIT(class, lock) extern struct _lock _lock_ ## lock;
> class _LOCK_T lock = &_lock_ ## lock;
> 
> The OS must then provide struct _lock and storage for all statically
> initialized locks.

Good and simple, changes almost nothing in newlib's code, easy to have
both recursive and non-recursive locks.

+1

I think it would be possible to get rid of the "class _LOCK_T lock =
&_lock_ ## lock;" part. For example with macros like:

#define __tz_lock_object &__tz_lock_storage

Regards,
FCh

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-11-23 14:38           ` Thomas Preudhomme
  2016-11-23 15:52             ` Freddie Chopin
@ 2016-11-24  7:44             ` Sebastian Huber
  2016-11-24  8:29               ` Freddie Chopin
  2016-11-25 10:21               ` Thomas Preudhomme
  1 sibling, 2 replies; 51+ messages in thread
From: Sebastian Huber @ 2016-11-24  7:44 UTC (permalink / raw)
  To: Thomas Preudhomme, newlib

Hello Thomas,

On 23/11/16 15:38, Thomas Preudhomme wrote:
> Hi Sebastian,
>
> I was thinking on how to solve this issue and found two possible 
> solutions:
>
> 1) select size of lock at configure time
>
> Instead of being an enable/disable option the configure option could 
> take an integer value N that determine the size of lock, default being 
> the size of a pointer. The lock would then be defined as an array of N 
> integers.
>
> Pro: LOCK_INIT works, simpler & smaller change
> Cons: lock needs to be as big as the biggest lock among all the 
> platforms you want to target wasting a bit of space.
>
> 2) Remove static initialization of locks
>
> Remove all LOCK_INIT and add code as required to call lock_initialize 
> at start up time.
>
> Pro: you only pay the size for the lock you need (ie nothing except 
> empty functions in the single threaded case)
> Cons: much bigger work, start up cannot support multithread

3)

struct _lock;

typedef struct _lock *_LOCK_T;

#define __LOCK_INIT(class, lock) extern struct _lock _lock_ ## lock; class _LOCK_T lock = &_lock_ ## lock;

The OS must then provide struct _lock and storage for all statically initialized locks.

-- 
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
E-Mail  : sebastian.huber@embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-11-23 14:38           ` Thomas Preudhomme
@ 2016-11-23 15:52             ` Freddie Chopin
  2016-11-24  7:44             ` Sebastian Huber
  1 sibling, 0 replies; 51+ messages in thread
From: Freddie Chopin @ 2016-11-23 15:52 UTC (permalink / raw)
  To: newlib

Hi!

I'm not Sebastian, but I took the liberty to give an opinion here.
Option 1 brings almost nothing, as you have to make sure the toolchain
you use supports the RTOS you want to use. If it doesn't you have to
build your own. If you have to build your own, then you can as well
just integrate locks without this change...

As for the option 2 I guess that it would be perfectly reasonable to
declare some kind of startup function that should be called by user's
RTOS.

I have just thought about another idea:
1. Newlib would define - in a public header - number of required
recursive and non-recursive statically allocated locks:
#define AMOUNT_OF_STATIC_LOCKS 5
#define AMOUNT_OF_STATIC_RECURSIVE_LOCKS 3
2. In the same header it would define functions like "void*
get_lock(size_t index)" and "void* get_recursive_lock(size_t index)".
3. In some private newlib header there would be assignments of indexes
with locks like:
#define MALLOC_RECURSIVE_LOCK 0
#define STDIO_RECURSIVE_LOCK 1
...
#define TZ_LOCK 0
#define WHATEVER_LOCK 1
...
4. All uses of locks like:
__lock_acquire_recursive(__malloc_lock);
would have to be changed to:
__lock_acquire_recursive(get_recursive_lock(MALLOC_RECURSIVE_LOCK));


This way the user could just have in his own RTOS a nice array of locks
with proper size and automatic amount of elements. More advantages:
- by having two functions and two defines we could easily have
recursive and non-recursive locks;
- we could just drop __LOCK_INIT and add a requirement for user to
initialize the locks;

What do you think?

Regards,
FCh

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-11-11 11:56         ` Sebastian Huber
  2016-11-11 13:40           ` Thomas Preudhomme
@ 2016-11-23 14:38           ` Thomas Preudhomme
  2016-11-23 15:52             ` Freddie Chopin
  2016-11-24  7:44             ` Sebastian Huber
  1 sibling, 2 replies; 51+ messages in thread
From: Thomas Preudhomme @ 2016-11-23 14:38 UTC (permalink / raw)
  To: newlib

Hi Sebastian,

I was thinking on how to solve this issue and found two possible solutions:

1) select size of lock at configure time

Instead of being an enable/disable option the configure option could take an 
integer value N that determine the size of lock, default being the size of a 
pointer. The lock would then be defined as an array of N integers.

Pro: LOCK_INIT works, simpler & smaller change
Cons: lock needs to be as big as the biggest lock among all the platforms you 
want to target wasting a bit of space.

2) Remove static initialization of locks

Remove all LOCK_INIT and add code as required to call lock_initialize at start 
up time.

Pro: you only pay the size for the lock you need (ie nothing except empty 
functions in the single threaded case)
Cons: much bigger work, start up cannot support multithread


I'm more in favor of 1) because that's good enough for us and the change is 
smaller in scale but I want to make sure that's good for your use case as well.

Best regards,

Thomas

On 11/11/16 11:56, Sebastian Huber wrote:
>
> ----- Thomas Preudhomme <thomas.preudhomme@foss.arm.com> schrieb:
>> On 10/11/16 20:32, Freddie Chopin wrote:
> [...]
>>> This could work, if only malloc() was not protected with the statically
>>> created _LOCK_T lock itself, which would need such initialization
>>> too... I don't see any other way to write such function for an RTOS
>>> which has mutexes with size greater than "uintptr_t" (probably huge
>>> majority). You could do it with a static pool of storage for mutexes,
>>> but then you'd have to know upfront how many you want and your RTOS
>>> would have to allow creation of locks in provided storage (most of them
>>> allow that, but not all). Maybe I just don't see the simplest solution
>>> to this problem?
>>
>> Why do mutex needs to be more than a single integer? How big are mutex in RTOS
>> typically in your experience?
>
> This depends on what features the RTOS wants to support.  For example SMP, locking protocols, blocking on a wait queue, user-provided or external-provided storage, nesting, etc.
>
> For RTEMS a recursive mutex with support for priority inheritance (or OMIP) and SMP (optional) needs 20 bytes on a 32-bit machine for example:
>
> https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=newlib/libc/sys/rtems/include/sys/lock.h;h=e0d77cb614b348a949e23ca4c543b1ce6a055b6d;hb=HEAD#l55
>
> With an integer only you can implement a futex like on Linux, however, this needs a complex infrastructure in the background and provides only random fairness.
>

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-11-11 13:40           ` Thomas Preudhomme
@ 2016-11-11 14:10             ` Freddie Chopin
  0 siblings, 0 replies; 51+ messages in thread
From: Freddie Chopin @ 2016-11-11 14:10 UTC (permalink / raw)
  To: newlib

On Fri, 2016-11-11 at 13:40 +0000, Thomas Preudhomme wrote:
> Right, I didn't think of extra features. The one thing I could think
> of would be 
> to remove usage of the static initializers and only use the function
> initializer 
> which could do a malloc if needed. The issue you described with
> malloc can be 
> avoided by redefining malloc_lock so as not to call the generic lock
> function.
> 
> Now whether this is worth the trouble is another issue because that
> would 
> require more work. Thanks a lot for the feedback, I'm glad you
> pointed out the 
> pitfalls in that approach. It is time to go back to the drawing
> board.

See my earlier message to onkel.jack - I've given some alternative
options there at the end, the one you mentioned is also there. It has a
major problem, that it's not easily possible to actually execute these
initialization functions for most of the global locks...

https://sourceware.org/ml/newlib/2016/msg01093.html

Regards,
FCh

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-11-11 11:56         ` Sebastian Huber
@ 2016-11-11 13:40           ` Thomas Preudhomme
  2016-11-11 14:10             ` Freddie Chopin
  2016-11-23 14:38           ` Thomas Preudhomme
  1 sibling, 1 reply; 51+ messages in thread
From: Thomas Preudhomme @ 2016-11-11 13:40 UTC (permalink / raw)
  To: newlib



On 11/11/16 11:56, Sebastian Huber wrote:
>
> ----- Thomas Preudhomme <thomas.preudhomme@foss.arm.com> schrieb:
>> On 10/11/16 20:32, Freddie Chopin wrote:
> [...]
>>> This could work, if only malloc() was not protected with the statically
>>> created _LOCK_T lock itself, which would need such initialization
>>> too... I don't see any other way to write such function for an RTOS
>>> which has mutexes with size greater than "uintptr_t" (probably huge
>>> majority). You could do it with a static pool of storage for mutexes,
>>> but then you'd have to know upfront how many you want and your RTOS
>>> would have to allow creation of locks in provided storage (most of them
>>> allow that, but not all). Maybe I just don't see the simplest solution
>>> to this problem?
>>
>> Why do mutex needs to be more than a single integer? How big are mutex in RTOS
>> typically in your experience?
>
> This depends on what features the RTOS wants to support.  For example SMP, locking protocols, blocking on a wait queue, user-provided or external-provided storage, nesting, etc.
>
> For RTEMS a recursive mutex with support for priority inheritance (or OMIP) and SMP (optional) needs 20 bytes on a 32-bit machine for example:
>
> https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=newlib/libc/sys/rtems/include/sys/lock.h;h=e0d77cb614b348a949e23ca4c543b1ce6a055b6d;hb=HEAD#l55

Right, I didn't think of extra features. The one thing I could think of would be 
to remove usage of the static initializers and only use the function initializer 
which could do a malloc if needed. The issue you described with malloc can be 
avoided by redefining malloc_lock so as not to call the generic lock function.

Now whether this is worth the trouble is another issue because that would 
require more work. Thanks a lot for the feedback, I'm glad you pointed out the 
pitfalls in that approach. It is time to go back to the drawing board.

Best regards,

Thomas

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-11-11 11:09       ` Thomas Preudhomme
  2016-11-11 11:54         ` Freddie Chopin
@ 2016-11-11 11:56         ` Sebastian Huber
  2016-11-11 13:40           ` Thomas Preudhomme
  2016-11-23 14:38           ` Thomas Preudhomme
  1 sibling, 2 replies; 51+ messages in thread
From: Sebastian Huber @ 2016-11-11 11:56 UTC (permalink / raw)
  To: Thomas Preudhomme; +Cc: newlib


----- Thomas Preudhomme <thomas.preudhomme@foss.arm.com> schrieb:
> On 10/11/16 20:32, Freddie Chopin wrote:
[...]
> > This could work, if only malloc() was not protected with the statically
> > created _LOCK_T lock itself, which would need such initialization
> > too... I don't see any other way to write such function for an RTOS
> > which has mutexes with size greater than "uintptr_t" (probably huge
> > majority). You could do it with a static pool of storage for mutexes,
> > but then you'd have to know upfront how many you want and your RTOS
> > would have to allow creation of locks in provided storage (most of them
> > allow that, but not all). Maybe I just don't see the simplest solution
> > to this problem?
> 
> Why do mutex needs to be more than a single integer? How big are mutex in RTOS 
> typically in your experience?

This depends on what features the RTOS wants to support.  For example SMP, locking protocols, blocking on a wait queue, user-provided or external-provided storage, nesting, etc.

For RTEMS a recursive mutex with support for priority inheritance (or OMIP) and SMP (optional) needs 20 bytes on a 32-bit machine for example:

https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;a=blob;f=newlib/libc/sys/rtems/include/sys/lock.h;h=e0d77cb614b348a949e23ca4c543b1ce6a055b6d;hb=HEAD#l55

With an integer only you can implement a futex like on Linux, however, this needs a complex infrastructure in the background and provides only random fairness.

-- 
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
E-Mail  : sebastian.huber at embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-11-11 11:09       ` Thomas Preudhomme
@ 2016-11-11 11:54         ` Freddie Chopin
  2016-11-11 11:56         ` Sebastian Huber
  1 sibling, 0 replies; 51+ messages in thread
From: Freddie Chopin @ 2016-11-11 11:54 UTC (permalink / raw)
  To: newlib

On Fri, 2016-11-11 at 11:09 +0000, Thomas Preudhomme wrote:
> Why do mutex needs to be more than a single integer? How big are
> mutex in RTOS 
> typically in your experience?

Well, mutexes or things like that may be just a "int" in Linux or other
"big" systems, where they are really just handles for data structures
managed by the kernel. In "small" embedded RTOSes these object usually
contain everything that is needed to implement the complete
functionality, especially the linked list of threads that are blocked
on this object.

In my RTOS mutex is 28 bytes.
In ChibiOS/RT mutex is 20 bytes.
In FreeRTOS mutx is a monster with size of at least 70 bytes (depending
on the config this can be a bit more).

(above number are valid for 32-bit architectures)

Regards,
FCh


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-11-10 20:32     ` Freddie Chopin
  2016-11-10 20:35       ` Freddie Chopin
@ 2016-11-11 11:09       ` Thomas Preudhomme
  2016-11-11 11:54         ` Freddie Chopin
  2016-11-11 11:56         ` Sebastian Huber
  1 sibling, 2 replies; 51+ messages in thread
From: Thomas Preudhomme @ 2016-11-11 11:09 UTC (permalink / raw)
  To: newlib

On 10/11/16 20:32, Freddie Chopin wrote:
> Hello again!
>
> On Thu, 2016-11-10 at 16:04 +0000, Thomas Preudhomme wrote:
>>> Why don't you do the same thing for recursive functions? At least
>>> the
>>> lock used by malloc() has to be recursive, so with your patch
>>> exactly
>>> all mutexes should be recursive too.
>>
>> Yes, I did not want to expose all functions until there is a need to
>> differentiate. it is easy to add them later but removing it if noone
>> use it
>> would be quite difficult.
>
> But there is a need to differentiate! Recursive lock is used 10 times
> in newlib (for example in malloc() / free()), non-recursive is used 4
> times (for example for locking time-zone info). If you only allow
> overriding the "standard" functions, you effectively force the user to
> use recursive locks everywhere. I'd definitely be "for" providing
> functions for both lock types!

My idea was indeed that all lock would have to be recursive in a first time and 
differential later if that proves necessary. I'm happy to revisit that though.

>
>>> I have doubts about practical implementation of these functions for
>>> any
>>> RTOS, because of the __LOCK_INIT() macro used for initialization.
>>> In
>>> every retargeted function you'll have to start critical section
>>> (most
>>> likely by disabling interrupts) to initialize the object on heap,
>>> but
>>> then how would you use heap if malloc()'s lock is used via these
>>> functions too?
>>
>> I do not understand. Why would __LOCK_INIT need to start a critical
>> section?
>
> OK, this was not very clear. The problem with simple functions like the
> ones in your patch is that they are extremely hard to actually use in
> an RTOS. Or maybe it just seems so hard for me, that's also possible.
>
> This problem affects only "static" locks created with __LOCK_INIT and
> __LOCK_INIT_RECURSIVE macros. With your patch such locks are just
> uintptr_t with value 0. From my understanding it seems that such locks
> are considered to be "initialized". So you can call __lock_acquire() on
> such object right away. But how would such function look like?
>
> void __lock_acquire(_LOCK_T lock)
> {
> 	if (lock == 0)
> 	{
> 		// lock not yet really initialized...
> 		disableInterrupts();
> 		if (lock == 0)	// re-check due to possible race condition
> 			lock = malloc(sizeof(RealMutexFromYourRtos));
>
> 		assert(lock != 0);
> 		rtos_mutex_create(lock);
> 		enableInterrupts();
> 	}
>
> 	rtos_mutex_lock((RealMutexFromYourRtos*)lock);
> }

Oh I see, that's very clear now, thank you.

>
> This could work, if only malloc() was not protected with the statically
> created _LOCK_T lock itself, which would need such initialization
> too... I don't see any other way to write such function for an RTOS
> which has mutexes with size greater than "uintptr_t" (probably huge
> majority). You could do it with a static pool of storage for mutexes,
> but then you'd have to know upfront how many you want and your RTOS
> would have to allow creation of locks in provided storage (most of them
> allow that, but not all). Maybe I just don't see the simplest solution
> to this problem?

Why do mutex needs to be more than a single integer? How big are mutex in RTOS 
typically in your experience?

>
> Don't get me wrong - I'd really like something like this to be in
> newlib. It just seems that this is extremely hard due to the
> __LOCK_INIT macro which hardcodes the actual size of storage... I'm
> really interested in that feature, as I'd like to provide better newlib
> integration for the RTOS I'm writing ( http://distortos.org/ ).
>
> Regasrds,
> FCh
>

Best regards,

Thomas

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-11-10 20:32     ` Freddie Chopin
@ 2016-11-10 20:35       ` Freddie Chopin
  2016-11-11 11:09       ` Thomas Preudhomme
  1 sibling, 0 replies; 51+ messages in thread
From: Freddie Chopin @ 2016-11-10 20:35 UTC (permalink / raw)
  To: newlib

On Thu, 2016-11-10 at 21:32 +0100, Freddie Chopin wrote:
> void __lock_acquire(_LOCK_T lock)
> {
> 	if (lock == 0)
> 	{
> 		// lock not yet really initialized...
> 		disableInterrupts();
> 		if (lock == 0)	// re-check due to possible race
> condition
> 			lock = malloc(sizeof(RealMutexFromYourRtos));
> 
> 		assert(lock != 0);
> 		rtos_mutex_create(lock);
> 		enableInterrupts();
> 	}
> 
> 	rtos_mutex_lock((RealMutexFromYourRtos*)lock);
> }

I've obviously missed some curly braces for the inner "if", but I guess
you get my idea anyway (;

Regards,
FCh

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-11-10 16:05   ` Thomas Preudhomme
@ 2016-11-10 20:32     ` Freddie Chopin
  2016-11-10 20:35       ` Freddie Chopin
  2016-11-11 11:09       ` Thomas Preudhomme
  0 siblings, 2 replies; 51+ messages in thread
From: Freddie Chopin @ 2016-11-10 20:32 UTC (permalink / raw)
  To: newlib

Hello again!

On Thu, 2016-11-10 at 16:04 +0000, Thomas Preudhomme wrote:
> > Why don't you do the same thing for recursive functions? At least
> > the
> > lock used by malloc() has to be recursive, so with your patch
> > exactly
> > all mutexes should be recursive too.
> 
> Yes, I did not want to expose all functions until there is a need to 
> differentiate. it is easy to add them later but removing it if noone
> use it 
> would be quite difficult.

But there is a need to differentiate! Recursive lock is used 10 times
in newlib (for example in malloc() / free()), non-recursive is used 4
times (for example for locking time-zone info). If you only allow
overriding the "standard" functions, you effectively force the user to
use recursive locks everywhere. I'd definitely be "for" providing
functions for both lock types!

> > I have doubts about practical implementation of these functions for
> > any
> > RTOS, because of the __LOCK_INIT() macro used for initialization.
> > In
> > every retargeted function you'll have to start critical section
> > (most
> > likely by disabling interrupts) to initialize the object on heap,
> > but
> > then how would you use heap if malloc()'s lock is used via these
> > functions too?
> 
> I do not understand. Why would __LOCK_INIT need to start a critical
> section?

OK, this was not very clear. The problem with simple functions like the
ones in your patch is that they are extremely hard to actually use in
an RTOS. Or maybe it just seems so hard for me, that's also possible.

This problem affects only "static" locks created with __LOCK_INIT and
__LOCK_INIT_RECURSIVE macros. With your patch such locks are just
uintptr_t with value 0. From my understanding it seems that such locks
are considered to be "initialized". So you can call __lock_acquire() on
such object right away. But how would such function look like?

void __lock_acquire(_LOCK_T lock)
{
	if (lock == 0)
	{
		// lock not yet really initialized...
		disableInterrupts();
		if (lock == 0)	// re-check due to possible race condition
			lock = malloc(sizeof(RealMutexFromYourRtos));

		assert(lock != 0);
		rtos_mutex_create(lock);
		enableInterrupts();
	}

	rtos_mutex_lock((RealMutexFromYourRtos*)lock);
}

This could work, if only malloc() was not protected with the statically
created _LOCK_T lock itself, which would need such initialization
too... I don't see any other way to write such function for an RTOS
which has mutexes with size greater than "uintptr_t" (probably huge
majority). You could do it with a static pool of storage for mutexes,
but then you'd have to know upfront how many you want and your RTOS
would have to allow creation of locks in provided storage (most of them
allow that, but not all). Maybe I just don't see the simplest solution
to this problem?

Don't get me wrong - I'd really like something like this to be in
newlib. It just seems that this is extremely hard due to the
__LOCK_INIT macro which hardcodes the actual size of storage... I'm
really interested in that feature, as I'd like to provide better newlib
integration for the RTOS I'm writing ( http://distortos.org/ ).

Regasrds,
FCh

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-11-10 15:34 ` Freddie Chopin
@ 2016-11-10 16:05   ` Thomas Preudhomme
  2016-11-10 20:32     ` Freddie Chopin
  0 siblings, 1 reply; 51+ messages in thread
From: Thomas Preudhomme @ 2016-11-10 16:05 UTC (permalink / raw)
  To: newlib

Hi Freddie,

Thanks for your feedback.

On 10/11/16 15:33, Freddie Chopin wrote:
> Hi Thomas!
>
> Why don't you do the same thing for recursive functions? At least the
> lock used by malloc() has to be recursive, so with your patch exactly
> all mutexes should be recursive too.

Yes, I did not want to expose all functions until there is a need to 
differentiate. it is easy to add them later but removing it if noone use it 
would be quite difficult.

>
> I have doubts about practical implementation of these functions for any
> RTOS, because of the __LOCK_INIT() macro used for initialization. In
> every retargeted function you'll have to start critical section (most
> likely by disabling interrupts) to initialize the object on heap, but
> then how would you use heap if malloc()'s lock is used via these
> functions too?

I do not understand. Why would __LOCK_INIT need to start a critical section?

Best regards,

Thomas

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH, newlib] Allow locking routine to be retargeted
  2016-11-10 14:42 Thomas Preudhomme
@ 2016-11-10 15:34 ` Freddie Chopin
  2016-11-10 16:05   ` Thomas Preudhomme
  0 siblings, 1 reply; 51+ messages in thread
From: Freddie Chopin @ 2016-11-10 15:34 UTC (permalink / raw)
  To: newlib

Hi Thomas!

Why don't you do the same thing for recursive functions? At least the
lock used by malloc() has to be recursive, so with your patch exactly
all mutexes should be recursive too.

I have doubts about practical implementation of these functions for any
RTOS, because of the __LOCK_INIT() macro used for initialization. In
every retargeted function you'll have to start critical section (most
likely by disabling interrupts) to initialize the object on heap, but
then how would you use heap if malloc()'s lock is used via these
functions too?

Regards,
FCh

^ permalink raw reply	[flat|nested] 51+ messages in thread

* [PATCH, newlib] Allow locking routine to be retargeted
@ 2016-11-10 14:42 Thomas Preudhomme
  2016-11-10 15:34 ` Freddie Chopin
  0 siblings, 1 reply; 51+ messages in thread
From: Thomas Preudhomme @ 2016-11-10 14:42 UTC (permalink / raw)
  To: newlib

[-- Attachment #1: Type: text/plain, Size: 989 bytes --]

Hi,

At the moment when targeting bare-metal targets or systems without definition 
for the locking primitives, newlib uses dummy empty macros. This has the 
advantage of reduced size and faster implementation but does not allow the 
application to retarget the locking routines. Retargeting is useful for a single 
toolchain to support multiple systems since then it's only at build time that 
you know which system you are targeting.

This patch adds a new configure option --enable-newlib-retargetable-locking to 
use dummy empty weakly defined functions instead of dummy empty macros. The 
default is to keep the current behavior to not have any size or speed impact on 
targets not interested in this feature.

Testing: I've built a simple test program that calls malloc and free with all 
the locking function defined in the same file. Running into a debugger with 
breakpoints on the function shows that they are indeed called.

Is this ok for master branch?

Best regards,

Thomas

[-- Attachment #2: retargetable_locking_routine.patch --]
[-- Type: text/x-patch, Size: 21050 bytes --]

diff --git a/newlib/configure b/newlib/configure
index 30e1d57664302248af9087b0051290e2aff4b382..42b1e13feeda8a5b7ad3cf365393bd4640da4c8c 100755
--- a/newlib/configure
+++ b/newlib/configure
@@ -798,6 +798,7 @@ enable_newlib_nano_malloc
 enable_newlib_unbuf_stream_opt
 enable_lite_exit
 enable_newlib_nano_formatted_io
+enable_newlib_retargetable_locking
 enable_multilib
 enable_target_optspace
 enable_malloc_debugging
@@ -1469,6 +1470,7 @@ Optional Features:
   --disable-newlib-unbuf-stream-opt    disable unbuffered stream optimization in streamio
   --enable-lite-exit	enable light weight exit
   --enable-newlib-nano-formatted-io    Use nano version formatted IO
+  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time
   --enable-multilib         build many library versions (default)
   --enable-target-optspace  optimize for space
   --enable-malloc-debugging indicate malloc debugging requested
@@ -2470,6 +2472,18 @@ else
 fi
 
 
+# Check whether --enable-newlib-retargetable-locking was given.
+if test "${enable_newlib_retargetable_locking+set}" = set; then :
+  enableval=$enable_newlib_retargetable_locking; case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_locking=no ;;
+   *) as_fn_error $? "bad value ${enableval} for newlib-retargetable-locking" "$LINENO" 5 ;;
+ esac
+else
+  newlib_retargetable_locking=no
+fi
+
+
 
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
@@ -11776,7 +11790,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11779 "configure"
+#line 11793 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11882,7 +11896,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11885 "configure"
+#line 11899 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12421,6 +12435,13 @@ _ACEOF
 
 fi
 
+if test "${newlib_retargetable_locking}" = "yes"; then
+cat >>confdefs.h <<_ACEOF
+#define _RETARGETABLE_LOCKING 1
+_ACEOF
+
+fi
+
 
 if test "x${iconv_encodings}" != "x" \
    || test "x${iconv_to_encodings}" != "x" \
diff --git a/newlib/configure.in b/newlib/configure.in
index 01c6367a99cdf6f74a5ad15c8a4eb4a45f206e9d..70cffa76a966f8d9cd1c8888156002e76ea13dc2 100644
--- a/newlib/configure.in
+++ b/newlib/configure.in
@@ -218,6 +218,17 @@ AC_ARG_ENABLE(newlib_nano_formatted_io,
    *) AC_MSG_ERROR(bad value ${enableval} for newlib-nano-formatted-io) ;;
  esac],[newlib_nano_formatted_io=no])
 
+dnl Support --enable-retargetable-locking
+dnl This option is also read in libc/configure.in.  It is repeated
+dnl here so that it shows up in the help text.
+AC_ARG_ENABLE(newlib-retargetable-locking,
+[  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time],
+[case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_locking=no ;;
+   *) AC_MSG_ERROR(bad value ${enableval} for newlib-retargetable-locking) ;;
+ esac],[newlib_retargetable_locking=no])
+
 NEWLIB_CONFIGURE(.)
 
 dnl We have to enable libtool after NEWLIB_CONFIGURE because if we try and
@@ -442,6 +453,10 @@ if test "${newlib_nano_formatted_io}" = "yes"; then
 AC_DEFINE_UNQUOTED(_NANO_FORMATTED_IO)
 fi
 
+if test "${newlib_retargetable_locking}" = "yes"; then
+AC_DEFINE_UNQUOTED(_RETARGETABLE_LOCKING)
+fi
+
 dnl
 dnl Parse --enable-newlib-iconv-encodings option argument
 dnl
diff --git a/newlib/libc/configure b/newlib/libc/configure
index 5dccc852b8cd90d697a90f113ec17982741ecc3a..35077b81550aa999026ff67a7428fec6509a26ce 100755
--- a/newlib/libc/configure
+++ b/newlib/libc/configure
@@ -751,6 +751,8 @@ build
 newlib_basedir
 MAY_SUPPLY_SYSCALLS_FALSE
 MAY_SUPPLY_SYSCALLS_TRUE
+NEWLIB_RETARGETABLE_LOCKING_FALSE
+NEWLIB_RETARGETABLE_LOCKING_TRUE
 NEWLIB_NANO_FORMATTED_IO_FALSE
 NEWLIB_NANO_FORMATTED_IO_TRUE
 target_alias
@@ -797,6 +799,7 @@ enable_option_checking
 enable_newlib_io_pos_args
 enable_newlib_nano_malloc
 enable_newlib_nano_formatted_io
+enable_newlib_retargetable_locking
 enable_multilib
 enable_target_optspace
 enable_malloc_debugging
@@ -1448,6 +1451,7 @@ Optional Features:
   --enable-newlib-io-pos-args enable printf-family positional arg support
   --enable-newlib-nano-malloc    Use small-footprint nano-malloc implementation
   --enable-newlib-nano-formatted-io    Use small-footprint nano-formatted-IO implementation
+  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time
   --enable-multilib         build many library versions (default)
   --enable-target-optspace  optimize for space
   --enable-malloc-debugging indicate malloc debugging requested
@@ -2252,6 +2256,26 @@ else
 fi
 
 
+# Check whether --enable-newlib-retargetable-locking was given.
+if test "${enable_newlib_retargetable_locking+set}" = set; then :
+  enableval=$enable_newlib_retargetable_locking; case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_lock=no ;;
+   *) as_fn_error $? "bad value ${enableval} for newlib-retargetable-locking" "$LINENO" 5 ;;
+ esac
+else
+  newlib_retargetable_locking=no
+fi
+
+ if test x$newlib_retargetable_locking = xyes; then
+  NEWLIB_RETARGETABLE_LOCKING_TRUE=
+  NEWLIB_RETARGETABLE_LOCKING_FALSE='#'
+else
+  NEWLIB_RETARGETABLE_LOCKING_TRUE='#'
+  NEWLIB_RETARGETABLE_LOCKING_FALSE=
+fi
+
+
 
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
@@ -11525,7 +11549,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11528 "configure"
+#line 11552 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11631,7 +11655,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11634 "configure"
+#line 11658 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12248,6 +12272,10 @@ if test -z "${NEWLIB_NANO_FORMATTED_IO_TRUE}" && test -z "${NEWLIB_NANO_FORMATTE
   as_fn_error $? "conditional \"NEWLIB_NANO_FORMATTED_IO\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${NEWLIB_RETARGETABLE_LOCKING_TRUE}" && test -z "${NEWLIB_RETARGETABLE_LOCKING_FALSE}"; then
+  as_fn_error $? "conditional \"NEWLIB_RETARGETABLE_LOCKING\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${MAY_SUPPLY_SYSCALLS_TRUE}" && test -z "${MAY_SUPPLY_SYSCALLS_FALSE}"; then
   as_fn_error $? "conditional \"MAY_SUPPLY_SYSCALLS\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
diff --git a/newlib/libc/configure.in b/newlib/libc/configure.in
index 0a7bb8815be44fb1e92f753fa2c8df2a31b95f94..ac25a3933c4a4794f3cfe291e0275d0ed001b96a 100644
--- a/newlib/libc/configure.in
+++ b/newlib/libc/configure.in
@@ -36,6 +36,16 @@ AC_ARG_ENABLE(newlib_nano_formatted_io,
  esac],[newlib_nano_formatted_io=no])
 AM_CONDITIONAL(NEWLIB_NANO_FORMATTED_IO, test x$newlib_nano_formatted_io = xyes)
 
+dnl Support --enable-retargetable-locking used by libc/sys
+AC_ARG_ENABLE(newlib-retargetable-locking,
+[  --enable-newlib-retargetable-locking    Allow locking routines to be retargeted at link time],
+[case "${enableval}" in
+   yes) newlib_retargetable_locking=yes ;;
+   no)  newlib_retargetable_lock=no ;;
+   *) AC_MSG_ERROR(bad value ${enableval} for newlib-retargetable-locking) ;;
+ esac],[newlib_retargetable_locking=no])
+AM_CONDITIONAL(NEWLIB_RETARGETABLE_LOCKING, test x$newlib_retargetable_locking = xyes)
+
 NEWLIB_CONFIGURE(..)
 
 AM_CONDITIONAL(NEWLIB_NANO_MALLOC, test x$newlib_nano_malloc = xyes)
diff --git a/newlib/libc/include/sys/lock.h b/newlib/libc/include/sys/lock.h
index 9075e35c9179968031010432515e3a845ff6ca8d..2578f303c8e365bec1009e8614f207823ff78eb3 100644
--- a/newlib/libc/include/sys/lock.h
+++ b/newlib/libc/include/sys/lock.h
@@ -3,10 +3,13 @@
 
 /* dummy lock routines for single-threaded aps */
 
+#include <newlib.h>
+#include <_ansi.h>
+
+#ifndef _RETARGETABLE_LOCKING
+
 typedef int _LOCK_T;
 typedef int _LOCK_RECURSIVE_T;
- 
-#include <_ansi.h>
 
 #define __LOCK_INIT(class,lock) static int lock = 0;
 #define __LOCK_INIT_RECURSIVE(class,lock) static int lock = 0;
@@ -21,4 +24,26 @@ typedef int _LOCK_RECURSIVE_T;
 #define __lock_release(lock) (_CAST_VOID 0)
 #define __lock_release_recursive(lock) (_CAST_VOID 0)
 
+#else
+
+#include <stdint.h>
+
+typedef uintptr_t _LOCK_T;
+#define _LOCK_RECURSIVE_T _LOCK_T
+
+#define __LOCK_INIT(class,lock) class _LOCK_T lock = 0;
+#define __LOCK_INIT_RECURSIVE(class,lock) __LOCK_INIT(class,lock)
+extern void __lock_init(_LOCK_T lock);
+#define __lock_init_recursive(lock) __lock_init(lock)
+extern void __lock_close(_LOCK_T lock);
+#define __lock_close_recursive(lock) __lock_close(lock)
+extern void __lock_acquire(_LOCK_T lock);
+#define __lock_acquire_recursive(lock) __lock_acquire(lock)
+extern void __lock_try_acquire(_LOCK_T lock);
+#define __lock_try_acquire_recursive(lock) __lock_try_acquire(lock)
+extern void __lock_release(_LOCK_T lock);
+#define __lock_release_recursive(lock) __lock_release(lock)
+
+#endif /* _RETARGETABLE_LOCKING */
+
 #endif /* __SYS_LOCK_H__ */
diff --git a/newlib/libc/stdlib/Makefile.am b/newlib/libc/stdlib/Makefile.am
index 2d45d1029ace8087b57657cbc11feabf76f4206e..76ed8480c28ebfb68e2f48432c0359b11f1522a8 100644
--- a/newlib/libc/stdlib/Makefile.am
+++ b/newlib/libc/stdlib/Makefile.am
@@ -74,6 +74,11 @@ GENERAL_SOURCES += \
 	wcstold.c
 endif # HAVE_LONG_DOUBLE
 
+if NEWLIB_RETARGETABLE_LOCKING
+GENERAL_SOURCES += \
+	lock.c
+endif
+
 if NEWLIB_NANO_MALLOC
 MALIGNR=nano-malignr
 MALLOPTR=nano-malloptr
diff --git a/newlib/libc/stdlib/Makefile.in b/newlib/libc/stdlib/Makefile.in
index 466ab6d1e02ea919f6c8ceed792024955bef1a66..3295e981c87bac3b21a6b72dda148f892fe018d6 100644
--- a/newlib/libc/stdlib/Makefile.in
+++ b/newlib/libc/stdlib/Makefile.in
@@ -57,6 +57,9 @@ host_triplet = @host@
 @HAVE_LONG_DOUBLE_TRUE@	strtold.c \
 @HAVE_LONG_DOUBLE_TRUE@	wcstold.c
 
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@am__append_2 = \
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@	lock.c
+
 DIST_COMMON = $(srcdir)/../../Makefile.shared $(srcdir)/Makefile.in \
 	$(srcdir)/Makefile.am
 subdir = stdlib
@@ -81,7 +84,9 @@ lib_a_AR = $(AR) $(ARFLAGS)
 @ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(ELIX_2_OBJS)
 @HAVE_LONG_DOUBLE_TRUE@am__objects_1 = lib_a-strtold.$(OBJEXT) \
 @HAVE_LONG_DOUBLE_TRUE@	lib_a-wcstold.$(OBJEXT)
-am__objects_2 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@am__objects_2 =  \
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@	lib_a-lock.$(OBJEXT)
+am__objects_3 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \
 	lib_a-__call_atexit.$(OBJEXT) lib_a-__exp10.$(OBJEXT) \
 	lib_a-__ten_mu.$(OBJEXT) lib_a-_Exit.$(OBJEXT) \
 	lib_a-abort.$(OBJEXT) lib_a-abs.$(OBJEXT) \
@@ -112,8 +117,8 @@ am__objects_2 = lib_a-__adjust.$(OBJEXT) lib_a-__atexit.$(OBJEXT) \
 	lib_a-wcstol.$(OBJEXT) lib_a-wcstoul.$(OBJEXT) \
 	lib_a-wcstombs.$(OBJEXT) lib_a-wcstombs_r.$(OBJEXT) \
 	lib_a-wctomb.$(OBJEXT) lib_a-wctomb_r.$(OBJEXT) \
-	$(am__objects_1)
-am__objects_3 = lib_a-arc4random.$(OBJEXT) \
+	$(am__objects_1) $(am__objects_2)
+am__objects_4 = lib_a-arc4random.$(OBJEXT) \
 	lib_a-arc4random_uniform.$(OBJEXT) lib_a-cxa_atexit.$(OBJEXT) \
 	lib_a-cxa_finalize.$(OBJEXT) lib_a-drand48.$(OBJEXT) \
 	lib_a-ecvtbuf.$(OBJEXT) lib_a-efgcvt.$(OBJEXT) \
@@ -128,7 +133,7 @@ am__objects_3 = lib_a-arc4random.$(OBJEXT) \
 	lib_a-wcstoll_r.$(OBJEXT) lib_a-wcstoull.$(OBJEXT) \
 	lib_a-wcstoull_r.$(OBJEXT) lib_a-atoll.$(OBJEXT) \
 	lib_a-llabs.$(OBJEXT) lib_a-lldiv.$(OBJEXT)
-am__objects_4 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \
+am__objects_5 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \
 	lib_a-getopt.$(OBJEXT) lib_a-getsubopt.$(OBJEXT) \
 	lib_a-l64a.$(OBJEXT) lib_a-malign.$(OBJEXT) \
 	lib_a-mbrlen.$(OBJEXT) lib_a-mbrtowc.$(OBJEXT) \
@@ -137,22 +142,23 @@ am__objects_4 = lib_a-a64l.$(OBJEXT) lib_a-btowc.$(OBJEXT) \
 	lib_a-valloc.$(OBJEXT) lib_a-wcrtomb.$(OBJEXT) \
 	lib_a-wcsnrtombs.$(OBJEXT) lib_a-wcsrtombs.$(OBJEXT) \
 	lib_a-wctob.$(OBJEXT)
-am__objects_5 = lib_a-putenv.$(OBJEXT) lib_a-putenv_r.$(OBJEXT) \
+am__objects_6 = lib_a-putenv.$(OBJEXT) lib_a-putenv_r.$(OBJEXT) \
 	lib_a-setenv.$(OBJEXT) lib_a-setenv_r.$(OBJEXT)
-am__objects_6 = lib_a-rpmatch.$(OBJEXT) lib_a-system.$(OBJEXT)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_7 = $(am__objects_4) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_5) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_6)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_7 = $(am__objects_4) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_5)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_7 =  \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_4)
-@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_2) \
-@USE_LIBTOOL_FALSE@	$(am__objects_3) $(am__objects_7)
+am__objects_7 = lib_a-rpmatch.$(OBJEXT) lib_a-system.$(OBJEXT)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_8 = $(am__objects_5) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_6) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_7)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_8 = $(am__objects_5) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_6)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_8 =  \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_5)
+@USE_LIBTOOL_FALSE@am_lib_a_OBJECTS = $(am__objects_3) \
+@USE_LIBTOOL_FALSE@	$(am__objects_4) $(am__objects_8)
 lib_a_OBJECTS = $(am_lib_a_OBJECTS)
 LTLIBRARIES = $(noinst_LTLIBRARIES)
-@HAVE_LONG_DOUBLE_TRUE@am__objects_8 = strtold.lo wcstold.lo
-am__objects_9 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \
+@HAVE_LONG_DOUBLE_TRUE@am__objects_9 = strtold.lo wcstold.lo
+@NEWLIB_RETARGETABLE_LOCKING_TRUE@am__objects_10 = lock.lo
+am__objects_11 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \
 	__ten_mu.lo _Exit.lo abort.lo abs.lo aligned_alloc.lo \
 	assert.lo atexit.lo atof.lo atoff.lo atoi.lo atol.lo calloc.lo \
 	div.lo dtoa.lo dtoastub.lo environ.lo envlock.lo eprintf.lo \
@@ -163,28 +169,28 @@ am__objects_9 = __adjust.lo __atexit.lo __call_atexit.lo __exp10.lo \
 	rand_r.lo random.lo realloc.lo reallocf.lo sb_charsets.lo \
 	strtod.lo strtodg.lo strtol.lo strtorx.lo strtoul.lo utoa.lo \
 	wcstod.lo wcstol.lo wcstoul.lo wcstombs.lo wcstombs_r.lo \
-	wctomb.lo wctomb_r.lo $(am__objects_8)
-am__objects_10 = arc4random.lo arc4random_uniform.lo cxa_atexit.lo \
+	wctomb.lo wctomb_r.lo $(am__objects_9) $(am__objects_10)
+am__objects_12 = arc4random.lo arc4random_uniform.lo cxa_atexit.lo \
 	cxa_finalize.lo drand48.lo ecvtbuf.lo efgcvt.lo erand48.lo \
 	jrand48.lo lcong48.lo lrand48.lo mrand48.lo msize.lo mtrim.lo \
 	nrand48.lo rand48.lo seed48.lo srand48.lo strtoll.lo \
 	strtoll_r.lo strtoull.lo strtoull_r.lo wcstoll.lo wcstoll_r.lo \
 	wcstoull.lo wcstoull_r.lo atoll.lo llabs.lo lldiv.lo
-am__objects_11 = a64l.lo btowc.lo getopt.lo getsubopt.lo l64a.lo \
+am__objects_13 = a64l.lo btowc.lo getopt.lo getsubopt.lo l64a.lo \
 	malign.lo mbrlen.lo mbrtowc.lo mbsinit.lo mbsnrtowcs.lo \
 	mbsrtowcs.lo on_exit.lo valloc.lo wcrtomb.lo wcsnrtombs.lo \
 	wcsrtombs.lo wctob.lo
-am__objects_12 = putenv.lo putenv_r.lo setenv.lo setenv_r.lo
-am__objects_13 = rpmatch.lo system.lo
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_14 = $(am__objects_11) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_12) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_13)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_14 = $(am__objects_11) \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_12)
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_14 =  \
-@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_11)
-@USE_LIBTOOL_TRUE@am_libstdlib_la_OBJECTS = $(am__objects_9) \
-@USE_LIBTOOL_TRUE@	$(am__objects_10) $(am__objects_14)
+am__objects_14 = putenv.lo putenv_r.lo setenv.lo setenv_r.lo
+am__objects_15 = rpmatch.lo system.lo
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@am__objects_16 = $(am__objects_13) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_14) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@	$(am__objects_15)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@am__objects_16 = $(am__objects_13) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_TRUE@	$(am__objects_14)
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@am__objects_16 =  \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_TRUE@	$(am__objects_13)
+@USE_LIBTOOL_TRUE@am_libstdlib_la_OBJECTS = $(am__objects_11) \
+@USE_LIBTOOL_TRUE@	$(am__objects_12) $(am__objects_16)
 libstdlib_la_OBJECTS = $(am_libstdlib_la_OBJECTS)
 libstdlib_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -367,7 +373,7 @@ GENERAL_SOURCES = __adjust.c __atexit.c __call_atexit.c __exp10.c \
 	quick_exit.c rand.c rand_r.c random.c realloc.c reallocf.c \
 	sb_charsets.c strtod.c strtodg.c strtol.c strtorx.c strtoul.c \
 	utoa.c wcstod.c wcstol.c wcstoul.c wcstombs.c wcstombs_r.c \
-	wctomb.c wctomb_r.c $(am__append_1)
+	wctomb.c wctomb_r.c $(am__append_1) $(am__append_2)
 @NEWLIB_NANO_MALLOC_FALSE@MALIGNR = malignr
 @NEWLIB_NANO_MALLOC_TRUE@MALIGNR = nano-malignr
 @NEWLIB_NANO_MALLOC_FALSE@MALLOPTR = malloptr
@@ -1002,6 +1008,12 @@ lib_a-wcstold.o: wcstold.c
 lib_a-wcstold.obj: wcstold.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wcstold.obj `if test -f 'wcstold.c'; then $(CYGPATH_W) 'wcstold.c'; else $(CYGPATH_W) '$(srcdir)/wcstold.c'; fi`
 
+lib_a-lock.o: lock.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lock.o `test -f 'lock.c' || echo '$(srcdir)/'`lock.c
+
+lib_a-lock.obj: lock.c
+	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-lock.obj `if test -f 'lock.c'; then $(CYGPATH_W) 'lock.c'; else $(CYGPATH_W) '$(srcdir)/lock.c'; fi`
+
 lib_a-arc4random.o: arc4random.c
 	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-arc4random.o `test -f 'arc4random.c' || echo '$(srcdir)/'`arc4random.c
 
diff --git a/newlib/libc/stdlib/lock.c b/newlib/libc/stdlib/lock.c
new file mode 100644
index 0000000000000000000000000000000000000000..22366b01917e5dd5d79daaa65a6b2ae9ade98e7d
--- /dev/null
+++ b/newlib/libc/stdlib/lock.c
@@ -0,0 +1,73 @@
+/*
+FUNCTION
+<<__lock_init>>, <<__lock_close>>, <<__lock_acquire>>, <<__lock_try_acquire>>, <<__lock_release>>---locking routines
+
+INDEX
+	__lock_init
+INDEX
+	__lock_close
+INDEX
+	__lock_acquire
+INDEX
+	__lock_try_acquire
+INDEX
+	__lock_release
+
+ANSI_SYNOPSIS
+	#include <lock.h>
+	void __lock_init (_LOCK_T <[lock]>);
+	void __lock_close (_LOCK_T <[lock]>);
+	void __lock_acquire (_LOCK_T <[lock]>);
+	void __lock_try_acquire (_LOCK_T <[lock]>);
+	void __lock_release (_LOCK_T <[lock]>);
+
+TRAD_SYNOPSIS
+	void __lock_init(<[lock]>)
+	_LOCK_T <[lock]>;
+
+	void __lock_close(<[lock]>)
+	_LOCK_T <[lock]>;
+
+	void __lock_acquire(<[lock]>)
+	_LOCK_T <[lock]>;
+
+	void __lock_try_acquire(<[lock]>)
+	_LOCK_T <[lock]>;
+
+	void __lock_release(<[lock]>)
+	_LOCK_T <[lock]>;
+
+DESCRIPTION
+These empty functions are used for locking to allow applications to retarget
+them.  They are used in place of the default dummy lock macros when newlib
+is configured with --enable-newlib-retargetable-locking.
+*/
+
+/* dummy lock routines for single-threaded apps */
+
+#include <sys/lock.h>
+
+void _ATTRIBUTE((__weak__))
+__lock_init (_LOCK_T lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__lock_close(_LOCK_T lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__lock_acquire (_LOCK_T lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__lock_try_acquire(_LOCK_T lock)
+{
+}
+
+void _ATTRIBUTE((__weak__))
+__lock_release (_LOCK_T lock)
+{
+}
diff --git a/newlib/newlib.hin b/newlib/newlib.hin
index d03dfac0eea6a8917a92b8f0f3584c2cd42b9388..397bc9b96eafddace3a75be509157040654b6fde 100644
--- a/newlib/newlib.hin
+++ b/newlib/newlib.hin
@@ -82,6 +82,9 @@
 /* Define if small footprint nano-formatted-IO implementation used.  */
 #undef _NANO_FORMATTED_IO
 
+/* Define if using retargetable functions for default lock routines.  */
+#undef _RETARGETABLE_LOCKING
+
 /*
  * Iconv encodings enabled ("to" direction)
  */

^ permalink raw reply	[flat|nested] 51+ messages in thread

end of thread, other threads:[~2017-01-30 10:51 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-12-13 17:18 [PATCH, newlib] Allow locking routine to be retargeted Thomas Preudhomme
2016-12-13 20:13 ` Freddie Chopin
2016-12-14 11:54   ` Thomas Preudhomme
2016-12-14 12:39     ` Freddie Chopin
2017-01-11 13:09       ` Thomas Preudhomme
2016-12-13 21:11 ` Freddie Chopin
2016-12-13 21:41 ` Freddie Chopin
2016-12-14 14:22 ` Sebastian Huber
2016-12-14 14:36   ` Thomas Preudhomme
2016-12-14 14:52     ` Thomas Preudhomme
2017-01-09 18:49       ` Freddie Chopin
2017-01-10 16:50         ` Thomas Preudhomme
2017-01-10 17:07           ` Freddie Chopin
2017-01-11 16:09             ` Thomas Preudhomme
2017-01-11 16:46               ` Craig Howland
2017-01-11 17:48                 ` Thomas Preudhomme
2017-01-11 18:08                   ` Craig Howland
2017-01-11 19:14                   ` Freddie Chopin
2017-01-12 10:52                     ` Thomas Preudhomme
2017-01-12 16:20                       ` Freddie Chopin
2017-01-12 16:55                         ` Thomas Preudhomme
2017-01-13 11:25                           ` Thomas Preudhomme
2017-01-13 13:24                             ` Thomas Preudhomme
2017-01-13 18:05                               ` Freddie Chopin
2017-01-13 18:16                                 ` Thomas Preudhomme
2017-01-16 15:59                                   ` Thomas Preudhomme
2017-01-20 13:37                                     ` Thomas Preudhomme
2017-01-20 13:55                                       ` Freddie Chopin
2017-01-24 10:00                                       ` Freddie Chopin
2017-01-25 12:31                                         ` Corinna Vinschen
2017-01-30 10:51                                         ` Thomas Preudhomme
2016-12-14 15:27     ` Freddie Chopin
  -- strict thread matches above, loose matches on Subject: below --
2016-11-10 14:42 Thomas Preudhomme
2016-11-10 15:34 ` Freddie Chopin
2016-11-10 16:05   ` Thomas Preudhomme
2016-11-10 20:32     ` Freddie Chopin
2016-11-10 20:35       ` Freddie Chopin
2016-11-11 11:09       ` Thomas Preudhomme
2016-11-11 11:54         ` Freddie Chopin
2016-11-11 11:56         ` Sebastian Huber
2016-11-11 13:40           ` Thomas Preudhomme
2016-11-11 14:10             ` Freddie Chopin
2016-11-23 14:38           ` Thomas Preudhomme
2016-11-23 15:52             ` Freddie Chopin
2016-11-24  7:44             ` Sebastian Huber
2016-11-24  8:29               ` Freddie Chopin
2016-11-25 10:21               ` Thomas Preudhomme
2016-11-25 12:04                 ` Thomas Preudhomme
2016-11-25 12:35                   ` Sebastian Huber
2016-12-13 17:20                     ` Thomas Preudhomme
2016-11-25 14:12                   ` Freddie Chopin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).