Hello everyone,
My name is Michael. I'm working for voestalpine in an embedded software project
for railways diagnostics.
Before filing a bug on Launchpad I wanted to write to this list to get a proper
judgement of our problem.
We use the gcc cross compiler for armhf architecture and qemu to execute some
of the built executables on an x86_64 host under Debian Jessie.
We would like to switch to Debian Stretch for various reasons but found the
following problem:
The qemu-arm emulation delivered by debian > jessie seems to not support the
pthread-protocol PTHREAD_PRIO_INHERIT.
A testcase is attached. The binary can be configured to use recursive mutexes
by using the -r flag, and enable the priority inheritance via -p flag. It
should not stop regardless the combination of flags.
Compile natively (amd64/i386):
gcc pmutex.c -pthread -o pmutex
compile cross:
arm-linux-gnueabihf-gcc pmutex.c -pthread -o pmutex.armhf
As matter of fact, using the -p flag inside the qemu emulation for debian
stretch or buster, the application returns the PTHREAD_PRIO_INHERIT as not
supported and locks upon recursive usage. Using this binary on a debian jessie
installation, it works.
We need the PTHREAD_PRIO_INHERIT since we use an RT patched kernel (4.1.40).
I would be very grateful if someone could give a hint how to get this fixed
such that we can switch to Debian Stretch.
Please tell me if I should provide additional information or if I made some
mistake by writing to this list.
Thanks in advance for your help.
Kind regards
Michael
#include <errno.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <stdlib.h>
pthread_t child;
struct sched_param child_param;
int child_policy;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutexattr_t mutex_attr;
void *child_fn(void *arg) {
pthread_getschedparam(child, &child_policy, &child_param);
child_param.__sched_priority = 10;
pthread_setschedparam(child, child_policy, &child_param);
while (1) {
pthread_mutex_lock(&mutex);
fprintf(stderr, "child acquired...");
usleep(300000);
fprintf(stderr, "released\n");
pthread_mutex_unlock(&mutex);
usleep(100000);
}
}
int main(int argc, char *argv[]) {
int ret;
int rec=0, prio=0;
int c;
ret = pthread_mutexattr_init(&mutex_attr);
if (ret) {
printf("pthread_mutexattr_init failed\n");
return 0;
}
while(( c = getopt( argc, argv, "pr")) != -1 )
{
switch( c )
{
case 'r':
rec = 1;
break;
case 'p':
prio=1;
break;
default:
printf("only -r for recursive, -p for prio-inherit
supported\n");
return 1;
}
}
if( rec ) {
ret = pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE);
if (ret) {
perror("pthread_mutexattr_settype failed");
return 0;
}
}
if( prio ) {
ret = pthread_mutexattr_setprotocol(&mutex_attr, PTHREAD_PRIO_INHERIT);
if (ret) {
perror("pthread_mutexattr_setprotocol failed");
return 0;
}
}
ret = pthread_mutex_init(&mutex, &mutex_attr);
if( ret ) {
perror("pthread_mutex_init failed");
printf("continue anymway\n");
}
ret = pthread_create(&child, NULL, child_fn, NULL);
while (1) {
pthread_mutex_lock(&mutex);
fprintf(stderr, "parent acquired...\n");
if( rec ) {
pthread_mutex_lock(&mutex);
fprintf(stderr, "parent acquired recursively...\n");
}
usleep(300000);
if( rec ) {
pthread_mutex_unlock(&mutex);
fprintf(stderr, "parent recursively locked mutex released\n");
}
pthread_mutex_unlock(&mutex);
fprintf(stderr, "parent released\n");
usleep(100000);
}
pthread_mutex_destroy(&mutex);
return 0;
}