This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler/66AK2H12: pthread_mutex_lock(&critsec_) generates a do_AngelSWI

Part Number: 66AK2H12
Other Parts Discussed in Thread: SYSBIOS

Tool/software: TI C/C++ Compiler

PDK 4.0.7, NDK 2.25.1.11, SYS/BIOS 6.46.5.55, IPC 3.46.2.04, EDMA3 2.12.4, CTools 2.2.0, CCS 7.4, GNU v4.9.3

From this thread: https://e2e.ti.com/support/legacy_forums/embedded/tirtos/f/355/t/574635?tisearch=e2e-sitesearch&keymatch=pthread_mutex_lock

I followed the directions in 

Made the additions to my cfg including supportsMutexPriority = true (I require it). 

Calls to pthread_mutexattr_init(&attr), pthread_mutexattr_setprotocol(), pthread_mutex_init(), pthread_mutexattr_destroy() all seem to work. However when I call pthread_mutex_lock(&critsec_); I get the crash. All the mentioned calls are from a Task created from main().

I stepped into pthread_mutex_lock() and got to here:

Trying to step over the Task_getPri() results in the doAngelSWI. 

Any suggestions please?

Mike

  • Hi Mike,

    Can you export a simple project that shows the problem?

    Todd

  • Todd,

    I don't know if I can or not. If I could copy my project settings easily it might be worth a try but honesty, I don't know how long it would take me to make a simple project to show it. Are there any obvious things I can look for?

  • Ok I built a simple project from scratch using new CCS project of type SYS/BIOS Typical. Followed the steps and it works.

    So I'm still at a loss as to why it doesn't work in my project. The code is in a C++ source file where as here it is C. Could that be a problem?

    I also have a call to  fdOpenSession(TaskSelf()) prior to using the critical section?

    How can I turn my main.c into a main.cpp? I renamed and changed the runtime lib to libstdc++.a (as is in my real project) and then I can not link. Get the following compile errors:

    making ../src/sysbios/sysbios.aa15fg ...
    gmake[2]: Nothing to be done for 'all'.
    'Building target: "pthread.out"'
    'Invoking: GNU Linker'
    "C:/ti/gcc-arm-none-eabi-4_9-2015q3/bin/arm-none-eabi-gcc.exe" -mtune=cortex-a15 -marm -g -gdwarf-3 -gstrict-dwarf -Wall -mfloat-abi=hard -Wl,-Map,"pthread.map" -nostartfiles -static -Wl,--gc-sections -L"C:/ti/bios_6_46_05_55/packages/gnu/targets/arm/libs/install-native/arm-none-eabi/lib/fpu" -o"pthread.out" "./main.o" -Wl,-T"configPkg/linker.cmd" -Wl,--start-group -lgcc -lm -lnosys -lstdc++ -Wl,--end-group 
    makefile:145: recipe for target 'pthread.out' failed
    C:/ti/bios_6_46_05_55/packages/gnu/targets/arm/libs/install-native/arm-none-eabi/lib/fpu\libg.a(lib_a-signalr.o): In function `_kill_r':
    /home/xlibrary/trees/gnu/gnu-c04/src/linaro/gcc-arm-none-eabi-4_7-2012q4-20121208/src/newlib/newlib/libc/reent/signalr.c:61: undefined reference to `_kill'
    C:/ti/bios_6_46_05_55/packages/gnu/targets/arm/libs/install-native/arm-none-eabi/lib/fpu\libg.a(lib_a-signalr.o): In function `_getpid_r':
    /home/xlibrary/trees/gnu/gnu-c04/src/linaro/gcc-arm-none-eabi-4_7-2012q4-20121208/src/newlib/newlib/libc/reent/signalr.c:96: undefined reference to `_getpid'
    collect2.exe: error: ld returned 1 exit status

  • It appears to be a problem with setting supportsMutexPriority = true and/or calling pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);

    If I remove them, both the simple test and my primary application, run. (both are c++). The call to pthread_mutex_lock() works (or at least appears to work. It returns. I haven't tried a test to try and gain access from another task).

    A couple of notes.

    With supportsMutexPriority = true: In my simple test application and PTHREAD_PRIO_INHERIT, the call to pthread_mutex_lock(&critsec_); just blocks.
    My real application crashes with the do_Angel.

    With PTHREAD_PRIO_INHERIT not set but pthread_mutexattr_setprioceiling() setting the ceailing to 3, the first call to pthread_mutex_lock() blocks.

  • Hi Mike,

    Is pthread_mutex_lock() being called from a BIOS Task or a pthread?  It cannot be called from a BIOS Task.  Can you try importing the BIOS bigtime example to test your use case?

    Best regards,

    Janet

  • Uggg!

    Yes I am calling from a BIOS Task.. I read this confusing part in the API manual:

    SYS/BIOS supports both pthread and pthread_attrs APIs for POSIX threads.

    Since each SYS/BIOS pthread has an underlying Task object, some of the SYS/BIOS Task APIs can be called from a pthread. These include Task_sleep(), Task_yield(), Task_self(), and Task_getPri(). Some Task APIs, such as Task_setPri(), should never be called from a pthread.

    Many of the pthread APIs must be called from a Task context, and therefore, cannot be called from main(). For example, pthread_create() can be called from main(), but pthread_join() cannot. A BIOS Task can call any pthread_mutexattr API, and can create and destroy a pthread mutex, but cannot call any other pthread_mutex APIs.

    With the exception of the supportsMutexPriority issue, it seemed to be working. Are you saying the mutex will not work across Tasks?

  • Hi Mike,

    The pthread runs as a BIOS task, but the pthread object has additional stuff embedded in it, along with a BIOS Task handle.  With PTHREAD_PRIO_INHERIT, there are Queue elements among other things in the pthread object before the Task handle.  You can see the pthread object defined in ti/sysbios/posix/_pthread.h.

    Also, when the pthread object is created, memory is first allocated for the pthread object, then Task_create() is called to initialize the pthread Task handle.  One of the Task Param args is used to store the base address of the pthread object.  In the acquireMutexPriority() code, you will see there is a call to pthread_self() which uses this argument to get the pthread object.

    So when you have a BIOS Task (created with Task_create(), or statically created in the .cfg file), it will not have the elements needed in the pthread object to support mutex priority inheritence.  The Task argument in the params passed to Task_create() will also be meaningless for pthread_self().  I wouldn't have expected any mutex locking to work for a BIOS Task, with or without mutex priority inheritance.

    Is the confusing part in the API doc that "Many of the pthread APIs must be called from a Task context"?  This means the APIs cannot be called from main(), or from a Swi or Hwi context.

    Could you try replacing Task_create() in your code with pthread_create() and see if that resolves the problem?

    Best regards,

    Janet

  • Janet,

    Thank you for your detailed explanation. I now understand the comments in the manual. "Many of the pthread APIs must be called from a Task context, and therefore, cannot be called from main()" I guess the key word was "many". And in this "A BIOS Task can call any pthread_mutexattr API, and can create and destroy a pthread mutex, but cannot call any other pthread_mutex APIs." I missed the distrinction between any "pthread_mutexattr" and "pthread_mutex".

    I can not ready change from using Tasks to pthreads. The application is very large across multiple cores and there are many tasks using many of the ti.sysbios.knl.Task api interfaces and calls. I'm afraid trying to change them all to pthreads would create more trouble in other areas.

    My main reason for looking at the pthread_mutex was to implement a c++ guard class. One that when create auto unlocks when it goes out of context. Useful for managing exception handling. I had been using GateMutexPri as a bases but was hoping to use the pthread mutex to gain the ceiling protocol and get rid of tracking keys. Maybe you have a suggestion there but no worries if you don't.

    You've answered my questions here on this thread. Again, thanks.

    Mike

  • Hi Mike,

    The best option is GateMutexPri.

    Todd