All of lore.kernel.org
 help / color / mirror / Atom feed
From: Wolfgang Grandegger <wg@domain.hid>
To: Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>
Cc: xenomai-help <xenomai@xenomai.org>
Subject: Re: [Xenomai-help] pthread cancelation and scheduling magics
Date: Tue, 02 Dec 2008 16:59:25 +0100	[thread overview]
Message-ID: <49355B5D.8070802@domain.hid> (raw)
In-Reply-To: <4933FE5A.5060501@domain.hid>

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

Hi Gilles,

Gilles Chanteperdrix wrote:
> Gilles Chanteperdrix wrote:
>>>> Now, the question is, do you realistically plan to write an application
>>>> which makes no syscall in its real-time loop?
>>> Unlikely, but it may happen in case of programming errors. Anyhow, the
>>> pthreads will run legacy code and it would be a pain to add
>>> pthread_testcancel where necessary. But maybe there is a more elegant
>>> and simple solution to do a defined exit/abort.
>> In case of programming error, enable the xenomai watchdog, it will
>> forcibly kill the problematic thread.
> 
> To give you a more complete answer: most blocking functions are
> cancellation points in the PTHREAD_CANCEL_DEFERRED case, so, you
> probably do not need to add pthread_testcancel at all. The only
> exception is pthread_mutex_lock: this way, cancellation happens for well
> defined mutex states, and you may install cleanup handlers with
> pthread_cleanup_push/pthread_cleanup_pop if ever a thread may be
> destroyed while holding a mutex. With PTHREAD_CANCEL_ASYNCHRONOUS, the
> situation is not that clean.

Well, there seems something wrong with it, also PTHREAD_CANCEL_DEFERRED
with pthread_testcancel does not work reliably and consistently and it
still behaves different on my ARM and PowerPC systems. I have attached
my revised test program allowing to enable/disable various method of
thread creation, setup and cancellation. They all work fine with the
Linux POSIX libraries. With Xenomai, only a few work as expected on my
ARM and PowerPC test systems. It would be nice if somebody could test it
on a X86 system. Maybe there is still something wrong with my test program.
I'm also puzzled why pthread_setschedparam() does make a mode switch to
secondary mode (sometimes).

Wolfgang.




[-- Attachment #2: cancel-test.c --]
[-- Type: text/x-csrc, Size: 5030 bytes --]

/*
 * Test program for thread cancelation
 */

#include <execinfo.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/mman.h>

#ifndef __XENO__
#define rt_printf printf
#else
#include <rtdk.h>
#endif

//#define USE_SIGXCPU
//#define USE_EXPLICIT_SCHED
#define CANCEL_TYPE PTHREAD_CANCEL_DEFERRED
//#define CANCEL_TYPE PTHREAD_CANCEL_ASYNCHRONOUS
#define USE_TEST_CANCEL

#define CTRL_PRIO 39
#define CALC_PRIO 38

static pthread_t calc_thread;
static pthread_t ctrl_thread;

volatile unsigned long count = 0;
static int load_ms = 2500;
static int calc_exit;

void check_err(char *string, int err)
{
	if (err) {
		printf("Failed with %d at %s", err, string);
		exit(1);
	}
}

static void create_load_100ms(void)
{
	struct timespec now, stop;

	clock_gettime(CLOCK_MONOTONIC, &stop);
	stop.tv_nsec += 100000000;
	if (stop.tv_nsec >= 1000000000) {
		stop.tv_nsec -= 1000000000;
		stop.tv_sec++;
	}

	while (1) {
#ifdef USE_TEST_CANCEL
		pthread_testcancel();
#endif
		clock_gettime(CLOCK_MONOTONIC, &now);
		if (now.tv_sec > stop.tv_sec)
			break;
		else if (now.tv_sec == stop.tv_sec &&
			 now.tv_nsec >= stop.tv_nsec)
			break;
	}
}

void *ctrl_func(void *parm)
{
	struct timespec ts;
#ifndef USE_EXPLICIT_SCHED
	struct sched_param param;
#endif
	int rc;

#ifdef __XENO__
	pthread_set_name_np(pthread_self(), __func__);
#ifdef USE_SIGXCPU
	pthread_set_mode_np(0, PTHREAD_WARNSW);
#endif
#endif
#ifndef USE_EXPLICIT_SCHED
	memset(&param, 0 , sizeof(param));
	param.sched_priority = CTRL_PRIO;
	rc = pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);
	check_err("pthread_setschedparam()\n", rc);
#endif
	rt_printf("%s: started at count %ld\n", __func__, count);

	ts.tv_sec = load_ms / 1000;
	ts.tv_nsec = (load_ms % 1000) * 1000000;
	rt_printf("%s: sleeping for %ldsec %ldns\n", __func__,
		  (long)ts.tv_sec, (long)ts.tv_nsec);
	nanosleep(&ts, NULL);
	if (!calc_exit) {
		rt_printf("%s: cancel at count %ld\n", __func__, count);
		pthread_cancel(calc_thread);
	}
	rt_printf("%s: stopped at count %ld\n", __func__, count);

	return NULL;
}
void *calc_func(void *parm)
{
	int rc , count_max;
#ifndef USE_EXPLICIT_SCHED
	struct sched_param param;

	memset(&param, 0 , sizeof(param));
	param.sched_priority = CALC_PRIO;
	rc = pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);
	check_err("pthread_setschedparam()\n", rc);
#endif
#ifdef __XENO__
	pthread_set_name_np(pthread_self(), __func__);
#ifdef USE_SIGXCPU
	pthread_set_mode_np(0, PTHREAD_WARNSW);
#endif
#endif
#ifdef CANCEL_TYPE
	rc = pthread_setcanceltype(CANCEL_TYPE, NULL);
	check_err("pthread_setcanceltype()\n", rc);
#endif

	count_max = 2 * load_ms / 100;
	rt_printf("%s: counting till %d\n", __func__, count_max);
	while (count < count_max) {
		create_load_100ms();
		rt_printf("%s: at count %ld\n", __func__, count);
		count++;
	}

	rt_printf("%s: stopped at count %ld\n", __func__, count);

	calc_exit = 1;

	return NULL;
}

#ifdef USE_SIGXCPU
void mode_switch_handler(int sig)
{
        void *bt[32];
        int nentries;

        /* Dump a backtrace of the frame which caused the switch to
           secondary mode: */
        nentries = backtrace(bt,sizeof(bt) / sizeof(bt[0]));
        backtrace_symbols_fd(bt, nentries, fileno(stdout));
}
#endif

int main(int argc, char **argv)
{
	int rc = 0;
	void *status;
#ifdef USE_EXPLICIT_SCHED
	pthread_attr_t calc_attr, ctrl_attr;
	struct sched_param calc_param, ctrl_param;
#endif

	if (argc == 2)
		load_ms = atoi(argv[1]);

	/* Lock process memory */
	mlockall(MCL_CURRENT | MCL_FUTURE);

#ifdef USE_SIGXCPU
	signal(SIGXCPU, mode_switch_handler);
#endif
#ifdef __XENO__
	/* We use rt_printf() for debugging real-time code */
	rt_print_auto_init(1);
	rt_printf("Real-Time debugging started\n");
#endif

#ifdef USE_EXPLICIT_SCHED
	memset(&ctrl_param, 0 , sizeof(ctrl_param));
	pthread_attr_init(&ctrl_attr);
	pthread_attr_setschedpolicy(&ctrl_attr, SCHED_FIFO);
 	ctrl_param.sched_priority = CTRL_PRIO;
	pthread_attr_setschedparam(&ctrl_attr, &ctrl_param);
	pthread_attr_setinheritsched(&ctrl_attr, PTHREAD_EXPLICIT_SCHED);
	rc = pthread_create(&ctrl_thread, &ctrl_attr, ctrl_func, NULL);
#else
	rc = pthread_create(&ctrl_thread, NULL, ctrl_func, NULL);
#endif
	check_err("pthread_create()\n", rc);

#ifdef USE_EXPLICIT_SCHED
	memset(&calc_param, 0 , sizeof(calc_param));
	pthread_attr_init(&calc_attr);
	pthread_attr_setschedpolicy(&calc_attr, SCHED_FIFO);
	calc_param.sched_priority = CALC_PRIO;
	pthread_attr_setschedparam(&calc_attr, &calc_param);
	pthread_attr_setinheritsched(&calc_attr, PTHREAD_EXPLICIT_SCHED);
	rc = pthread_create(&calc_thread, &calc_attr, calc_func, NULL);
#else
	rc = pthread_create(&calc_thread, NULL, calc_func, NULL);
#endif
	check_err("pthread_create()\n", rc);

	rc = pthread_join(calc_thread, &status);
	check_err("pthread_join()\n", rc);

	if (status != PTHREAD_CANCELED)
		printf("Unexpected thread status\n");

	printf("main terminating in 2 seconds...\n");
	sleep(3);
	return 0;
}

[-- Attachment #3: Makefile --]
[-- Type: text/plain, Size: 524 bytes --]

APP := cancel-test

CFLAGS = -Wall -O0 -g

ifeq ($(XENO),)

CC = gcc
LDFLAGS = -lpthread -lrt

else

XENOCONFIG = \
$(shell PATH=$(XENO):$(XENO)/bin:$(PATH) which xeno-config 2>/dev/null)

CC = $(shell $(XENOCONFIG) --cc)
LD = $(patsubst %-gcc,%-ld,$(CC))
CFLAGS += $(shell $(XENOCONFIG) --posix-cflags)
LDFLAGS = $(shell $(XENOCONFIG) --posix-ldflags) -lrtdk
LDFLAGS += -Xlinker -rpath -Xlinker $(shell $(XENOCONFIG) --libdir)

endif

all: $(APP)

$(APP): % : %.c
	$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)

clean:
	$(RM) $(APP)

  reply	other threads:[~2008-12-02 15:59 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-30 21:34 [Xenomai-help] pthread cancelation and scheduling magics Wolfgang Grandegger
2008-11-30 21:46 ` Gilles Chanteperdrix
2008-11-30 21:59 ` Gilles Chanteperdrix
2008-12-01 10:22   ` Gilles Chanteperdrix
2008-12-01 14:16     ` Wolfgang Grandegger
2008-12-01 14:15       ` Gilles Chanteperdrix
2008-12-01 15:10         ` Gilles Chanteperdrix
2008-12-02 15:59           ` Wolfgang Grandegger [this message]
2008-12-02 15:55             ` Gilles Chanteperdrix
2008-12-02 18:18               ` Wolfgang Grandegger
2008-12-02 18:35                 ` Gilles Chanteperdrix
2008-12-02 19:50                   ` Wolfgang Grandegger
2008-12-02 20:03                     ` Philippe Gerum
2008-12-07 16:05                   ` Wolfgang Grandegger
2008-12-10 11:16                     ` Wolfgang Grandegger
2008-12-11 15:26                       ` Jan Kiszka
2008-12-13 15:55                         ` Wolfgang Grandegger
2009-01-01 13:34                       ` Gilles Chanteperdrix
2009-01-01 17:07                         ` Philippe Gerum
2009-01-01 18:00                           ` Gilles Chanteperdrix
2009-01-09 13:08                           ` Gilles Chanteperdrix
2009-01-09 13:38                             ` Philippe Gerum
2009-01-01 17:10                         ` Wolfgang Grandegger
2009-01-01 18:11                           ` Gilles Chanteperdrix
2008-12-03 10:16                 ` Gilles Chanteperdrix
2008-12-03 11:19                   ` Wolfgang Grandegger
2008-12-03 13:30                     ` Gilles Chanteperdrix
2008-12-03 18:02                       ` Wolfgang Grandegger
2008-12-03 17:57                         ` Gilles Chanteperdrix
2008-12-03 18:37                           ` Wolfgang Grandegger
2008-12-03 18:32                             ` Gilles Chanteperdrix
2008-12-03 18:55                               ` Wolfgang Grandegger
2008-12-03 18:55                                 ` Gilles Chanteperdrix
2008-12-03 19:19                                   ` Wolfgang Grandegger
2008-12-03 19:19                                     ` Gilles Chanteperdrix
2008-12-03 20:02                                       ` Wolfgang Grandegger
2008-12-03 20:02                                         ` Gilles Chanteperdrix
2008-12-04 15:29                                           ` Wolfgang Grandegger
2008-12-04 15:38                                             ` Gilles Chanteperdrix
2008-12-04 15:42                                               ` Gilles Chanteperdrix
2008-12-04 16:31                                               ` Wolfgang Grandegger
2008-12-04 16:26                                                 ` Gilles Chanteperdrix
2008-12-04 16:49                                                   ` Wolfgang Grandegger
2008-12-04 17:02                                                     ` Gilles Chanteperdrix
2008-12-04 17:52                                                       ` Wolfgang Grandegger
2008-12-04 17:51                                                         ` Gilles Chanteperdrix
2008-12-05 14:58                                                       ` Wolfgang Grandegger
2008-12-03  8:04         ` Wolfgang Grandegger
2008-12-03 10:12           ` Gilles Chanteperdrix
2008-12-03 10:46             ` Wolfgang Grandegger
2008-12-03 10:40               ` Gilles Chanteperdrix
2008-12-03 11:16                 ` Wolfgang Grandegger
2008-12-03 11:11               ` Philippe Gerum
2008-12-03 11:22                 ` Wolfgang Grandegger
2008-12-01 13:31   ` Wolfgang Grandegger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=49355B5D.8070802@domain.hid \
    --to=wg@domain.hid \
    --cc=gilles.chanteperdrix@xenomai.org \
    --cc=xenomai@xenomai.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.