Can't build libpthread for M3

Submitted by sposelenov@emcraft.com on Oct. 22, 2014, 10:11 a.m.

Details

Message ID 20141022141126.3e6849ec@skywanderer.emcraft.com
State New
Headers show

Commit Message

sposelenov@emcraft.com Oct. 22, 2014, 10:11 a.m.
Hello,

On Thu, 9 Oct 2014 23:29:01 +0300
Andrii <bearrailgun@gmail.com> wrote:

> I'm trying to build uClibc for Cortex-M3 LPC17XX with codesourcery
> g++ lite arm2010q1(189) toolchain.
> I've tried 0.9.30.3, 0.9.33.2 and latest git a9bdc5d2 with almost same
> results.
> Here is the output from latest git:
> 
> When trying to build with old linuxthreads:
>   CC libpthread/linuxthreads.old/mutex.os
> /tmp/ccB7JHC6.s: Assembler messages:
> /tmp/ccB7JHC6.s:29: Error: selected processor does not support ARM
> opcodes /tmp/ccB7JHC6.s:30: Error: attempt to use an ARM instruction
> on a Thumb-only processor -- `swp r3,r3,[r0]'
> /tmp/ccB7JHC6.s:31: Error: attempt to use an ARM instruction on a
> Thumb-only processor -- `orr r0,pc,#1'
> /tmp/ccB7JHC6.s:32: Error: attempt to use an ARM instruction on a
> Thumb-only processor -- `bx r0'
> /tmp/ccB7JHC6.s:58: Error: selected processor does not support ARM
> opcodes /tmp/ccB7JHC6.s:59: Error: attempt to use an ARM instruction
> on a Thumb-only processor -- `swp r2,r2,[r0]'
> /tmp/ccB7JHC6.s:60: Error: attempt to use an ARM instruction on a
> Thumb-only processor -- `orr r0,pc,#1'
> /tmp/ccB7JHC6.s:61: Error: attempt to use an ARM instruction on a
> Thumb-only processor -- `bx r0'
> make: *** [libpthread/linuxthreads.old/mutex.os] Error 1
> 
> New linux threads:
>   CC libpthread/linuxthreads/sysdeps/arm/pspinlock.os
> In file included from ./libpthread/linuxthreads/descr.h:46,
>                  from ./libpthread/linuxthreads/internals.h:36,
>                  from
> libpthread/linuxthreads/sysdeps/arm/pspinlock.c:21: ./libpthread/linuxthreads/sysdeps/arm/pt-machine.h:36:
> warning: no previous prototype for 'testandset'
> /tmp/cczGDaGC.s: Assembler messages:
> /tmp/cczGDaGC.s:27: Error: selected processor does not support Thumb
> mode `swp r3,r3,[r0]'
> /tmp/cczGDaGC.s:46: Error: selected processor does not support Thumb
> mode `swp r3,r3,[r0]'
> make: *** [libpthread/linuxthreads/sysdeps/arm/pspinlock.os] Error 1
> 
> NPTL:
> -----
>   CC libpthread/nptl/pthread_atfork.os
>   AS libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-vfork.os
> libpthread/nptl/sysdeps/unix/sysv/linux/arm/../../../../../../../libc/sysdeps/linux/arm/vfork.S:
> Assembler messages:
> libpthread/nptl/sysdeps/unix/sysv/linux/arm/../../../../../../../libc/sysdeps/linux/arm/vfork.S:72:
> Error: only SUBS PC, LR, #const allowed -- `sub pc,r0,#31'
> libpthread/nptl/sysdeps/unix/sysv/linux/arm/../../../../../../../libc/sysdeps/linux/arm/vfork.S:74:
> Error: thumb conditional instruction should be in IT block -- `strne
> r3,[r2,#-1044]'
> make: *** [libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-vfork.os]
> Error 1
> 
> Extra CFLAGS :
> march=armv7-m -mthumb -Wl, -elf2flt -Wa, -march=armv7-m -Wa, -mthumb
> 
> As I undestand thumb2 doesn't support swp instruction. But is there a
> way to avoid hardcoded swp instructions in threads code (spinlock
> implementation)?
> 
Uclibc (still) lacks pthreads support on Cortex-M3.

I'm attaching two patches:
 - implement testandset() for Cortex-M3.
 - Fix a bug in implementation of clone() for Cortex-M3.

That should make pthreads work. Note also that we are building the
"linuxthreads.old" pthreads configuration.


Regards,

Sergei Poselenov,
Emcraft Systems
> Regards.
> _______________________________________________
> uClibc mailing list
> uClibc@uclibc.org
> http://lists.busybox.net/mailman/listinfo/uclibc

Comments

Andrii Oct. 22, 2014, 5:53 p.m.
Thanks for the patches!

I've tried to apply both on uClibc-0.9.33.2 (latest official release).
uclibc-cm3-clone.patch was applied just well.
But I was not able to apply uclibc-cm3-testandset.patch correctly:
In libpthread/linuxthreads.old/sysdeps/arm/pt-machine.h
I don't have next lines:
-  int unused = 0;
-  return INTERNAL_SYSCALL_ARM (atomicops, , 4, SYS_ARM_ATOMIC_SET,
-                         spinlock, 1, unused);
But rest seems the same.
So I fixed it manually by copying ldrex/strex and testandset functions.
This patch also creates dot_config_pthreads-no-ldrex which I used to build
uclibc (also I enabled the USE_LDREXSTREX=y)

The result is next (In app just usual pthread_create() used without any
other pthread calls) :
# ./the_app
00026 : pthread_initialize: initial thread stack bounds: bos=0x1,
tos=0xffffffff
the_app started. version 6.76_threads
Starting sensor simulation thread
00026 : __pthread_initialize_manager: manager stack: size=8160,
bos=0xa0696008, tos=0xa0697fe8
00026 : __pthread_initialize_manager: send REQ_DEBUG to manager thread
00026 : pthread_create: write REQ_CREATE to manager thread
00026 : pthread_create: before suspend(self)
[   18.810000]
[   18.810000]
[   18.810000] the_app: unhandled MPU fault (0x08) at 0x00000000
[pc=0xa0583ea8,sp=0xa0697fc0]
[   18.810000]

Actually I have same results on latest uclibc git without fixing clone
patch but with ldrex/strex fix.

Any suggestions are welcome.

Regards.



On Wed, Oct 22, 2014 at 1:11 PM, Sergei Poselenov <sposelenov@emcraft.com>
wrote:

> Hello,
>
> On Thu, 9 Oct 2014 23:29:01 +0300
> Andrii <bearrailgun@gmail.com> wrote:
>
> > I'm trying to build uClibc for Cortex-M3 LPC17XX with codesourcery
> > g++ lite arm2010q1(189) toolchain.
> > I've tried 0.9.30.3, 0.9.33.2 and latest git a9bdc5d2 with almost same
> > results.
> > Here is the output from latest git:
> >
> > When trying to build with old linuxthreads:
> >   CC libpthread/linuxthreads.old/mutex.os
> > /tmp/ccB7JHC6.s: Assembler messages:
> > /tmp/ccB7JHC6.s:29: Error: selected processor does not support ARM
> > opcodes /tmp/ccB7JHC6.s:30: Error: attempt to use an ARM instruction
> > on a Thumb-only processor -- `swp r3,r3,[r0]'
> > /tmp/ccB7JHC6.s:31: Error: attempt to use an ARM instruction on a
> > Thumb-only processor -- `orr r0,pc,#1'
> > /tmp/ccB7JHC6.s:32: Error: attempt to use an ARM instruction on a
> > Thumb-only processor -- `bx r0'
> > /tmp/ccB7JHC6.s:58: Error: selected processor does not support ARM
> > opcodes /tmp/ccB7JHC6.s:59: Error: attempt to use an ARM instruction
> > on a Thumb-only processor -- `swp r2,r2,[r0]'
> > /tmp/ccB7JHC6.s:60: Error: attempt to use an ARM instruction on a
> > Thumb-only processor -- `orr r0,pc,#1'
> > /tmp/ccB7JHC6.s:61: Error: attempt to use an ARM instruction on a
> > Thumb-only processor -- `bx r0'
> > make: *** [libpthread/linuxthreads.old/mutex.os] Error 1
> >
> > New linux threads:
> >   CC libpthread/linuxthreads/sysdeps/arm/pspinlock.os
> > In file included from ./libpthread/linuxthreads/descr.h:46,
> >                  from ./libpthread/linuxthreads/internals.h:36,
> >                  from
> > libpthread/linuxthreads/sysdeps/arm/pspinlock.c:21:
> ./libpthread/linuxthreads/sysdeps/arm/pt-machine.h:36:
> > warning: no previous prototype for 'testandset'
> > /tmp/cczGDaGC.s: Assembler messages:
> > /tmp/cczGDaGC.s:27: Error: selected processor does not support Thumb
> > mode `swp r3,r3,[r0]'
> > /tmp/cczGDaGC.s:46: Error: selected processor does not support Thumb
> > mode `swp r3,r3,[r0]'
> > make: *** [libpthread/linuxthreads/sysdeps/arm/pspinlock.os] Error 1
> >
> > NPTL:
> > -----
> >   CC libpthread/nptl/pthread_atfork.os
> >   AS libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-vfork.os
> >
> libpthread/nptl/sysdeps/unix/sysv/linux/arm/../../../../../../../libc/sysdeps/linux/arm/vfork.S:
> > Assembler messages:
> >
> libpthread/nptl/sysdeps/unix/sysv/linux/arm/../../../../../../../libc/sysdeps/linux/arm/vfork.S:72:
> > Error: only SUBS PC, LR, #const allowed -- `sub pc,r0,#31'
> >
> libpthread/nptl/sysdeps/unix/sysv/linux/arm/../../../../../../../libc/sysdeps/linux/arm/vfork.S:74:
> > Error: thumb conditional instruction should be in IT block -- `strne
> > r3,[r2,#-1044]'
> > make: *** [libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-vfork.os]
> > Error 1
> >
> > Extra CFLAGS :
> > march=armv7-m -mthumb -Wl, -elf2flt -Wa, -march=armv7-m -Wa, -mthumb
> >
> > As I undestand thumb2 doesn't support swp instruction. But is there a
> > way to avoid hardcoded swp instructions in threads code (spinlock
> > implementation)?
> >
> Uclibc (still) lacks pthreads support on Cortex-M3.
>
> I'm attaching two patches:
>  - implement testandset() for Cortex-M3.
>  - Fix a bug in implementation of clone() for Cortex-M3.
>
> That should make pthreads work. Note also that we are building the
> "linuxthreads.old" pthreads configuration.
>
>
> Regards,
>
> Sergei Poselenov,
> Emcraft Systems
> > Regards.
> > _______________________________________________
> > uClibc mailing list
> > uClibc@uclibc.org
> > http://lists.busybox.net/mailman/listinfo/uclibc
>
>
sposelenov@emcraft.com Oct. 23, 2014, 9:45 a.m.
Hello,

On Wed, 22 Oct 2014 20:53:52 +0300
Andrii <bearrailgun@gmail.com> wrote:

> Thanks for the patches!
> 
> I've tried to apply both on uClibc-0.9.33.2 (latest official release).
> uclibc-cm3-clone.patch was applied just well.
> But I was not able to apply uclibc-cm3-testandset.patch correctly:
> In libpthread/linuxthreads.old/sysdeps/arm/pt-machine.h
> I don't have next lines:
> -  int unused = 0;
> -  return INTERNAL_SYSCALL_ARM (atomicops, , 4, SYS_ARM_ATOMIC_SET,
> -                         spinlock, 1, unused);

Yes, just skip that part of the patch.

> But rest seems the same.
> So I fixed it manually by copying ldrex/strex and testandset
> functions. This patch also creates dot_config_pthreads-no-ldrex which
> I used to build uclibc (also I enabled the USE_LDREXSTREX=y)
> 

Correct.

> The result is next (In app just usual pthread_create() used without
> any other pthread calls) :
> # ./the_app
> 00026 : pthread_initialize: initial thread stack bounds: bos=0x1,
> tos=0xffffffff
> the_app started. version 6.76_threads
> Starting sensor simulation thread
> 00026 : __pthread_initialize_manager: manager stack: size=8160,
> bos=0xa0696008, tos=0xa0697fe8
> 00026 : __pthread_initialize_manager: send REQ_DEBUG to manager thread
> 00026 : pthread_create: write REQ_CREATE to manager thread
> 00026 : pthread_create: before suspend(self)
> [   18.810000]
> [   18.810000]
> [   18.810000] the_app: unhandled MPU fault (0x08) at 0x00000000
> [pc=0xa0583ea8,sp=0xa0697fc0]
> [   18.810000]
> 
> Actually I have same results on latest uclibc git without fixing clone
> patch but with ldrex/strex fix.
> 
> Any suggestions are welcome.
> 

Looks like your build flags are not optimal for Cortex-M3. You are
building as "march=armv7-m -mthumb".
Try:
make -s ARCH_CFLAGS= 'CPU_CFLAGS=-mthumb -march=armv7 -mfix-cortex-m3-ldrd'

Also, make sure your application doesn't use big arrays located in stack.
By default, stack size is only 4K for the Cortex-M applications.
See arm-uclinuxeabi-flthdr utility to display and change the stack size.

Regards,

Sergei
> Regards.
> 
> 
> 
> On Wed, Oct 22, 2014 at 1:11 PM, Sergei Poselenov
> <sposelenov@emcraft.com> wrote:
> 
> > Hello,
> >
> > On Thu, 9 Oct 2014 23:29:01 +0300
> > Andrii <bearrailgun@gmail.com> wrote:
> >
> > > I'm trying to build uClibc for Cortex-M3 LPC17XX with codesourcery
> > > g++ lite arm2010q1(189) toolchain.
> > > I've tried 0.9.30.3, 0.9.33.2 and latest git a9bdc5d2 with almost
> > > same results.
> > > Here is the output from latest git:
> > >
> > > When trying to build with old linuxthreads:
> > >   CC libpthread/linuxthreads.old/mutex.os
> > > /tmp/ccB7JHC6.s: Assembler messages:
> > > /tmp/ccB7JHC6.s:29: Error: selected processor does not support ARM
> > > opcodes /tmp/ccB7JHC6.s:30: Error: attempt to use an ARM
> > > instruction on a Thumb-only processor -- `swp r3,r3,[r0]'
> > > /tmp/ccB7JHC6.s:31: Error: attempt to use an ARM instruction on a
> > > Thumb-only processor -- `orr r0,pc,#1'
> > > /tmp/ccB7JHC6.s:32: Error: attempt to use an ARM instruction on a
> > > Thumb-only processor -- `bx r0'
> > > /tmp/ccB7JHC6.s:58: Error: selected processor does not support ARM
> > > opcodes /tmp/ccB7JHC6.s:59: Error: attempt to use an ARM
> > > instruction on a Thumb-only processor -- `swp r2,r2,[r0]'
> > > /tmp/ccB7JHC6.s:60: Error: attempt to use an ARM instruction on a
> > > Thumb-only processor -- `orr r0,pc,#1'
> > > /tmp/ccB7JHC6.s:61: Error: attempt to use an ARM instruction on a
> > > Thumb-only processor -- `bx r0'
> > > make: *** [libpthread/linuxthreads.old/mutex.os] Error 1
> > >
> > > New linux threads:
> > >   CC libpthread/linuxthreads/sysdeps/arm/pspinlock.os
> > > In file included from ./libpthread/linuxthreads/descr.h:46,
> > >                  from ./libpthread/linuxthreads/internals.h:36,
> > >                  from
> > > libpthread/linuxthreads/sysdeps/arm/pspinlock.c:21:
> > ./libpthread/linuxthreads/sysdeps/arm/pt-machine.h:36:
> > > warning: no previous prototype for 'testandset'
> > > /tmp/cczGDaGC.s: Assembler messages:
> > > /tmp/cczGDaGC.s:27: Error: selected processor does not support
> > > Thumb mode `swp r3,r3,[r0]'
> > > /tmp/cczGDaGC.s:46: Error: selected processor does not support
> > > Thumb mode `swp r3,r3,[r0]'
> > > make: *** [libpthread/linuxthreads/sysdeps/arm/pspinlock.os]
> > > Error 1
> > >
> > > NPTL:
> > > -----
> > >   CC libpthread/nptl/pthread_atfork.os
> > >   AS libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-vfork.os
> > >
> > libpthread/nptl/sysdeps/unix/sysv/linux/arm/../../../../../../../libc/sysdeps/linux/arm/vfork.S:
> > > Assembler messages:
> > >
> > libpthread/nptl/sysdeps/unix/sysv/linux/arm/../../../../../../../libc/sysdeps/linux/arm/vfork.S:72:
> > > Error: only SUBS PC, LR, #const allowed -- `sub pc,r0,#31'
> > >
> > libpthread/nptl/sysdeps/unix/sysv/linux/arm/../../../../../../../libc/sysdeps/linux/arm/vfork.S:74:
> > > Error: thumb conditional instruction should be in IT block --
> > > `strne r3,[r2,#-1044]'
> > > make: ***
> > > [libpthread/nptl/sysdeps/unix/sysv/linux/arm/pt-vfork.os] Error 1
> > >
> > > Extra CFLAGS :
> > > march=armv7-m -mthumb -Wl, -elf2flt -Wa, -march=armv7-m -Wa,
> > > -mthumb
> > >
> > > As I undestand thumb2 doesn't support swp instruction. But is
> > > there a way to avoid hardcoded swp instructions in threads code
> > > (spinlock implementation)?
> > >
> > Uclibc (still) lacks pthreads support on Cortex-M3.
> >
> > I'm attaching two patches:
> >  - implement testandset() for Cortex-M3.
> >  - Fix a bug in implementation of clone() for Cortex-M3.
> >
> > That should make pthreads work. Note also that we are building the
> > "linuxthreads.old" pthreads configuration.
> >
> >
> > Regards,
> >
> > Sergei Poselenov,
> > Emcraft Systems
> > > Regards.
> > > _______________________________________________
> > > uClibc mailing list
> > > uClibc@uclibc.org
> > > http://lists.busybox.net/mailman/listinfo/uclibc
> >
> >
aldot Oct. 23, 2014, 3:25 p.m.
On 22 October 2014 12:11:26 CEST, Sergei Poselenov <sposelenov@emcraft.com> wrote:
>Hello,
>

>Uclibc (still) lacks pthreads support on Cortex-M3.
>
>I'm attaching two patches:
> - implement testandset() for Cortex-M3.
> - Fix a bug in implementation of clone() for Cortex-M3.

Can you please send the two patches with appropriate signed-off-by lines?

TIA,
Andrii Oct. 23, 2014, 10:50 p.m.
I tried to build a very simple app which just calls pthread_create() and
prints debugs. And I could say it works.
0.9.33.2 release + 2 patches from emcraft and 1 more fix for compilation.
So If someone needs uclibc with threads
for M3 - it could be downloaded here:
https://github.com/repu1sion/uclibc
(not an advertisement - just hope it will solve someone's problem).
It was built with
make ARCH_CFLAGS= 'CPU_CFLAGS=-mthumb -march=armv7 -mfix-cortex-m3-ldrd'
as Sergei said but I think its not about flags but about complicated app I
tried to run before and some issues with
mem allocations (not stack size. stack size was changed
with arm-uclinuxeabi-flthdr to 32Kb and was enough when running without
threads)

/opt # ./zpm_thread
00033 : pthread_initialize: initial thread stack bounds: bos=0x1,
tos=0xffffffff
app started. v1
00033 : __pthread_initialize_manager: manager stack: size=8160,
bos=0xa0018008, tos=0xa0019fe8
00033 : __pthread_initialize_manager: send REQ_DEBUG to manager thread
00034 : __pthread_manager: before poll
00033 : pthread_create: write REQ_CREATE to manager thread
00034 : __pthread_manager: after poll
00034 : __pthread_manager: before read
00034 : __pthread_manager: after read, n=28
00034 : __pthread_manager: got REQ_CREATE
00033 : pthread_create: before suspend(self)
00034 : pthread_allocate_stack: malloced chunk: base=0xa0278008, size=0x4000
00034 : pthread_allocate_stack: thread stack: bos=0xa0278008, tos=0xa027bea8
00034 : pthread_allocate_stack: initial stack: bos=0xa0019fe8,
tos=0xa0278008
00034 : pthread_handle_create: cloning new_thread = 0xa027bea8
00034 : pthread_handle_create: new thread pid = 35
00035 : pthread_start_thread:
new thread created
thread
00034 : __pthread_manager: restarting 0xa004ddd0
00033 : pthread_create: after suspend(self)
app
00034 : __pthread_manager: before poll
thread
app

Thanks for the help!


On Thu, Oct 23, 2014 at 6:25 PM, Bernhard Reutner-Fischer <
rep.dot.nop@gmail.com> wrote:

> On 22 October 2014 12:11:26 CEST, Sergei Poselenov <sposelenov@emcraft.com>
> wrote:
> >Hello,
> >
>
> >Uclibc (still) lacks pthreads support on Cortex-M3.
> >
> >I'm attaching two patches:
> > - implement testandset() for Cortex-M3.
> > - Fix a bug in implementation of clone() for Cortex-M3.
>
> Can you please send the two patches with appropriate signed-off-by lines?
>
> TIA,
>
>
Andrii Oct. 30, 2014, 12:01 p.m.
After some tests it seems that linuxthreads doesn't work stable (on 0.9.33.2
release + 2 patches from emcraft)
2 simple threads work well, but when I try to create more complicated app
with few more (4 for example)
I have constant crashes during malloc of mem for a new thread' stack.
Seems like it crashes here:
pthread_allocate_stack()->malloc()->__heap_free()->__heap_add_free_area()

Here is the example of log:
00032 : __pthread_initialize_manager: send REQ_DEBUG to manager thread
00032 : pthread_create: write REQ_CREATE to manager thread
00033 : __pthread_manager: before poll
00033 : __pthread_manager: after poll
00033 : __pthread_manager: before read
00033 : __pthread_manager: after read, n=28
00033 : __pthread_manager: got REQ_CREATE
00033 : pthread_allocate_stack: BEGIN
00033 : pthread_allocate_stack: HAVE NO MMU
00032 : pthread_create: before suspend(self)
00033 : pthread_allocate_stack: SETTING STACK SIZE
00033 : pthread_allocate_stack: BEFORE MALLOC. SIZE: 16384
malloc: 16384 bytes
   before __heap_alloc: heap @0xa000dff4:
      0xa000dff4:  0xa000d148 - 0xa000e000  (3768)      P=0x0, N=0xa0054464
      0xa0054464:  0xa0054370 - 0xa0054470  (256)       P=0xa000dff4, N=0x0
   after __heap_alloc: heap @0xa000dff4:
      0xa000dff4:  0xa000d148 - 0xa000e000  (3768)      P=0x0, N=0xa0054464
      0xa0054464:  0xa0054370 - 0xa0054470  (256)       P=0xa000dff4, N=0x0
   adding system memory to heap: 0xa0088000 - 0xa008d000 (20480 bytes)
      before __heap_free: heap @0xa000dff4:
         0xa000dff4:  0xa000d148 - 0xa000e000  (3768)   P=0x0, N=0xa0054464
         0xa0054464:  0xa0054370 - 0xa0054470  (256)    P=0xa000dff4, N=0x0
      __heap_free debug1: heap @0xa000dff4:
         0xa000dff4:  0xa000d148 - 0xa000e000  (3768)   P=0x0, N=0xa0054464
         0xa0054464:  0xa0054370 - 0xa0054470  (256)    P=0xa000dff4, N=0x0
      __heap_free debug4: heap @0xa000dff4:
         0xa000dff4:  0xa000d148 - 0xa000e000  (3768)   P=0x0, N=0xa0054464
         0xa0054464:  0xa0054370 - 0xa0054470  (256)    P=0xa000dff4, N=0x0
      __heap_add_free_area debug1: heap @0xa000dff4:
         0xa000dff4:  0xa000d148 - 0xa000e000  (3768)   P=0x0, N=0xa0054464
         0xa0054464:  0xa0054370 - 0xa0054470  (256)    P=0xa000dff4, N=0x0
[   66.630000]
[   66.630000] zpm_thread: unhandled MPU fault (0x08) at 0x00000000
[pc=0xa004545a,sp=0xa001df18]
[   66.630000]

Seems like magic.
I tested malloc allocations with allocating like 100 chunks for 16-20Kb and
everything works well.
I also compared malloc from 0.9.33.2 with latest one from git and found no
any significant changes,
so I don't think there is a malloc bug.
It doesn't look like stack overflow either because main app has 32Kb and
every thread has 16Kb stack.
Maybe something is still wrong exactly with cloning and stack allocation
for thread?
Also I have an idea that maybe locks doesn't work well... Is it still
contiguous with ldrex/strex? But this is less
possible as I have only one hardware cpu thread on M3 ;)

Regards.









On Fri, Oct 24, 2014 at 1:50 AM, Andrii <bearrailgun@gmail.com> wrote:

> I tried to build a very simple app which just calls pthread_create() and
> prints debugs. And I could say it works.
> 0.9.33.2 release + 2 patches from emcraft and 1 more fix for compilation.
> So If someone needs uclibc with threads
> for M3 - it could be downloaded here:
> https://github.com/repu1sion/uclibc
> (not an advertisement - just hope it will solve someone's problem).
> It was built with
> make ARCH_CFLAGS= 'CPU_CFLAGS=-mthumb -march=armv7 -mfix-cortex-m3-ldrd'
> as Sergei said but I think its not about flags but about complicated app I
> tried to run before and some issues with
> mem allocations (not stack size. stack size was changed
> with arm-uclinuxeabi-flthdr to 32Kb and was enough when running without
> threads)
>
> /opt # ./zpm_thread
> 00033 : pthread_initialize: initial thread stack bounds: bos=0x1,
> tos=0xffffffff
> app started. v1
> 00033 : __pthread_initialize_manager: manager stack: size=8160,
> bos=0xa0018008, tos=0xa0019fe8
> 00033 : __pthread_initialize_manager: send REQ_DEBUG to manager thread
> 00034 : __pthread_manager: before poll
> 00033 : pthread_create: write REQ_CREATE to manager thread
> 00034 : __pthread_manager: after poll
> 00034 : __pthread_manager: before read
> 00034 : __pthread_manager: after read, n=28
> 00034 : __pthread_manager: got REQ_CREATE
> 00033 : pthread_create: before suspend(self)
> 00034 : pthread_allocate_stack: malloced chunk: base=0xa0278008,
> size=0x4000
> 00034 : pthread_allocate_stack: thread stack: bos=0xa0278008,
> tos=0xa027bea8
> 00034 : pthread_allocate_stack: initial stack: bos=0xa0019fe8,
> tos=0xa0278008
> 00034 : pthread_handle_create: cloning new_thread = 0xa027bea8
> 00034 : pthread_handle_create: new thread pid = 35
> 00035 : pthread_start_thread:
> new thread created
> thread
> 00034 : __pthread_manager: restarting 0xa004ddd0
> 00033 : pthread_create: after suspend(self)
> app
> 00034 : __pthread_manager: before poll
> thread
> app
>
> Thanks for the help!
>
>
> On Thu, Oct 23, 2014 at 6:25 PM, Bernhard Reutner-Fischer <
> rep.dot.nop@gmail.com> wrote:
>
>> On 22 October 2014 12:11:26 CEST, Sergei Poselenov <
>> sposelenov@emcraft.com> wrote:
>> >Hello,
>> >
>>
>> >Uclibc (still) lacks pthreads support on Cortex-M3.
>> >
>> >I'm attaching two patches:
>> > - implement testandset() for Cortex-M3.
>> > - Fix a bug in implementation of clone() for Cortex-M3.
>>
>> Can you please send the two patches with appropriate signed-off-by lines?
>>
>> TIA,
>>
>>
>
sposelenov@emcraft.com Nov. 1, 2014, 8:52 a.m.
Hello,

On Thu, 2014-10-23 at 17:25 +0200, Bernhard Reutner-Fischer wrote:
> On 22 October 2014 12:11:26 CEST, Sergei Poselenov <sposelenov@emcraft.com> wrote:
> >Hello,
> >
> 
> >Uclibc (still) lacks pthreads support on Cortex-M3.
> >
> >I'm attaching two patches:
> > - implement testandset() for Cortex-M3.
> > - Fix a bug in implementation of clone() for Cortex-M3.
> 
> Can you please send the two patches with appropriate signed-off-by lines?

I'm sending the patches made against the pristine 0.9.33.2 in the next
emails. Note that the changes may be not quite portable, feel free to
modify them.

Regards,

Sergei
> TIA,
>
Andrii Nov. 3, 2014, 3:53 p.m.
I've tried to apply Sergei' 3 patches to the original 0.9.33.2 and run test
app on it.
Still got a crash:

/ # /opt/zpm_thread
00032 : pthread_initialize: initial thread stack bounds: bos=0x1,
tos=0xffffffff
00032 : __pthread_initialize_manager: manager stack: size=8160,
bos=0xa00a2008, tos=0xa00a3fe8
00032 : __pthread_initialize_manager: send REQ_DEBUG to manager thread
00032 : pthread_create: write REQ_CREATE to manager thread
00032 : pthread_create: before suspend(self)
00033 : __pthread_manager: before poll
00033 : __pthread_manager: after poll
00033 : __pthread_manager: before read
00033 : __pthread_manager: after read, n=28
00033 : __pthread_manager: got REQ_CREATE
00033 : pthread_allocate_stack: malloced chunk: base=0xa00a8008, size=0x4000
00033 : pthread_allocate_stack: thread stack: bos=0xa00a8008, tos=0xa00abea8
00033 : pthread_allocate_stack: initial stack: bos=0x1, tos=0xa00a2008
00033 : pthread_handle_create: cloning new_thread = 0xa00abea8
00033 : pthread_handle_create: new thread pid = 34
00033 : __pthread_manager: restarting 0xa008e8d0
00032 : pthread_create: after suspend(self)
thread #0 created
00033 : __pthread_manager: before poll
00034 : pthread_start_thread:
new thread 1 executed.
00032 : pthread_create: write REQ_CREATE to manager thread
00032 : pthread_create: before suspend(self)
00033 : __pthread_manager: after poll
00033 : __pthread_manager: before read
00033 : __pthread_manager: after read, n=28
00033 : __pthread_manager: got REQ_CREATE
00033 : pthread_allocate_stack: malloced chunk: base=0xa03d8008, size=0x4000
00033 : pthread_allocate_stack: thread stack: bos=0xa03d8008, tos=0xa03dbea8
00033 : pthread_allocate_stack: initial stack: bos=0x1, tos=0xa00a2008
00033 : pthread_handle_create: cloning new_thread = 0xa03dbea8
00033 : pthread_handle_create: new thread pid = 35
00033 : __pthread_manager: restarting 0xa008e8d0
00033 : __pthread_manager: before poll
00035 : pthread_start_thread:
new thread 1 executed.
00032 : pthread_create: after suspend(self)
thread #1 created
00032 : pthread_create: write REQ_CREATE to manager thread
00033 : __pthread_manager: after poll
00033 : __pthread_manager: before read
00033 : __pthread_manager: after read, n=28
00033 : __pthread_manager: got REQ_CREATE
00032 : pthread_create: before suspend(self)

[   12.390000]
[   12.390000] zpm_thread: unhandled MPU fault (0x08) at 0x00000000
[pc=0xa0084c74,sp=0xa00a3f20]
[   12.390000]
[   12.390000] Pid: 33, comm:           zpm_thread
[   12.390000] CPU: 0    Not tainted  (2.6.33-arm1 #2)
[   12.390000] pc : [<a0084c74>]    lr : [<a008478f>]    psr: 21000000
[   12.390000] sp : a00a3f20  ip : 5220746f  fp : 00000803
[   12.390000] Code dump at pc [a0084c74]:
[   12.390000] a003f848 463b4621 ff98f7ff 681b4b04
[   12.390000] r10: 00005000  r9 : 00000003  r8 : a0020000
[   12.390000] r7 : a0092f04  r6 : 00000100  r5 : a0092e0c  r4 : a0024ff4
[   12.390000] r3 : 00004ff4  r2 : 00000000  r1 : a0092e10  r0 : a0092e0c
[   12.390000] Flags: nzCv  IRQs on  FIQs on  Mode USER_26  ISA unknown
 Segment user
[   12.390000] Backtrace: invalid frame pointer 0x00000803

From my observations it crashes in malloc() during allocation of 16Kb stack
for a new thread while trying to find and link a new free area.

Here is the app code. It's trivial:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>

#define NUM_THREADS 10

pthread_t thread[NUM_THREADS] = {0};
int thread_cnt = 0;

void* start_routine(void *arg)
{
        printf("new thread %d executed.\n", thread_cnt);
        while(1)
        {
                sleep(1);
        }
}

void main()
{
        int i;
        int rv;

        for (i = 0; i < NUM_THREADS; i++)
        {
                rv = pthread_create(&thread[thread_cnt], NULL,
start_routine, NULL);
                if (rv)
                        printf("<error> thread was not created! Error num
is : %d\n", rv);
                printf("thread #%d created \n", thread_cnt);
                thread_cnt++;
                sleep(1);
        }
        while(1)
        {
                static int loop_cnt = 0;
                printf("app loop: %d\n", loop_cnt);
                sleep(1);
                loop_cnt++;
                if (loop_cnt == 10)
                        break;
        }
}

uClibc config is attached.

Could someone please try it on M3 and tell me the results?

Regards.




On Sat, Nov 1, 2014 at 10:52 AM, Sergei Poselenov <sposelenov@emcraft.com>
wrote:

> Hello,
>
> On Thu, 2014-10-23 at 17:25 +0200, Bernhard Reutner-Fischer wrote:
> > On 22 October 2014 12:11:26 CEST, Sergei Poselenov <
> sposelenov@emcraft.com> wrote:
> > >Hello,
> > >
> >
> > >Uclibc (still) lacks pthreads support on Cortex-M3.
> > >
> > >I'm attaching two patches:
> > > - implement testandset() for Cortex-M3.
> > > - Fix a bug in implementation of clone() for Cortex-M3.
> >
> > Can you please send the two patches with appropriate signed-off-by lines?
>
> I'm sending the patches made against the pristine 0.9.33.2 in the next
> emails. Note that the changes may be not quite portable, feel free to
> modify them.
>
> Regards,
>
> Sergei
> > TIA,
> >
>
>
>
Andrii Nov. 3, 2014, 3:58 p.m.
uClibc was built with: make ARCH_CFLAGS= 'CPU_CFLAGS=-mthumb -march=armv7
-mfix-cortex-m3-ldrd'
App was built with: arm-uclinuxeabi-gcc -c -g -mthumb -march=armv7
-mfix-cortex-m3-ldrd -O0 -Wl,-elf2flt,--static  main.c
arm-uclinuxeabi-gcc -Wl,-elf2flt,--static  main.o
-L../arm-2010q1/arm-uclinuxeabi/libc/thumb2/usr/lib -lpthread -o zpm_thread
where all original uclibc libraries from toolchain were replaced with newly
built ones:
/mnt/repos/repos/github/uclibc$ ls -la
/mnt/repos/repos/github/nocturn_tools/arm-2010q1/arm-uclinuxeabi/libc/thumb2/usr/lib
total 1412
drwxrwxr-x 2 repu1sion repu1sion    4096 Nov  3 17:32 .
drwxrwxr-x 5 repu1sion repu1sion    4096 Aug 25 22:50 ..
-rw-rw-r-- 1 repu1sion repu1sion     992 Nov  3 17:32 crt1.o
-rw-rw-r-- 1 repu1sion repu1sion     959 Nov  3 17:32 crti.o
-rw-rw-r-- 1 repu1sion repu1sion     959 Nov  3 17:32 crtn.o
-rw-rw-r-- 1 repu1sion repu1sion 1130956 Nov  3 17:32 libc.a
-rw-rw-r-- 1 repu1sion repu1sion  175768 Nov  3 17:32 libm.a
-rw-rw-r-- 1 repu1sion repu1sion   90352 Nov  3 17:32 libpthread.a
-rw-rw-r-- 1 repu1sion repu1sion    1082 Nov  3 17:32 libresolv.a
-rw-rw-r-- 1 repu1sion repu1sion   14084 Nov  3 17:32 librt.a



On Mon, Nov 3, 2014 at 5:53 PM, Andrii <bearrailgun@gmail.com> wrote:

> I've tried to apply Sergei' 3 patches to the original 0.9.33.2 and run
> test app on it.
> Still got a crash:
>
> / # /opt/zpm_thread
> 00032 : pthread_initialize: initial thread stack bounds: bos=0x1,
> tos=0xffffffff
> 00032 : __pthread_initialize_manager: manager stack: size=8160,
> bos=0xa00a2008, tos=0xa00a3fe8
> 00032 : __pthread_initialize_manager: send REQ_DEBUG to manager thread
> 00032 : pthread_create: write REQ_CREATE to manager thread
> 00032 : pthread_create: before suspend(self)
> 00033 : __pthread_manager: before poll
> 00033 : __pthread_manager: after poll
> 00033 : __pthread_manager: before read
> 00033 : __pthread_manager: after read, n=28
> 00033 : __pthread_manager: got REQ_CREATE
> 00033 : pthread_allocate_stack: malloced chunk: base=0xa00a8008,
> size=0x4000
> 00033 : pthread_allocate_stack: thread stack: bos=0xa00a8008,
> tos=0xa00abea8
> 00033 : pthread_allocate_stack: initial stack: bos=0x1, tos=0xa00a2008
> 00033 : pthread_handle_create: cloning new_thread = 0xa00abea8
> 00033 : pthread_handle_create: new thread pid = 34
> 00033 : __pthread_manager: restarting 0xa008e8d0
> 00032 : pthread_create: after suspend(self)
> thread #0 created
> 00033 : __pthread_manager: before poll
> 00034 : pthread_start_thread:
> new thread 1 executed.
> 00032 : pthread_create: write REQ_CREATE to manager thread
> 00032 : pthread_create: before suspend(self)
> 00033 : __pthread_manager: after poll
> 00033 : __pthread_manager: before read
> 00033 : __pthread_manager: after read, n=28
> 00033 : __pthread_manager: got REQ_CREATE
> 00033 : pthread_allocate_stack: malloced chunk: base=0xa03d8008,
> size=0x4000
> 00033 : pthread_allocate_stack: thread stack: bos=0xa03d8008,
> tos=0xa03dbea8
> 00033 : pthread_allocate_stack: initial stack: bos=0x1, tos=0xa00a2008
> 00033 : pthread_handle_create: cloning new_thread = 0xa03dbea8
> 00033 : pthread_handle_create: new thread pid = 35
> 00033 : __pthread_manager: restarting 0xa008e8d0
> 00033 : __pthread_manager: before poll
> 00035 : pthread_start_thread:
> new thread 1 executed.
> 00032 : pthread_create: after suspend(self)
> thread #1 created
> 00032 : pthread_create: write REQ_CREATE to manager thread
> 00033 : __pthread_manager: after poll
> 00033 : __pthread_manager: before read
> 00033 : __pthread_manager: after read, n=28
> 00033 : __pthread_manager: got REQ_CREATE
> 00032 : pthread_create: before suspend(self)
>
> [   12.390000]
> [   12.390000] zpm_thread: unhandled MPU fault (0x08) at 0x00000000
> [pc=0xa0084c74,sp=0xa00a3f20]
> [   12.390000]
> [   12.390000] Pid: 33, comm:           zpm_thread
> [   12.390000] CPU: 0    Not tainted  (2.6.33-arm1 #2)
> [   12.390000] pc : [<a0084c74>]    lr : [<a008478f>]    psr: 21000000
> [   12.390000] sp : a00a3f20  ip : 5220746f  fp : 00000803
> [   12.390000] Code dump at pc [a0084c74]:
> [   12.390000] a003f848 463b4621 ff98f7ff 681b4b04
> [   12.390000] r10: 00005000  r9 : 00000003  r8 : a0020000
> [   12.390000] r7 : a0092f04  r6 : 00000100  r5 : a0092e0c  r4 : a0024ff4
> [   12.390000] r3 : 00004ff4  r2 : 00000000  r1 : a0092e10  r0 : a0092e0c
> [   12.390000] Flags: nzCv  IRQs on  FIQs on  Mode USER_26  ISA unknown
>  Segment user
> [   12.390000] Backtrace: invalid frame pointer 0x00000803
>
> From my observations it crashes in malloc() during allocation of 16Kb
> stack for a new thread while trying to find and link a new free area.
>
> Here is the app code. It's trivial:
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
> #include <string.h>
> #include <pthread.h>
>
> #define NUM_THREADS 10
>
> pthread_t thread[NUM_THREADS] = {0};
> int thread_cnt = 0;
>
> void* start_routine(void *arg)
> {
>         printf("new thread %d executed.\n", thread_cnt);
>         while(1)
>         {
>                 sleep(1);
>         }
> }
>
> void main()
> {
>         int i;
>         int rv;
>
>         for (i = 0; i < NUM_THREADS; i++)
>         {
>                 rv = pthread_create(&thread[thread_cnt], NULL,
> start_routine, NULL);
>                 if (rv)
>                         printf("<error> thread was not created! Error num
> is : %d\n", rv);
>                 printf("thread #%d created \n", thread_cnt);
>                 thread_cnt++;
>                 sleep(1);
>         }
>         while(1)
>         {
>                 static int loop_cnt = 0;
>                 printf("app loop: %d\n", loop_cnt);
>                 sleep(1);
>                 loop_cnt++;
>                 if (loop_cnt == 10)
>                         break;
>         }
> }
>
> uClibc config is attached.
>
> Could someone please try it on M3 and tell me the results?
>
> Regards.
>
>
>
>
> On Sat, Nov 1, 2014 at 10:52 AM, Sergei Poselenov <sposelenov@emcraft.com>
> wrote:
>
>> Hello,
>>
>> On Thu, 2014-10-23 at 17:25 +0200, Bernhard Reutner-Fischer wrote:
>> > On 22 October 2014 12:11:26 CEST, Sergei Poselenov <
>> sposelenov@emcraft.com> wrote:
>> > >Hello,
>> > >
>> >
>> > >Uclibc (still) lacks pthreads support on Cortex-M3.
>> > >
>> > >I'm attaching two patches:
>> > > - implement testandset() for Cortex-M3.
>> > > - Fix a bug in implementation of clone() for Cortex-M3.
>> >
>> > Can you please send the two patches with appropriate signed-off-by
>> lines?
>>
>> I'm sending the patches made against the pristine 0.9.33.2 in the next
>> emails. Note that the changes may be not quite portable, feel free to
>> modify them.
>>
>> Regards,
>>
>> Sergei
>> > TIA,
>> >
>>
>>
>>
>
Andrii Nov. 6, 2014, 3:06 p.m.
What I actually did - disabled CONFIG_MPU in kernel and it started to work.
After that I found that my u-boot is custom fork and probably doesn't setup
MPU well.
Without CONFIG_MPU everything started to work great.
So I could say linuxthreads.old work on M3 with 3 patches provided by
Sergei over 0.9.33.2 release

On Mon, Nov 3, 2014 at 5:58 PM, Andrii <bearrailgun@gmail.com> wrote:

> uClibc was built with: make ARCH_CFLAGS= 'CPU_CFLAGS=-mthumb -march=armv7
> -mfix-cortex-m3-ldrd'
> App was built with: arm-uclinuxeabi-gcc -c -g -mthumb -march=armv7
> -mfix-cortex-m3-ldrd -O0 -Wl,-elf2flt,--static  main.c
> arm-uclinuxeabi-gcc -Wl,-elf2flt,--static  main.o
> -L../arm-2010q1/arm-uclinuxeabi/libc/thumb2/usr/lib -lpthread -o zpm_thread
> where all original uclibc libraries from toolchain were replaced with
> newly built ones:
> /mnt/repos/repos/github/uclibc$ ls -la
> /mnt/repos/repos/github/nocturn_tools/arm-2010q1/arm-uclinuxeabi/libc/thumb2/usr/lib
> total 1412
> drwxrwxr-x 2 repu1sion repu1sion    4096 Nov  3 17:32 .
> drwxrwxr-x 5 repu1sion repu1sion    4096 Aug 25 22:50 ..
> -rw-rw-r-- 1 repu1sion repu1sion     992 Nov  3 17:32 crt1.o
> -rw-rw-r-- 1 repu1sion repu1sion     959 Nov  3 17:32 crti.o
> -rw-rw-r-- 1 repu1sion repu1sion     959 Nov  3 17:32 crtn.o
> -rw-rw-r-- 1 repu1sion repu1sion 1130956 Nov  3 17:32 libc.a
> -rw-rw-r-- 1 repu1sion repu1sion  175768 Nov  3 17:32 libm.a
> -rw-rw-r-- 1 repu1sion repu1sion   90352 Nov  3 17:32 libpthread.a
> -rw-rw-r-- 1 repu1sion repu1sion    1082 Nov  3 17:32 libresolv.a
> -rw-rw-r-- 1 repu1sion repu1sion   14084 Nov  3 17:32 librt.a
>
>
>
> On Mon, Nov 3, 2014 at 5:53 PM, Andrii <bearrailgun@gmail.com> wrote:
>
>> I've tried to apply Sergei' 3 patches to the original 0.9.33.2 and run
>> test app on it.
>> Still got a crash:
>>
>> / # /opt/zpm_thread
>> 00032 : pthread_initialize: initial thread stack bounds: bos=0x1,
>> tos=0xffffffff
>> 00032 : __pthread_initialize_manager: manager stack: size=8160,
>> bos=0xa00a2008, tos=0xa00a3fe8
>> 00032 : __pthread_initialize_manager: send REQ_DEBUG to manager thread
>> 00032 : pthread_create: write REQ_CREATE to manager thread
>> 00032 : pthread_create: before suspend(self)
>> 00033 : __pthread_manager: before poll
>> 00033 : __pthread_manager: after poll
>> 00033 : __pthread_manager: before read
>> 00033 : __pthread_manager: after read, n=28
>> 00033 : __pthread_manager: got REQ_CREATE
>> 00033 : pthread_allocate_stack: malloced chunk: base=0xa00a8008,
>> size=0x4000
>> 00033 : pthread_allocate_stack: thread stack: bos=0xa00a8008,
>> tos=0xa00abea8
>> 00033 : pthread_allocate_stack: initial stack: bos=0x1, tos=0xa00a2008
>> 00033 : pthread_handle_create: cloning new_thread = 0xa00abea8
>> 00033 : pthread_handle_create: new thread pid = 34
>> 00033 : __pthread_manager: restarting 0xa008e8d0
>> 00032 : pthread_create: after suspend(self)
>> thread #0 created
>> 00033 : __pthread_manager: before poll
>> 00034 : pthread_start_thread:
>> new thread 1 executed.
>> 00032 : pthread_create: write REQ_CREATE to manager thread
>> 00032 : pthread_create: before suspend(self)
>> 00033 : __pthread_manager: after poll
>> 00033 : __pthread_manager: before read
>> 00033 : __pthread_manager: after read, n=28
>> 00033 : __pthread_manager: got REQ_CREATE
>> 00033 : pthread_allocate_stack: malloced chunk: base=0xa03d8008,
>> size=0x4000
>> 00033 : pthread_allocate_stack: thread stack: bos=0xa03d8008,
>> tos=0xa03dbea8
>> 00033 : pthread_allocate_stack: initial stack: bos=0x1, tos=0xa00a2008
>> 00033 : pthread_handle_create: cloning new_thread = 0xa03dbea8
>> 00033 : pthread_handle_create: new thread pid = 35
>> 00033 : __pthread_manager: restarting 0xa008e8d0
>> 00033 : __pthread_manager: before poll
>> 00035 : pthread_start_thread:
>> new thread 1 executed.
>> 00032 : pthread_create: after suspend(self)
>> thread #1 created
>> 00032 : pthread_create: write REQ_CREATE to manager thread
>> 00033 : __pthread_manager: after poll
>> 00033 : __pthread_manager: before read
>> 00033 : __pthread_manager: after read, n=28
>> 00033 : __pthread_manager: got REQ_CREATE
>> 00032 : pthread_create: before suspend(self)
>>
>> [   12.390000]
>> [   12.390000] zpm_thread: unhandled MPU fault (0x08) at 0x00000000
>> [pc=0xa0084c74,sp=0xa00a3f20]
>> [   12.390000]
>> [   12.390000] Pid: 33, comm:           zpm_thread
>> [   12.390000] CPU: 0    Not tainted  (2.6.33-arm1 #2)
>> [   12.390000] pc : [<a0084c74>]    lr : [<a008478f>]    psr: 21000000
>> [   12.390000] sp : a00a3f20  ip : 5220746f  fp : 00000803
>> [   12.390000] Code dump at pc [a0084c74]:
>> [   12.390000] a003f848 463b4621 ff98f7ff 681b4b04
>> [   12.390000] r10: 00005000  r9 : 00000003  r8 : a0020000
>> [   12.390000] r7 : a0092f04  r6 : 00000100  r5 : a0092e0c  r4 : a0024ff4
>> [   12.390000] r3 : 00004ff4  r2 : 00000000  r1 : a0092e10  r0 : a0092e0c
>> [   12.390000] Flags: nzCv  IRQs on  FIQs on  Mode USER_26  ISA unknown
>>  Segment user
>> [   12.390000] Backtrace: invalid frame pointer 0x00000803
>>
>> From my observations it crashes in malloc() during allocation of 16Kb
>> stack for a new thread while trying to find and link a new free area.
>>
>> Here is the app code. It's trivial:
>>
>> #include <stdio.h>
>> #include <stdlib.h>
>> #include <unistd.h>
>> #include <string.h>
>> #include <pthread.h>
>>
>> #define NUM_THREADS 10
>>
>> pthread_t thread[NUM_THREADS] = {0};
>> int thread_cnt = 0;
>>
>> void* start_routine(void *arg)
>> {
>>         printf("new thread %d executed.\n", thread_cnt);
>>         while(1)
>>         {
>>                 sleep(1);
>>         }
>> }
>>
>> void main()
>> {
>>         int i;
>>         int rv;
>>
>>         for (i = 0; i < NUM_THREADS; i++)
>>         {
>>                 rv = pthread_create(&thread[thread_cnt], NULL,
>> start_routine, NULL);
>>                 if (rv)
>>                         printf("<error> thread was not created! Error num
>> is : %d\n", rv);
>>                 printf("thread #%d created \n", thread_cnt);
>>                 thread_cnt++;
>>                 sleep(1);
>>         }
>>         while(1)
>>         {
>>                 static int loop_cnt = 0;
>>                 printf("app loop: %d\n", loop_cnt);
>>                 sleep(1);
>>                 loop_cnt++;
>>                 if (loop_cnt == 10)
>>                         break;
>>         }
>> }
>>
>> uClibc config is attached.
>>
>> Could someone please try it on M3 and tell me the results?
>>
>> Regards.
>>
>>
>>
>>
>> On Sat, Nov 1, 2014 at 10:52 AM, Sergei Poselenov <sposelenov@emcraft.com
>> > wrote:
>>
>>> Hello,
>>>
>>> On Thu, 2014-10-23 at 17:25 +0200, Bernhard Reutner-Fischer wrote:
>>> > On 22 October 2014 12:11:26 CEST, Sergei Poselenov <
>>> sposelenov@emcraft.com> wrote:
>>> > >Hello,
>>> > >
>>> >
>>> > >Uclibc (still) lacks pthreads support on Cortex-M3.
>>> > >
>>> > >I'm attaching two patches:
>>> > > - implement testandset() for Cortex-M3.
>>> > > - Fix a bug in implementation of clone() for Cortex-M3.
>>> >
>>> > Can you please send the two patches with appropriate signed-off-by
>>> lines?
>>>
>>> I'm sending the patches made against the pristine 0.9.33.2 in the next
>>> emails. Note that the changes may be not quite portable, feel free to
>>> modify them.
>>>
>>> Regards,
>>>
>>> Sergei
>>> > TIA,
>>> >
>>>
>>>
>>>
>>
>
sposelenov@emcraft.com Nov. 7, 2014, 9:21 a.m.
Hello Andrii,

On Thu, 6 Nov 2014 17:06:36 +0200
Andrii <bearrailgun@gmail.com> wrote:

> What I actually did - disabled CONFIG_MPU in kernel and it started to
> work. After that I found that my u-boot is custom fork and probably
> doesn't setup MPU well.
> Without CONFIG_MPU everything started to work great.
> So I could say linuxthreads.old work on M3 with 3 patches provided by
> Sergei over 0.9.33.2 release
> 
Sounds good.

BTW you can see Emcraft LPC17xx port of U-Boot and Linux on GitHub
https://github.com/EmcraftSystems

Regards,

Sergei

> On Mon, Nov 3, 2014 at 5:58 PM, Andrii <bearrailgun@gmail.com> wrote:
> 
> > uClibc was built with: make ARCH_CFLAGS= 'CPU_CFLAGS=-mthumb
> > -march=armv7 -mfix-cortex-m3-ldrd'
> > App was built with: arm-uclinuxeabi-gcc -c -g -mthumb -march=armv7
> > -mfix-cortex-m3-ldrd -O0 -Wl,-elf2flt,--static  main.c
> > arm-uclinuxeabi-gcc -Wl,-elf2flt,--static  main.o
> > -L../arm-2010q1/arm-uclinuxeabi/libc/thumb2/usr/lib -lpthread -o
> > zpm_thread where all original uclibc libraries from toolchain were
> > replaced with newly built ones:
> > /mnt/repos/repos/github/uclibc$ ls -la
> > /mnt/repos/repos/github/nocturn_tools/arm-2010q1/arm-uclinuxeabi/libc/thumb2/usr/lib
> > total 1412
> > drwxrwxr-x 2 repu1sion repu1sion    4096 Nov  3 17:32 .
> > drwxrwxr-x 5 repu1sion repu1sion    4096 Aug 25 22:50 ..
> > -rw-rw-r-- 1 repu1sion repu1sion     992 Nov  3 17:32 crt1.o
> > -rw-rw-r-- 1 repu1sion repu1sion     959 Nov  3 17:32 crti.o
> > -rw-rw-r-- 1 repu1sion repu1sion     959 Nov  3 17:32 crtn.o
> > -rw-rw-r-- 1 repu1sion repu1sion 1130956 Nov  3 17:32 libc.a
> > -rw-rw-r-- 1 repu1sion repu1sion  175768 Nov  3 17:32 libm.a
> > -rw-rw-r-- 1 repu1sion repu1sion   90352 Nov  3 17:32 libpthread.a
> > -rw-rw-r-- 1 repu1sion repu1sion    1082 Nov  3 17:32 libresolv.a
> > -rw-rw-r-- 1 repu1sion repu1sion   14084 Nov  3 17:32 librt.a
> >
> >
> >
> > On Mon, Nov 3, 2014 at 5:53 PM, Andrii <bearrailgun@gmail.com>
> > wrote:
> >
> >> I've tried to apply Sergei' 3 patches to the original 0.9.33.2 and
> >> run test app on it.
> >> Still got a crash:
> >>
> >> / # /opt/zpm_thread
> >> 00032 : pthread_initialize: initial thread stack bounds: bos=0x1,
> >> tos=0xffffffff
> >> 00032 : __pthread_initialize_manager: manager stack: size=8160,
> >> bos=0xa00a2008, tos=0xa00a3fe8
> >> 00032 : __pthread_initialize_manager: send REQ_DEBUG to manager
> >> thread 00032 : pthread_create: write REQ_CREATE to manager thread
> >> 00032 : pthread_create: before suspend(self)
> >> 00033 : __pthread_manager: before poll
> >> 00033 : __pthread_manager: after poll
> >> 00033 : __pthread_manager: before read
> >> 00033 : __pthread_manager: after read, n=28
> >> 00033 : __pthread_manager: got REQ_CREATE
> >> 00033 : pthread_allocate_stack: malloced chunk: base=0xa00a8008,
> >> size=0x4000
> >> 00033 : pthread_allocate_stack: thread stack: bos=0xa00a8008,
> >> tos=0xa00abea8
> >> 00033 : pthread_allocate_stack: initial stack: bos=0x1,
> >> tos=0xa00a2008 00033 : pthread_handle_create: cloning new_thread =
> >> 0xa00abea8 00033 : pthread_handle_create: new thread pid = 34
> >> 00033 : __pthread_manager: restarting 0xa008e8d0
> >> 00032 : pthread_create: after suspend(self)
> >> thread #0 created
> >> 00033 : __pthread_manager: before poll
> >> 00034 : pthread_start_thread:
> >> new thread 1 executed.
> >> 00032 : pthread_create: write REQ_CREATE to manager thread
> >> 00032 : pthread_create: before suspend(self)
> >> 00033 : __pthread_manager: after poll
> >> 00033 : __pthread_manager: before read
> >> 00033 : __pthread_manager: after read, n=28
> >> 00033 : __pthread_manager: got REQ_CREATE
> >> 00033 : pthread_allocate_stack: malloced chunk: base=0xa03d8008,
> >> size=0x4000
> >> 00033 : pthread_allocate_stack: thread stack: bos=0xa03d8008,
> >> tos=0xa03dbea8
> >> 00033 : pthread_allocate_stack: initial stack: bos=0x1,
> >> tos=0xa00a2008 00033 : pthread_handle_create: cloning new_thread =
> >> 0xa03dbea8 00033 : pthread_handle_create: new thread pid = 35
> >> 00033 : __pthread_manager: restarting 0xa008e8d0
> >> 00033 : __pthread_manager: before poll
> >> 00035 : pthread_start_thread:
> >> new thread 1 executed.
> >> 00032 : pthread_create: after suspend(self)
> >> thread #1 created
> >> 00032 : pthread_create: write REQ_CREATE to manager thread
> >> 00033 : __pthread_manager: after poll
> >> 00033 : __pthread_manager: before read
> >> 00033 : __pthread_manager: after read, n=28
> >> 00033 : __pthread_manager: got REQ_CREATE
> >> 00032 : pthread_create: before suspend(self)
> >>
> >> [   12.390000]
> >> [   12.390000] zpm_thread: unhandled MPU fault (0x08) at 0x00000000
> >> [pc=0xa0084c74,sp=0xa00a3f20]
> >> [   12.390000]
> >> [   12.390000] Pid: 33, comm:           zpm_thread
> >> [   12.390000] CPU: 0    Not tainted  (2.6.33-arm1 #2)
> >> [   12.390000] pc : [<a0084c74>]    lr : [<a008478f>]    psr:
> >> 21000000 [   12.390000] sp : a00a3f20  ip : 5220746f  fp : 00000803
> >> [   12.390000] Code dump at pc [a0084c74]:
> >> [   12.390000] a003f848 463b4621 ff98f7ff 681b4b04
> >> [   12.390000] r10: 00005000  r9 : 00000003  r8 : a0020000
> >> [   12.390000] r7 : a0092f04  r6 : 00000100  r5 : a0092e0c  r4 :
> >> a0024ff4 [   12.390000] r3 : 00004ff4  r2 : 00000000  r1 :
> >> a0092e10  r0 : a0092e0c [   12.390000] Flags: nzCv  IRQs on  FIQs
> >> on  Mode USER_26  ISA unknown Segment user
> >> [   12.390000] Backtrace: invalid frame pointer 0x00000803
> >>
> >> From my observations it crashes in malloc() during allocation of
> >> 16Kb stack for a new thread while trying to find and link a new
> >> free area.
> >>
> >> Here is the app code. It's trivial:
> >>
> >> #include <stdio.h>
> >> #include <stdlib.h>
> >> #include <unistd.h>
> >> #include <string.h>
> >> #include <pthread.h>
> >>
> >> #define NUM_THREADS 10
> >>
> >> pthread_t thread[NUM_THREADS] = {0};
> >> int thread_cnt = 0;
> >>
> >> void* start_routine(void *arg)
> >> {
> >>         printf("new thread %d executed.\n", thread_cnt);
> >>         while(1)
> >>         {
> >>                 sleep(1);
> >>         }
> >> }
> >>
> >> void main()
> >> {
> >>         int i;
> >>         int rv;
> >>
> >>         for (i = 0; i < NUM_THREADS; i++)
> >>         {
> >>                 rv = pthread_create(&thread[thread_cnt], NULL,
> >> start_routine, NULL);
> >>                 if (rv)
> >>                         printf("<error> thread was not created!
> >> Error num is : %d\n", rv);
> >>                 printf("thread #%d created \n", thread_cnt);
> >>                 thread_cnt++;
> >>                 sleep(1);
> >>         }
> >>         while(1)
> >>         {
> >>                 static int loop_cnt = 0;
> >>                 printf("app loop: %d\n", loop_cnt);
> >>                 sleep(1);
> >>                 loop_cnt++;
> >>                 if (loop_cnt == 10)
> >>                         break;
> >>         }
> >> }
> >>
> >> uClibc config is attached.
> >>
> >> Could someone please try it on M3 and tell me the results?
> >>
> >> Regards.
> >>
> >>
> >>
> >>
> >> On Sat, Nov 1, 2014 at 10:52 AM, Sergei Poselenov
> >> <sposelenov@emcraft.com
> >> > wrote:
> >>
> >>> Hello,
> >>>
> >>> On Thu, 2014-10-23 at 17:25 +0200, Bernhard Reutner-Fischer wrote:
> >>> > On 22 October 2014 12:11:26 CEST, Sergei Poselenov <
> >>> sposelenov@emcraft.com> wrote:
> >>> > >Hello,
> >>> > >
> >>> >
> >>> > >Uclibc (still) lacks pthreads support on Cortex-M3.
> >>> > >
> >>> > >I'm attaching two patches:
> >>> > > - implement testandset() for Cortex-M3.
> >>> > > - Fix a bug in implementation of clone() for Cortex-M3.
> >>> >
> >>> > Can you please send the two patches with appropriate
> >>> > signed-off-by
> >>> lines?
> >>>
> >>> I'm sending the patches made against the pristine 0.9.33.2 in the
> >>> next emails. Note that the changes may be not quite portable,
> >>> feel free to modify them.
> >>>
> >>> Regards,
> >>>
> >>> Sergei
> >>> > TIA,
> >>> >
> >>>
> >>>
> >>>
> >>
> >

Patch hide | download patch | download mbox

commit 626dbe5372b47aea1fe27c52b55649621ee30ff4
Author: Sergei Poselenov <sposelenov@emcraft.com>
Date:   Sun Dec 15 13:53:55 2013 +0400

    RT #91128. Implemented testandset() with ldrex/strex (not supported on SmartFusion).

diff --git a/dot_config_pthreads b/dot_config_pthreads
index 1181fde..3f5e11b 100644
--- a/dot_config_pthreads
+++ b/dot_config_pthreads
@@ -38,6 +38,7 @@  FORCE_OPTIONS_FOR_ARCH=y
 CONFIG_ARM_EABI=y
 COMPILE_IN_THUMB_MODE=y
 USE_BX=y
+USE_LDREXSTREX=y
 TARGET_SUBARCH=""
 # UCLIBC_FORMAT_ELF is not set
 # UCLIBC_FORMAT_FDPIC_ELF is not set
diff --git a/dot_config_pthreads-no-ldrex b/dot_config_pthreads-no-ldrex
new file mode 100644
index 0000000..64b147d
--- /dev/null
+++ b/dot_config_pthreads-no-ldrex
@@ -0,0 +1,230 @@ 
+#
+# Automatically generated make config: don't edit
+# Version: 0.9.33.2
+# Sun Mar 24 12:28:02 2013
+#
+# TARGET_alpha is not set
+TARGET_arm=y
+# TARGET_avr32 is not set
+# TARGET_bfin is not set
+# TARGET_c6x is not set
+# TARGET_cris is not set
+# TARGET_e1 is not set
+# TARGET_frv is not set
+# TARGET_h8300 is not set
+# TARGET_hppa is not set
+# TARGET_i386 is not set
+# TARGET_i960 is not set
+# TARGET_ia64 is not set
+# TARGET_m68k is not set
+# TARGET_microblaze is not set
+# TARGET_mips is not set
+# TARGET_nios is not set
+# TARGET_nios2 is not set
+# TARGET_powerpc is not set
+# TARGET_sh is not set
+# TARGET_sh64 is not set
+# TARGET_sparc is not set
+# TARGET_v850 is not set
+# TARGET_vax is not set
+# TARGET_x86_64 is not set
+# TARGET_xtensa is not set
+
+#
+# Target Architecture Features and Options
+#
+TARGET_ARCH="arm"
+FORCE_OPTIONS_FOR_ARCH=y
+CONFIG_ARM_EABI=y
+COMPILE_IN_THUMB_MODE=y
+USE_BX=y
+# USE_LDREXSTREX is not set
+TARGET_SUBARCH=""
+# UCLIBC_FORMAT_ELF is not set
+# UCLIBC_FORMAT_FDPIC_ELF is not set
+# UCLIBC_FORMAT_DSBT_ELF is not set
+UCLIBC_FORMAT_FLAT=y
+# UCLIBC_FORMAT_FLAT_SEP_DATA is not set
+# UCLIBC_FORMAT_SHARED_FLAT is not set
+ARCH_ANY_ENDIAN=y
+ARCH_LITTLE_ENDIAN=y
+# ARCH_WANTS_BIG_ENDIAN is not set
+ARCH_WANTS_LITTLE_ENDIAN=y
+# ARCH_HAS_MMU is not set
+UCLIBC_HAS_FLOATS=y
+# UCLIBC_HAS_FPU is not set
+UCLIBC_HAS_SOFT_FLOAT=y
+DO_C99_MATH=y
+# DO_XSI_MATH is not set
+# UCLIBC_HAS_FENV is not set
+KERNEL_HEADERS="KRNL_HDR"
+UCLIBC_UCLINUX_BROKEN_MUNMAP=y
+HAVE_DOT_CONFIG=y
+
+#
+# General Library Settings
+#
+# DOPIC is not set
+ARCH_HAS_NO_SHARED=y
+ARCH_HAS_NO_LDSO=y
+UCLIBC_CTOR_DTOR=y
+# HAS_NO_THREADS is not set
+LINUXTHREADS_OLD=y
+# LINUXTHREADS_NEW is not set
+# UCLIBC_HAS_THREADS_NATIVE is not set
+UCLIBC_HAS_THREADS=y
+PTHREADS_DEBUG_SUPPORT=y
+UCLIBC_HAS_SYSLOG=y
+UCLIBC_HAS_LFS=y
+MALLOC=y
+# MALLOC_SIMPLE is not set
+# MALLOC_STANDARD is not set
+# MALLOC_GLIBC_COMPAT is not set
+UCLIBC_DYNAMIC_ATEXIT=y
+# COMPAT_ATEXIT is not set
+UCLIBC_SUSV3_LEGACY=y
+# UCLIBC_SUSV3_LEGACY_MACROS is not set
+UCLIBC_SUSV4_LEGACY=y
+# UCLIBC_STRICT_HEADERS is not set
+# UCLIBC_HAS_STUBS is not set
+UCLIBC_HAS_SHADOW=y
+UCLIBC_HAS_PROGRAM_INVOCATION_NAME=y
+UCLIBC_HAS___PROGNAME=y
+UCLIBC_HAS_PTY=y
+ASSUME_DEVPTS=y
+UNIX98PTY_ONLY=y
+# UCLIBC_HAS_GETPT is not set
+# UCLIBC_HAS_LIBUTIL is not set
+UCLIBC_HAS_TM_EXTENSIONS=y
+UCLIBC_HAS_TZ_CACHING=y
+UCLIBC_HAS_TZ_FILE=y
+UCLIBC_HAS_TZ_FILE_READ_MANY=y
+UCLIBC_TZ_FILE_PATH="/etc/TZ"
+# UCLIBC_FALLBACK_TO_ETC_LOCALTIME is not set
+
+#
+# Advanced Library Settings
+#
+UCLIBC_PWD_BUFFER_SIZE=256
+UCLIBC_GRP_BUFFER_SIZE=256
+
+#
+# Support various families of functions
+#
+UCLIBC_LINUX_MODULE_26=y
+# UCLIBC_LINUX_MODULE_24 is not set
+UCLIBC_LINUX_SPECIFIC=y
+# UCLIBC_HAS_GNU_ERROR is not set
+# UCLIBC_BSD_SPECIFIC is not set
+# UCLIBC_HAS_BSD_ERR is not set
+# UCLIBC_HAS_OBSOLETE_BSD_SIGNAL is not set
+# UCLIBC_HAS_OBSOLETE_SYSV_SIGNAL is not set
+# UCLIBC_NTP_LEGACY is not set
+# UCLIBC_SV4_DEPRECATED is not set
+UCLIBC_HAS_REALTIME=y
+# UCLIBC_HAS_ADVANCED_REALTIME is not set
+# UCLIBC_HAS_EPOLL is not set
+# UCLIBC_HAS_XATTR is not set
+# UCLIBC_HAS_PROFILING is not set
+# UCLIBC_HAS_CRYPT_IMPL is not set
+# UCLIBC_HAS_CRYPT_STUB is not set
+UCLIBC_HAS_NETWORK_SUPPORT=y
+UCLIBC_HAS_SOCKET=y
+UCLIBC_HAS_IPV4=y
+# UCLIBC_HAS_IPV6 is not set
+UCLIBC_HAS_RPC=y
+# UCLIBC_HAS_FULL_RPC is not set
+# UCLIBC_HAS_REENTRANT_RPC is not set
+# UCLIBC_USE_NETLINK is not set
+# UCLIBC_HAS_BSD_RES_CLOSE is not set
+UCLIBC_HAS_COMPAT_RES_STATE=y
+# UCLIBC_HAS_EXTRA_COMPAT_RES_STATE is not set
+UCLIBC_HAS_RESOLVER_SUPPORT=y
+UCLIBC_HAS_LIBRESOLV_STUB=y
+# UCLIBC_HAS_LIBNSL_STUB is not set
+
+#
+# String and Stdio Support
+#
+# UCLIBC_HAS_STRING_GENERIC_OPT is not set
+UCLIBC_HAS_STRING_ARCH_OPT=y
+UCLIBC_HAS_CTYPE_TABLES=y
+UCLIBC_HAS_CTYPE_SIGNED=y
+UCLIBC_HAS_CTYPE_UNSAFE=y
+# UCLIBC_HAS_CTYPE_CHECKED is not set
+# UCLIBC_HAS_CTYPE_ENFORCED is not set
+UCLIBC_HAS_WCHAR=y
+# UCLIBC_HAS_LOCALE is not set
+UCLIBC_HAS_HEXADECIMAL_FLOATS=y
+UCLIBC_HAS_GLIBC_CUSTOM_PRINTF=y
+UCLIBC_PRINTF_SCANF_POSITIONAL_ARGS=9
+UCLIBC_HAS_SCANF_GLIBC_A_FLAG=y
+# UCLIBC_HAS_STDIO_BUFSIZ_NONE is not set
+# UCLIBC_HAS_STDIO_BUFSIZ_256 is not set
+# UCLIBC_HAS_STDIO_BUFSIZ_512 is not set
+# UCLIBC_HAS_STDIO_BUFSIZ_1024 is not set
+# UCLIBC_HAS_STDIO_BUFSIZ_2048 is not set
+UCLIBC_HAS_STDIO_BUFSIZ_4096=y
+# UCLIBC_HAS_STDIO_BUFSIZ_8192 is not set
+UCLIBC_HAS_STDIO_BUILTIN_BUFFER_NONE=y
+# UCLIBC_HAS_STDIO_BUILTIN_BUFFER_4 is not set
+# UCLIBC_HAS_STDIO_BUILTIN_BUFFER_8 is not set
+# UCLIBC_HAS_STDIO_SHUTDOWN_ON_ABORT is not set
+UCLIBC_HAS_STDIO_GETC_MACRO=y
+UCLIBC_HAS_STDIO_PUTC_MACRO=y
+UCLIBC_HAS_STDIO_AUTO_RW_TRANSITION=y
+UCLIBC_HAS_FOPEN_LARGEFILE_MODE=y
+UCLIBC_HAS_FOPEN_EXCLUSIVE_MODE=y
+# UCLIBC_HAS_FOPEN_CLOSEEXEC_MODE is not set
+UCLIBC_HAS_GLIBC_CUSTOM_STREAMS=y
+# UCLIBC_HAS_PRINTF_M_SPEC is not set
+UCLIBC_HAS_ERRNO_MESSAGES=y
+# UCLIBC_HAS_SYS_ERRLIST is not set
+UCLIBC_HAS_SIGNUM_MESSAGES=y
+# UCLIBC_HAS_SYS_SIGLIST is not set
+UCLIBC_HAS_GNU_GETOPT=y
+UCLIBC_HAS_GNU_GETSUBOPT=y
+
+#
+# Big and Tall
+#
+# UCLIBC_HAS_REGEX is not set
+UCLIBC_HAS_FNMATCH=y
+UCLIBC_HAS_FNMATCH_OLD=y
+# UCLIBC_HAS_WORDEXP is not set
+# UCLIBC_HAS_NFTW is not set
+# UCLIBC_HAS_FTW is not set
+# UCLIBC_HAS_FTS is not set
+UCLIBC_HAS_GLOB=y
+# UCLIBC_HAS_GNU_GLOB is not set
+# UCLIBC_HAS_UTMPX is not set
+
+#
+# Library Installation Options
+#
+RUNTIME_PREFIX="/"
+DEVEL_PREFIX="/usr"
+MULTILIB_DIR="lib"
+HARDWIRED_ABSPATH=y
+
+#
+# Security options
+#
+# UCLIBC_HAS_ARC4RANDOM is not set
+# UCLIBC_HAS_SSP is not set
+UCLIBC_BUILD_NOEXECSTACK=y
+
+#
+# Development/debugging options
+#
+CROSS_COMPILER_PREFIX="arm-uclinuxeabi-"
+UCLIBC_EXTRA_CFLAGS=""
+# DODEBUG is not set
+# DODEBUG_PT is not set
+# DOSTRIP is not set
+# DOASSERTS is not set
+# UCLIBC_MALLOC_DEBUGGING is not set
+WARNINGS="-Wall"
+# EXTRA_WARNINGS is not set
+# DOMULTI is not set
+# UCLIBC_MJN3_ONLY is not set
diff --git a/extra/Configs/Config.arm b/extra/Configs/Config.arm
index 0bb2971..5777d3b 100644
--- a/extra/Configs/Config.arm
+++ b/extra/Configs/Config.arm
@@ -36,3 +36,10 @@  config USE_BX
 	  Say 'y' to use BX to return from functions on your thumb-aware
 	  processor. Say 'y' if you need to use interworking. Say 'n' if not.
 	  It is safe to say 'y' even if you're not doing interworking.
+
+config USE_LDREXSTREX
+	bool "Use load-store exclusive ASM ops (not supported in SmartFusion)"
+	depends on COMPILE_IN_THUMB_MODE
+	default y
+	help
+	  Say 'y' to use LDREX/STREX ASM ops.
diff --git a/libpthread/linuxthreads.old/sysdeps/arm/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/arm/pt-machine.h
index 0b8c0cc..dcffeb1 100644
--- a/libpthread/linuxthreads.old/sysdeps/arm/pt-machine.h
+++ b/libpthread/linuxthreads.old/sysdeps/arm/pt-machine.h
@@ -30,15 +30,50 @@ 
 #endif
 
 #if defined(__thumb__)
+#if defined(__USE_LDREXSTREX__)
+PT_EI long int ldrex(int *spinlock)
+{
+	long int ret;
+	__asm__ __volatile__(
+		"ldrex %0, [%1]\n"
+		: "=r"(ret)
+		: "r"(spinlock) : "memory");
+	return ret;
+}
+
+PT_EI long int strex(int val, int *spinlock)
+{
+	long int ret;
+	__asm__ __volatile__(
+		"strex %0, %1, [%2]\n"
+		: "=r"(ret)
+		: "r" (val), "r"(spinlock) : "memory");
+	return ret;
+}
+
 /* Spinlock implementation; required.  */
 PT_EI long int
 testandset (int *spinlock)
 {
-  int unused = 0;
-  return INTERNAL_SYSCALL_ARM (atomicops, , 4, SYS_ARM_ATOMIC_SET,
-			  spinlock, 1, unused);
+  register unsigned int ret;
+
+  do {
+	  ret = ldrex(spinlock);
+  } while (strex(1, spinlock));
+
+  return ret;
 }
+#else /* USE_LDREXSTREX */
 
+/* Spinlock implementation; required.  */
+PT_EI long int
+testandset (int *spinlock)
+{
+	int unused = 0;
+	return INTERNAL_SYSCALL_ARM (atomicops, , 4, SYS_ARM_ATOMIC_SET,
+				spinlock, 1, unused);
+}
+#endif
 #else
 
 /* This will not work on ARM1 or ARM2 because SWP is lacking on those