All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-core] How to cancel a Xenomai POSIX thread
@ 2007-12-06 12:31 Wolfgang Grandegger
  2007-12-06 13:13 ` Gilles Chanteperdrix
  0 siblings, 1 reply; 33+ messages in thread
From: Wolfgang Grandegger @ 2007-12-06 12:31 UTC (permalink / raw)
  To: xenomai-core

Hello,

how do I cancel or delete a Xenomai POSIX thread running in primary
context from a higher priority thread? IIUC, pthread_kill() can only be
used in secondary context. I tried pthread_cancel(), but it only works
when hitting a cancelation point, e.g. pthread_testcancel(). Setting
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS) did not help. Is
there a code snippet or even an example program showing how to cancel a
pthread in primary context?

TIA,

Wolfgang.



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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-06 12:31 [Xenomai-core] How to cancel a Xenomai POSIX thread Wolfgang Grandegger
@ 2007-12-06 13:13 ` Gilles Chanteperdrix
  2007-12-06 13:24   ` Wolfgang Grandegger
  0 siblings, 1 reply; 33+ messages in thread
From: Gilles Chanteperdrix @ 2007-12-06 13:13 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: xenomai-core

On Dec 6, 2007 1:31 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
> Hello,
>
> how do I cancel or delete a Xenomai POSIX thread running in primary
> context from a higher priority thread? IIUC, pthread_kill() can only be
> used in secondary context. I tried pthread_cancel(), but it only works
> when hitting a cancelation point, e.g. pthread_testcancel(). Setting
> pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS) did not help. Is
> there a code snippet or even an example program showing how to cancel a
> pthread in primary context?

pthread_kill or pthread_cancel should result in sending a signal to
the target thread, so should cause this thread to switch to secondary
mode to handle it. If you want to wait for the target thread to be
canceled, you should use pthread_cancel and pthread_join.

-- 
                                               Gilles Chanteperdrix


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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-06 13:13 ` Gilles Chanteperdrix
@ 2007-12-06 13:24   ` Wolfgang Grandegger
  2007-12-06 13:28     ` Gilles Chanteperdrix
  0 siblings, 1 reply; 33+ messages in thread
From: Wolfgang Grandegger @ 2007-12-06 13:24 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai-core

Gilles Chanteperdrix wrote:
> On Dec 6, 2007 1:31 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>> Hello,
>>
>> how do I cancel or delete a Xenomai POSIX thread running in primary
>> context from a higher priority thread? IIUC, pthread_kill() can only be
>> used in secondary context. I tried pthread_cancel(), but it only works
>> when hitting a cancelation point, e.g. pthread_testcancel(). Setting
>> pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS) did not help. Is
>> there a code snippet or even an example program showing how to cancel a
>> pthread in primary context?
> 
> pthread_kill or pthread_cancel should result in sending a signal to
> the target thread, so should cause this thread to switch to secondary
> mode to handle it. If you want to wait for the target thread to be
> canceled, you should use pthread_cancel and pthread_join.

There is no way to cancel a pthread in primary mode from another pthread?

Wolfgang.



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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-06 13:24   ` Wolfgang Grandegger
@ 2007-12-06 13:28     ` Gilles Chanteperdrix
  2007-12-06 13:44       ` Gilles Chanteperdrix
  2007-12-06 13:47       ` Wolfgang Grandegger
  0 siblings, 2 replies; 33+ messages in thread
From: Gilles Chanteperdrix @ 2007-12-06 13:28 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: xenomai-core

On Dec 6, 2007 2:24 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>
> Gilles Chanteperdrix wrote:
> > On Dec 6, 2007 1:31 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
> >> Hello,
> >>
> >> how do I cancel or delete a Xenomai POSIX thread running in primary
> >> context from a higher priority thread? IIUC, pthread_kill() can only be
> >> used in secondary context. I tried pthread_cancel(), but it only works
> >> when hitting a cancelation point, e.g. pthread_testcancel(). Setting
> >> pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS) did not help. Is
> >> there a code snippet or even an example program showing how to cancel a
> >> pthread in primary context?
> >
> > pthread_kill or pthread_cancel should result in sending a signal to
> > the target thread, so should cause this thread to switch to secondary
> > mode to handle it. If you want to wait for the target thread to be
> > canceled, you should use pthread_cancel and pthread_join.
>
> There is no way to cancel a pthread in primary mode from another pthread?

No. You always need secondary mode to effectively delete a thread. The
same goes for the native skin.

-- 
                                               Gilles Chanteperdrix


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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-06 13:28     ` Gilles Chanteperdrix
@ 2007-12-06 13:44       ` Gilles Chanteperdrix
  2007-12-06 14:05         ` Wolfgang Grandegger
  2007-12-06 13:47       ` Wolfgang Grandegger
  1 sibling, 1 reply; 33+ messages in thread
From: Gilles Chanteperdrix @ 2007-12-06 13:44 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: xenomai-core

On Dec 6, 2007 2:28 PM, Gilles Chanteperdrix
<gilles.chanteperdrix@xenomai.org> wrote:
>
> On Dec 6, 2007 2:24 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
> >
> > Gilles Chanteperdrix wrote:
> > > On Dec 6, 2007 1:31 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
> > >> Hello,
> > >>
> > >> how do I cancel or delete a Xenomai POSIX thread running in primary
> > >> context from a higher priority thread? IIUC, pthread_kill() can only be
> > >> used in secondary context. I tried pthread_cancel(), but it only works
> > >> when hitting a cancelation point, e.g. pthread_testcancel(). Setting
> > >> pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS) did not help. Is
> > >> there a code snippet or even an example program showing how to cancel a
> > >> pthread in primary context?
> > >
> > > pthread_kill or pthread_cancel should result in sending a signal to
> > > the target thread, so should cause this thread to switch to secondary
> > > mode to handle it. If you want to wait for the target thread to be
> > > canceled, you should use pthread_cancel and pthread_join.
> >
> > There is no way to cancel a pthread in primary mode from another pthread?
>
> No. You always need secondary mode to effectively delete a thread. The
> same goes for the native skin.

Ok. I understand what you mean. You want pthread_cancel not to leave
primary mode. This can easily be done by causing pthread_cancel to use
the kernel-space real-time pthread_cancel service. This should work
with no further modification.

-- 
                                               Gilles Chanteperdrix


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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-06 13:28     ` Gilles Chanteperdrix
  2007-12-06 13:44       ` Gilles Chanteperdrix
@ 2007-12-06 13:47       ` Wolfgang Grandegger
  1 sibling, 0 replies; 33+ messages in thread
From: Wolfgang Grandegger @ 2007-12-06 13:47 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai-core

Gilles Chanteperdrix wrote:
> On Dec 6, 2007 2:24 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>> Gilles Chanteperdrix wrote:
>>> On Dec 6, 2007 1:31 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>>>> Hello,
>>>>
>>>> how do I cancel or delete a Xenomai POSIX thread running in primary
>>>> context from a higher priority thread? IIUC, pthread_kill() can only be
>>>> used in secondary context. I tried pthread_cancel(), but it only works
>>>> when hitting a cancelation point, e.g. pthread_testcancel(). Setting
>>>> pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS) did not help. Is
>>>> there a code snippet or even an example program showing how to cancel a
>>>> pthread in primary context?
>>> pthread_kill or pthread_cancel should result in sending a signal to
>>> the target thread, so should cause this thread to switch to secondary
>>> mode to handle it. If you want to wait for the target thread to be
>>> canceled, you should use pthread_cancel and pthread_join.
>> There is no way to cancel a pthread in primary mode from another pthread?
> 
> No. You always need secondary mode to effectively delete a thread. The
> same goes for the native skin.

OK, I see, but I could force the pthread to secondary mode using
pthread_setschedparam(id, SCHED_OTHER, &param) from outside!?

Thanks for your quick help.

Wolfgang.



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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-06 13:44       ` Gilles Chanteperdrix
@ 2007-12-06 14:05         ` Wolfgang Grandegger
  2007-12-06 14:21           ` Gilles Chanteperdrix
  0 siblings, 1 reply; 33+ messages in thread
From: Wolfgang Grandegger @ 2007-12-06 14:05 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai-core

Gilles Chanteperdrix wrote:
> On Dec 6, 2007 2:28 PM, Gilles Chanteperdrix
> <gilles.chanteperdrix@xenomai.org> wrote:
>> On Dec 6, 2007 2:24 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>>> Gilles Chanteperdrix wrote:
>>>> On Dec 6, 2007 1:31 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>>>>> Hello,
>>>>>
>>>>> how do I cancel or delete a Xenomai POSIX thread running in primary
>>>>> context from a higher priority thread? IIUC, pthread_kill() can only be
>>>>> used in secondary context. I tried pthread_cancel(), but it only works
>>>>> when hitting a cancelation point, e.g. pthread_testcancel(). Setting
>>>>> pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS) did not help. Is
>>>>> there a code snippet or even an example program showing how to cancel a
>>>>> pthread in primary context?
>>>> pthread_kill or pthread_cancel should result in sending a signal to
>>>> the target thread, so should cause this thread to switch to secondary
>>>> mode to handle it. If you want to wait for the target thread to be
>>>> canceled, you should use pthread_cancel and pthread_join.
>>> There is no way to cancel a pthread in primary mode from another pthread?
>> No. You always need secondary mode to effectively delete a thread. The
>> same goes for the native skin.
> 
> Ok. I understand what you mean. You want pthread_cancel not to leave
> primary mode. This can easily be done by causing pthread_cancel to use
> the kernel-space real-time pthread_cancel service. This should work
> with no further modification.

I want to cancel/delete a task running in primary mode, e.g.

  void* work_task(void* dummy)
  {
	int count = 0;
	while (1)
		count++;
  }

from the outside (= another higher priority task). How can I use the
kernel-space real-time pthread_cancel service? My POSIX app is runs in
user-land.

Wolfgang.



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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-06 14:05         ` Wolfgang Grandegger
@ 2007-12-06 14:21           ` Gilles Chanteperdrix
  2007-12-07 14:03             ` Wolfgang Grandegger
  0 siblings, 1 reply; 33+ messages in thread
From: Gilles Chanteperdrix @ 2007-12-06 14:21 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: xenomai-core

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

On Dec 6, 2007 3:05 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>
> Gilles Chanteperdrix wrote:
> > On Dec 6, 2007 2:28 PM, Gilles Chanteperdrix
> > <gilles.chanteperdrix@xenomai.org> wrote:
> >> On Dec 6, 2007 2:24 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
> >>> Gilles Chanteperdrix wrote:
> >>>> On Dec 6, 2007 1:31 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
> >>>>> Hello,
> >>>>>
> >>>>> how do I cancel or delete a Xenomai POSIX thread running in primary
> >>>>> context from a higher priority thread? IIUC, pthread_kill() can only be
> >>>>> used in secondary context. I tried pthread_cancel(), but it only works
> >>>>> when hitting a cancelation point, e.g. pthread_testcancel(). Setting
> >>>>> pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS) did not help. Is
> >>>>> there a code snippet or even an example program showing how to cancel a
> >>>>> pthread in primary context?
> >>>> pthread_kill or pthread_cancel should result in sending a signal to
> >>>> the target thread, so should cause this thread to switch to secondary
> >>>> mode to handle it. If you want to wait for the target thread to be
> >>>> canceled, you should use pthread_cancel and pthread_join.
> >>> There is no way to cancel a pthread in primary mode from another pthread?
> >> No. You always need secondary mode to effectively delete a thread. The
> >> same goes for the native skin.
> >
> > Ok. I understand what you mean. You want pthread_cancel not to leave
> > primary mode. This can easily be done by causing pthread_cancel to use
> > the kernel-space real-time pthread_cancel service. This should work
> > with no further modification.
>
> I want to cancel/delete a task running in primary mode, e.g.
>
>   void* work_task(void* dummy)
>   {
>         int count = 0;
>         while (1)
>                 count++;
>   }
>
> from the outside (= another higher priority task). How can I use the
> kernel-space real-time pthread_cancel service? My POSIX app is runs in
> user-land.

I was thinking about adding a pthread_cancel syscall that would have
triggered the kernel-space pthread_cancel. But this will not work:
user-space cleanup handlers would no longer get executed. However,
this can work for pthread_kill. Here is a patch which adds the
pthread_kill syscall.


-- 
                                               Gilles Chanteperdrix

[-- Attachment #2: xeno-posix-primary-mode-pthread_kill.diff --]
[-- Type: application/octet-stream, Size: 2460 bytes --]

Index: include/posix/syscall.h
===================================================================
--- include/posix/syscall.h	(révision 3242)
+++ include/posix/syscall.h	(copie de travail)
@@ -99,6 +99,7 @@
 #define __pse51_condattr_getpshared   73
 #define __pse51_condattr_setpshared   74
 #define __pse51_thread_getschedparam  75
+#define __pse51_thread_kill           76
 
 #ifdef __KERNEL__
 
Index: src/skins/posix/thread.c
===================================================================
--- src/skins/posix/thread.c	(révision 3242)
+++ src/skins/posix/thread.c	(copie de travail)
@@ -245,3 +245,15 @@
 	return -XENOMAI_SKINCALL2(__pse51_muxid,
 				  __pse51_thread_set_name, thread, name);
 }
+
+int __wrap_pthread_kill(pthread_t thread, int sig)
+{
+	int err;
+	err = -XENOMAI_SKINCALL2(__pse51_muxid,
+				 __pse51_thread_kill, thread, sig);
+
+	if (err == ESRCH)
+		return __real_pthread_kill(thread, sig);
+
+	return err;
+}
Index: src/skins/posix/posix.wrappers
===================================================================
--- src/skins/posix/posix.wrappers	(révision 3242)
+++ src/skins/posix/posix.wrappers	(copie de travail)
@@ -3,6 +3,7 @@
 --wrap pthread_getschedparam
 --wrap pthread_yield
 --wrap sched_yield
+--wrap pthread_kill
 --wrap sem_init
 --wrap sem_destroy
 --wrap sem_post
Index: ksrc/skins/posix/syscall.c
===================================================================
--- ksrc/skins/posix/syscall.c	(révision 3242)
+++ ksrc/skins/posix/syscall.c	(copie de travail)
@@ -396,6 +396,21 @@
 	return -pthread_set_name_np(k_tid, name);
 }
 
+static int __pthread_kill(struct task_struct *curr, struct pt_regs *regs)
+{
+	struct pse51_hkey hkey;
+	pthread_t k_tid;
+
+	hkey.u_tid = __xn_reg_arg1(regs);
+	hkey.mm = curr->mm;
+	k_tid = __pthread_find(&hkey);
+
+	if(!k_tid)
+		return -ESRCH;
+
+	return -pthread_kill(k_tid, __xn_reg_arg2(regs));
+}
+
 static int __sem_init(struct task_struct *curr, struct pt_regs *regs)
 {
 	union __xeno_sem sm, *usm;
@@ -2653,6 +2668,7 @@
 	[__pse51_thread_wait] = {&__pthread_wait_np, __xn_exec_primary},
 	[__pse51_thread_set_mode] = {&__pthread_set_mode_np, __xn_exec_primary},
 	[__pse51_thread_set_name] = {&__pthread_set_name_np, __xn_exec_any},
+	[__pse51_thread_kill] = {&__pthread_kill, __xn_exec_any},
 	[__pse51_sem_init] = {&__sem_init, __xn_exec_any},
 	[__pse51_sem_destroy] = {&__sem_destroy, __xn_exec_any},
 	[__pse51_sem_post] = {&__sem_post, __xn_exec_any},

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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-06 14:21           ` Gilles Chanteperdrix
@ 2007-12-07 14:03             ` Wolfgang Grandegger
  2007-12-07 21:23               ` Gilles Chanteperdrix
  0 siblings, 1 reply; 33+ messages in thread
From: Wolfgang Grandegger @ 2007-12-07 14:03 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai-core

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

Hi Gilles,

Gilles Chanteperdrix wrote:
> On Dec 6, 2007 3:05 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>> Gilles Chanteperdrix wrote:
>>> On Dec 6, 2007 2:28 PM, Gilles Chanteperdrix
>>> <gilles.chanteperdrix@xenomai.org> wrote:
>>>> On Dec 6, 2007 2:24 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>>>>> Gilles Chanteperdrix wrote:
>>>>>> On Dec 6, 2007 1:31 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>>>>>>> Hello,
>>>>>>>
>>>>>>> how do I cancel or delete a Xenomai POSIX thread running in primary
>>>>>>> context from a higher priority thread? IIUC, pthread_kill() can only be
>>>>>>> used in secondary context. I tried pthread_cancel(), but it only works
>>>>>>> when hitting a cancelation point, e.g. pthread_testcancel(). Setting
>>>>>>> pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS) did not help. Is
>>>>>>> there a code snippet or even an example program showing how to cancel a
>>>>>>> pthread in primary context?
>>>>>> pthread_kill or pthread_cancel should result in sending a signal to
>>>>>> the target thread, so should cause this thread to switch to secondary
>>>>>> mode to handle it. If you want to wait for the target thread to be
>>>>>> canceled, you should use pthread_cancel and pthread_join.
>>>>> There is no way to cancel a pthread in primary mode from another pthread?
>>>> No. You always need secondary mode to effectively delete a thread. The
>>>> same goes for the native skin.
>>> Ok. I understand what you mean. You want pthread_cancel not to leave
>>> primary mode. This can easily be done by causing pthread_cancel to use
>>> the kernel-space real-time pthread_cancel service. This should work
>>> with no further modification.
>> I want to cancel/delete a task running in primary mode, e.g.
>>
>>   void* work_task(void* dummy)
>>   {
>>         int count = 0;
>>         while (1)
>>                 count++;
>>   }
>>
>> from the outside (= another higher priority task). How can I use the
>> kernel-space real-time pthread_cancel service? My POSIX app is runs in
>> user-land.
> 
> I was thinking about adding a pthread_cancel syscall that would have
> triggered the kernel-space pthread_cancel. But this will not work:
> user-space cleanup handlers would no longer get executed. However,
> this can work for pthread_kill. Here is a patch which adds the
> pthread_kill syscall.

Great, thanks a lot. This seems to work but I'm now fiddling with proper
cleanup and exit. I have attached my small test program. It behaves
somehow strange, at least to me:

- I see task period overruns when the low prio task is started. I
  suspect some switch to secondary mode in init_task().

- The program/system hangs after the listed messages:

  # ./kill_pthread
  Starting high_prio_task
  Killed low_prio task: count=3813129, overruns=0

Any idea what I'm doing wrong?

This is with Linux 2.4.25 and Xenomai 2.3.x on a MPC5200 board.

TIA.

Wolfgang.


[-- Attachment #2: kill_pthread.c --]
[-- Type: text/x-csrc, Size: 2986 bytes --]

#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <sys/mman.h>

static int count;

static pthread_t id_low;
static pthread_t id_high;

#define LOW_PRIO 5
#define HIGH_PRIO 10

#undef WITH_PRINTF
#undef WITH_SIGXCPU

void init_task(int prio);

void* low_prio_task(void* dummy)
{

   while (1)
   {
#ifdef WITH_PRINTF
	   printf("%s %d\n", __FUNCTION__, count);
#endif
	   count++;
   }
   printf("Exiting %s, count=%d\n", __FUNCTION__, count);
   return 0;
}

void* high_prio_task(void* dummy)
{
	struct timespec tstart = { .tv_sec = 0, .tv_nsec = 0};
#ifdef WITH_PRINTF
	struct timespec tperiod = { .tv_sec = 0, .tv_nsec = 10000000 };
#else
	struct timespec tperiod = { .tv_sec = 0, .tv_nsec = 1000000 };
#endif
	unsigned long overruns = 0;
	int tick = 0, step = 0, loop = 0, err;

	printf("Starting %s\n", __FUNCTION__);

#ifdef WITH_SIGXCPU
	pthread_set_mode_np(0, PTHREAD_WARNSW);
#endif
	err = pthread_make_periodic_np(pthread_self(), &tstart, &tperiod);
	if (err)
		return (void *)err;

	while (1) {
		err = pthread_wait_np(&overruns);
#if 0
		if (err) {
			pthread_kill(id_low, SIGSTOP);
			printf("%s overruns=%lu, tick=%d, count=%d, err=%d\n",
			       __FUNCTION__, overruns, tick, count, err);
			return 0;
		}
#endif
		if  (step == 0 && loop > 100) {
			loop = 0;
			step = 1;
			init_task(LOW_PRIO);
		}
		else if (step == 1 && loop > 50) {
			loop = 0;
			step = 0;
			pthread_kill(id_low, SIGSTOP);
			printf("Killed low_prio task: count=%d, overruns=%lu\n",
			       count, overruns);
			return 0;
		}
		tick++;
		loop++;
	}
	printf("Exiting %s\n", __FUNCTION__);
	return 0;
}

void init_task(int prio)
{
   struct sched_param parm;
   pthread_attr_t attr;

   pthread_attr_init(&attr);
   if (prio == HIGH_PRIO)
	   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
   else
	   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
   pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
   parm.sched_priority = prio;
   pthread_attr_setschedparam(&attr, &parm);

   if (prio == HIGH_PRIO) {
	   pthread_create(&id_high, &attr, high_prio_task, NULL);
	   pthread_set_name_np(id_high,"high_prio");
   } else {
	   pthread_create(&id_low, &attr, low_prio_task, NULL);
	   pthread_set_name_np(id_low,"low_prio");
   }
}

void catch_signal(int sig)
{
	printf("Signal %d catched\n", sig);
}

#ifdef WITH_SIGXCPU
void catch_switch(int sig)
{
	void *bt[32];
	int nentries;

	printf("Signal %d catched\n", sig);

	/* 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[])
{
	mlockall(MCL_CURRENT|MCL_FUTURE);

	signal(SIGTERM, catch_signal);
	signal(SIGINT, catch_signal);
	signal(SIGHUP, catch_signal);
#ifdef WITH_SIGXCPU
	signal(SIGXCPU, catch_switch);
#endif
	init_task(HIGH_PRIO);

	pthread_join(id_high, NULL);

	printf("Exiting %s\n", __FUNCTION__);
	return 0;
}

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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-07 14:03             ` Wolfgang Grandegger
@ 2007-12-07 21:23               ` Gilles Chanteperdrix
  2007-12-07 22:10                 ` Gilles Chanteperdrix
  0 siblings, 1 reply; 33+ messages in thread
From: Gilles Chanteperdrix @ 2007-12-07 21:23 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: xenomai-core

Wolfgang Grandegger wrote:
 > Hi Gilles,
 > 
 > Gilles Chanteperdrix wrote:
 > > On Dec 6, 2007 3:05 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
 > >> Gilles Chanteperdrix wrote:
 > >>> On Dec 6, 2007 2:28 PM, Gilles Chanteperdrix
 > >>> <gilles.chanteperdrix@xenomai.org> wrote:
 > >>>> On Dec 6, 2007 2:24 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
 > >>>>> Gilles Chanteperdrix wrote:
 > >>>>>> On Dec 6, 2007 1:31 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
 > >>>>>>> Hello,
 > >>>>>>>
 > >>>>>>> how do I cancel or delete a Xenomai POSIX thread running in primary
 > >>>>>>> context from a higher priority thread? IIUC, pthread_kill() can only be
 > >>>>>>> used in secondary context. I tried pthread_cancel(), but it only works
 > >>>>>>> when hitting a cancelation point, e.g. pthread_testcancel(). Setting
 > >>>>>>> pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS) did not help. Is
 > >>>>>>> there a code snippet or even an example program showing how to cancel a
 > >>>>>>> pthread in primary context?
 > >>>>>> pthread_kill or pthread_cancel should result in sending a signal to
 > >>>>>> the target thread, so should cause this thread to switch to secondary
 > >>>>>> mode to handle it. If you want to wait for the target thread to be
 > >>>>>> canceled, you should use pthread_cancel and pthread_join.
 > >>>>> There is no way to cancel a pthread in primary mode from another pthread?
 > >>>> No. You always need secondary mode to effectively delete a thread. The
 > >>>> same goes for the native skin.
 > >>> Ok. I understand what you mean. You want pthread_cancel not to leave
 > >>> primary mode. This can easily be done by causing pthread_cancel to use
 > >>> the kernel-space real-time pthread_cancel service. This should work
 > >>> with no further modification.
 > >> I want to cancel/delete a task running in primary mode, e.g.
 > >>
 > >>   void* work_task(void* dummy)
 > >>   {
 > >>         int count = 0;
 > >>         while (1)
 > >>                 count++;
 > >>   }
 > >>
 > >> from the outside (= another higher priority task). How can I use the
 > >> kernel-space real-time pthread_cancel service? My POSIX app is runs in
 > >> user-land.
 > > 
 > > I was thinking about adding a pthread_cancel syscall that would have
 > > triggered the kernel-space pthread_cancel. But this will not work:
 > > user-space cleanup handlers would no longer get executed. However,
 > > this can work for pthread_kill. Here is a patch which adds the
 > > pthread_kill syscall.
 > 
 > Great, thanks a lot. This seems to work but I'm now fiddling with proper
 > cleanup and exit. I have attached my small test program. It behaves
 > somehow strange, at least to me:
 > 
 > - I see task period overruns when the low prio task is started. I
 >   suspect some switch to secondary mode in init_task().
 > 
 > - The program/system hangs after the listed messages:
 > 
 >   # ./kill_pthread
 >   Starting high_prio_task
 >   Killed low_prio task: count=3813129, overruns=0
 > 
 > Any idea what I'm doing wrong?
 > 
 > This is with Linux 2.4.25 and Xenomai 2.3.x on a MPC5200 board.

Your test runs fine with Xenomai trunk (on ARM). I will now try with
current state of the v2.3.x branch.

-- 


					    Gilles Chanteperdrix.


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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-07 21:23               ` Gilles Chanteperdrix
@ 2007-12-07 22:10                 ` Gilles Chanteperdrix
  2007-12-09 21:55                   ` Wolfgang Grandegger
  0 siblings, 1 reply; 33+ messages in thread
From: Gilles Chanteperdrix @ 2007-12-07 22:10 UTC (permalink / raw)
  To: Wolfgang Grandegger, xenomai-core

Gilles Chanteperdrix wrote:
 > Wolfgang Grandegger wrote:
 >  > Hi Gilles,
 >  > 
 >  > Gilles Chanteperdrix wrote:
 >  > > On Dec 6, 2007 3:05 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
 >  > >> Gilles Chanteperdrix wrote:
 >  > >>> On Dec 6, 2007 2:28 PM, Gilles Chanteperdrix
 >  > >>> <gilles.chanteperdrix@xenomai.org> wrote:
 >  > >>>> On Dec 6, 2007 2:24 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
 >  > >>>>> Gilles Chanteperdrix wrote:
 >  > >>>>>> On Dec 6, 2007 1:31 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
 >  > >>>>>>> Hello,
 >  > >>>>>>>
 >  > >>>>>>> how do I cancel or delete a Xenomai POSIX thread running in primary
 >  > >>>>>>> context from a higher priority thread? IIUC, pthread_kill() can only be
 >  > >>>>>>> used in secondary context. I tried pthread_cancel(), but it only works
 >  > >>>>>>> when hitting a cancelation point, e.g. pthread_testcancel(). Setting
 >  > >>>>>>> pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS) did not help. Is
 >  > >>>>>>> there a code snippet or even an example program showing how to cancel a
 >  > >>>>>>> pthread in primary context?
 >  > >>>>>> pthread_kill or pthread_cancel should result in sending a signal to
 >  > >>>>>> the target thread, so should cause this thread to switch to secondary
 >  > >>>>>> mode to handle it. If you want to wait for the target thread to be
 >  > >>>>>> canceled, you should use pthread_cancel and pthread_join.
 >  > >>>>> There is no way to cancel a pthread in primary mode from another pthread?
 >  > >>>> No. You always need secondary mode to effectively delete a thread. The
 >  > >>>> same goes for the native skin.
 >  > >>> Ok. I understand what you mean. You want pthread_cancel not to leave
 >  > >>> primary mode. This can easily be done by causing pthread_cancel to use
 >  > >>> the kernel-space real-time pthread_cancel service. This should work
 >  > >>> with no further modification.
 >  > >> I want to cancel/delete a task running in primary mode, e.g.
 >  > >>
 >  > >>   void* work_task(void* dummy)
 >  > >>   {
 >  > >>         int count = 0;
 >  > >>         while (1)
 >  > >>                 count++;
 >  > >>   }
 >  > >>
 >  > >> from the outside (= another higher priority task). How can I use the
 >  > >> kernel-space real-time pthread_cancel service? My POSIX app is runs in
 >  > >> user-land.
 >  > > 
 >  > > I was thinking about adding a pthread_cancel syscall that would have
 >  > > triggered the kernel-space pthread_cancel. But this will not work:
 >  > > user-space cleanup handlers would no longer get executed. However,
 >  > > this can work for pthread_kill. Here is a patch which adds the
 >  > > pthread_kill syscall.
 >  > 
 >  > Great, thanks a lot. This seems to work but I'm now fiddling with proper
 >  > cleanup and exit. I have attached my small test program. It behaves
 >  > somehow strange, at least to me:
 >  > 
 >  > - I see task period overruns when the low prio task is started. I
 >  >   suspect some switch to secondary mode in init_task().
 >  > 
 >  > - The program/system hangs after the listed messages:
 >  > 
 >  >   # ./kill_pthread
 >  >   Starting high_prio_task
 >  >   Killed low_prio task: count=3813129, overruns=0
 >  > 
 >  > Any idea what I'm doing wrong?
 >  > 
 >  > This is with Linux 2.4.25 and Xenomai 2.3.x on a MPC5200 board.
 > 
 > Your test runs fine with Xenomai trunk (on ARM). I will now try with
 > current state of the v2.3.x branch.

Works with v2.3.x too.

-- 


					    Gilles Chanteperdrix.


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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-07 22:10                 ` Gilles Chanteperdrix
@ 2007-12-09 21:55                   ` Wolfgang Grandegger
  2007-12-09 22:52                     ` Gilles Chanteperdrix
  0 siblings, 1 reply; 33+ messages in thread
From: Wolfgang Grandegger @ 2007-12-09 21:55 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai-core

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

Gilles Chanteperdrix wrote:
> Gilles Chanteperdrix wrote:
>  > Wolfgang Grandegger wrote:
>  >  > Hi Gilles,
>  >  > 
>  >  > Gilles Chanteperdrix wrote:
>  >  > > On Dec 6, 2007 3:05 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>  >  > >> Gilles Chanteperdrix wrote:
>  >  > >>> On Dec 6, 2007 2:28 PM, Gilles Chanteperdrix
>  >  > >>> <gilles.chanteperdrix@xenomai.org> wrote:
>  >  > >>>> On Dec 6, 2007 2:24 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>  >  > >>>>> Gilles Chanteperdrix wrote:
>  >  > >>>>>> On Dec 6, 2007 1:31 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>  >  > >>>>>>> Hello,
>  >  > >>>>>>>
>  >  > >>>>>>> how do I cancel or delete a Xenomai POSIX thread running in primary
>  >  > >>>>>>> context from a higher priority thread? IIUC, pthread_kill() can only be
>  >  > >>>>>>> used in secondary context. I tried pthread_cancel(), but it only works
>  >  > >>>>>>> when hitting a cancelation point, e.g. pthread_testcancel(). Setting
>  >  > >>>>>>> pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS) did not help. Is
>  >  > >>>>>>> there a code snippet or even an example program showing how to cancel a
>  >  > >>>>>>> pthread in primary context?
>  >  > >>>>>> pthread_kill or pthread_cancel should result in sending a signal to
>  >  > >>>>>> the target thread, so should cause this thread to switch to secondary
>  >  > >>>>>> mode to handle it. If you want to wait for the target thread to be
>  >  > >>>>>> canceled, you should use pthread_cancel and pthread_join.
>  >  > >>>>> There is no way to cancel a pthread in primary mode from another pthread?
>  >  > >>>> No. You always need secondary mode to effectively delete a thread. The
>  >  > >>>> same goes for the native skin.
>  >  > >>> Ok. I understand what you mean. You want pthread_cancel not to leave
>  >  > >>> primary mode. This can easily be done by causing pthread_cancel to use
>  >  > >>> the kernel-space real-time pthread_cancel service. This should work
>  >  > >>> with no further modification.
>  >  > >> I want to cancel/delete a task running in primary mode, e.g.
>  >  > >>
>  >  > >>   void* work_task(void* dummy)
>  >  > >>   {
>  >  > >>         int count = 0;
>  >  > >>         while (1)
>  >  > >>                 count++;
>  >  > >>   }
>  >  > >>
>  >  > >> from the outside (= another higher priority task). How can I use the
>  >  > >> kernel-space real-time pthread_cancel service? My POSIX app is runs in
>  >  > >> user-land.
>  >  > > 
>  >  > > I was thinking about adding a pthread_cancel syscall that would have
>  >  > > triggered the kernel-space pthread_cancel. But this will not work:
>  >  > > user-space cleanup handlers would no longer get executed. However,
>  >  > > this can work for pthread_kill. Here is a patch which adds the
>  >  > > pthread_kill syscall.
>  >  > 
>  >  > Great, thanks a lot. This seems to work but I'm now fiddling with proper
>  >  > cleanup and exit. I have attached my small test program. It behaves
>  >  > somehow strange, at least to me:
>  >  > 
>  >  > - I see task period overruns when the low prio task is started. I
>  >  >   suspect some switch to secondary mode in init_task().
>  >  > 
>  >  > - The program/system hangs after the listed messages:
>  >  > 
>  >  >   # ./kill_pthread
>  >  >   Starting high_prio_task
>  >  >   Killed low_prio task: count=3813129, overruns=0
>  >  > 
>  >  > Any idea what I'm doing wrong?
>  >  > 
>  >  > This is with Linux 2.4.25 and Xenomai 2.3.x on a MPC5200 board.
>  > 
>  > Your test runs fine with Xenomai trunk (on ARM). I will now try with
>  > current state of the v2.3.x branch.
> 
> Works with v2.3.x too.

I re-activated my test PC running Linux 2.6.20.21. with Xenomai 2.3.x.
There the program runs fine _without_ your pthread_kill patch. For some
reason the low_prio_task() is running in secondary mode (do you know
why? Is there a function to check the mode?). I added

        struct sched_param  param = { .sched_priority = LOW_PRIO };
        pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);

to the head of that function and then I get:

  ./kill_pthread
  Starting high_prio_task
  BUG: NMI Watchdog detected LOCKUP
  Killed low_prio task: count=1588495996, overruns=0
  Exiting main

I have attached the corresponding oops in case it's of interest.
Unfortunately, with your patch and adding the function
__real_pthread_kill() to wrappers.c, the behavior is the same. I'm going
to repeat the tests with Xenomai trunk tomorrow.

Wolfgang.


[-- Attachment #2: oops.log --]
[-- Type: text/x-log, Size: 3364 bytes --]

BUG: NMI Watchdog detected LOCKUP<0>------------[ cut here ]------------
kernel BUG at kernel/ipipe/core.c:207!
invalid opcode: 0000 [#1]
PREEMPT 
Modules linked in: nfs lockd nfs_acl ipv6 autofs4 sunrpc dm_mod video sbs i2c_ec
 dock container button battery ac uhci_hcd parport_pc parport via686a hwmon i2c_
isa i2c_core snd_via82xx gameport snd_ac97_codec ac97_bus snd_seq_dummy snd_seq_
oss snd_seq_midi_event snd_seq snd_pcm_oss snd_mixer_oss snd_pcm snd_timer snd_p
age_alloc snd_mpu401_uart snd_rawmidi snd_seq_device snd soundcore 8139cp 8139to
o mii floppy ide_cd cdrom ext3 jbd
CPU:    0
EIP:    0060:[<c013fe91>]    Not tainted VLI
EFLAGS: 00010006   (2.6.20.21 #1)
EIP is at __ipipe_restore_root+0xc/0x22
eax: 00000001   ebx: c03c94a0   ecx: 00000001   edx: 00000004
esi: 00003533   edi: 00003554   ebp: 00003554   esp: db88ae48
ds: 007b   es: 007b   ss: 0068
Process kill_pthread (pid: 2507, ti=db88a000 task=df854250 task.ti=db88a000)
Stack: c0117f66 00003533 c0459660 00003533 c01185b4 00000400 00000000 ffffffdc 
       ffffffff db88afb8 c0439244 00000024 c0118bb4 db88af20 00000000 00000003 
       00000200 00000200 c047c650 c03165e6 dbfbdf20 c047c650 c047c650 c031656a 
Call Trace:
 [<c0117f66>] __call_console_drivers+0x42/0x4d
 [<c01185b4>] release_console_sem+0x141/0x1c2
 [<c0118bb4>] vprintk+0x28d/0x2fd
 [<c03165e6>] _spin_unlock_irqrestore+0x22/0x38
 [<c031656a>] _spin_unlock+0xf/0x23
 [<c014afab>] schedule_event+0x27c/0x2fb
 [<c0144ab3>] xnpod_renice_thread_inner+0x8a/0xcf
 [<c0118c70>] printk+0x4c/0xb5
 [<c0316d81>] die_nmi+0x6b/0xe6
 [<c03171a3>] default_nmi_watchdog_tick+0xda/0x1ba
 [<c0316e8d>] do_nmi+0x91/0x24e
 [<c013d7ba>] __ipipe_ack_level_irq+0x12/0x22
 [<c03168df>] nmi_stack_correct+0x26/0x2b
 =======================
Code: 0b eb fe fa 0f ba 35 80 46 3b c0 00 83 3d 84 46 3b c0 00 74 08 83 c8 ff e8
 fa f7 ff ff fb c3 81 3d 68 46 3b c0 80 05 48 c0 74 04 <0f> 0b eb fe 85 c0 74 09
 0f ba 2d 80 46 3b c0 00 c3 e9 b2 ff ff 
EIP: [<c013fe91>] __ipipe_restore_root+0xc/0x22 SS:ESP 0068:db88ae48
 <6>note: kill_pthread[2507] exited with preempt_count 2
BUG: sleeping function called from invalid context at mm/slab.c:3034
in_atomic():1, irqs_disabled():0
 [<c017bd85>] kmem_cache_zalloc+0x1b/0x92
 [<c0140725>] taskstats_exit+0x43/0x273
 [<c011a02b>] do_exit+0x1e0/0x75a
 [<c010445a>] die+0x1e9/0x1f1
 [<c0104820>] do_invalid_op+0xa2/0xab
 [<c013fe91>] __ipipe_restore_root+0xc/0x22
 [<c014713d>] xnpod_fault_handler+0x11b/0x123
 [<c0144343>] xnpod_trap_fault+0x2b/0x31
 [<c0142b70>] xnarch_trap_fault+0x0/0x1c
 [<c0142b88>] xnarch_trap_fault+0x18/0x1c
 [<c02b4542>] exception_event+0x25/0x34
 [<c01109e3>] __ipipe_handle_exception+0x124/0x163
 [<c031680d>] error_code+0x79/0x88
 [<c013fe91>] __ipipe_restore_root+0xc/0x22
 [<c0117f66>] __call_console_drivers+0x42/0x4d
 [<c01185b4>] release_console_sem+0x141/0x1c2
 [<c0118bb4>] vprintk+0x28d/0x2fd
 [<c03165e6>] _spin_unlock_irqrestore+0x22/0x38
 [<c031656a>] _spin_unlock+0xf/0x23
 [<c014afab>] schedule_event+0x27c/0x2fb
 [<c0144ab3>] xnpod_renice_thread_inner+0x8a/0xcf
 [<c0118c70>] printk+0x4c/0xb5
 [<c0316d81>] die_nmi+0x6b/0xe6
 [<c03171a3>] default_nmi_watchdog_tick+0xda/0x1ba
 [<c0316e8d>] do_nmi+0x91/0x24e
 [<c013d7ba>] __ipipe_ack_level_irq+0x12/0x22
 [<c03168df>] nmi_stack_correct+0x26/0x2b
 =======================
Xenomai: POSIX: destroyed thread c16e0610


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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-09 21:55                   ` Wolfgang Grandegger
@ 2007-12-09 22:52                     ` Gilles Chanteperdrix
  2007-12-10  7:27                       ` Wolfgang Grandegger
  2007-12-10 15:20                       ` Wolfgang Grandegger
  0 siblings, 2 replies; 33+ messages in thread
From: Gilles Chanteperdrix @ 2007-12-09 22:52 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: xenomai-core

Wolfgang Grandegger wrote:
 > Gilles Chanteperdrix wrote:
 > > Gilles Chanteperdrix wrote:
 > >  > Wolfgang Grandegger wrote:
 > >  >  > Hi Gilles,
 > >  >  > 
 > >  >  > Gilles Chanteperdrix wrote:
 > >  >  > > On Dec 6, 2007 3:05 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
 > >  >  > >> Gilles Chanteperdrix wrote:
 > >  >  > >>> On Dec 6, 2007 2:28 PM, Gilles Chanteperdrix
 > >  >  > >>> <gilles.chanteperdrix@xenomai.org> wrote:
 > >  >  > >>>> On Dec 6, 2007 2:24 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
 > >  >  > >>>>> Gilles Chanteperdrix wrote:
 > >  >  > >>>>>> On Dec 6, 2007 1:31 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
 > >  >  > >>>>>>> Hello,
 > >  >  > >>>>>>>
 > >  >  > >>>>>>> how do I cancel or delete a Xenomai POSIX thread running in primary
 > >  >  > >>>>>>> context from a higher priority thread? IIUC, pthread_kill() can only be
 > >  >  > >>>>>>> used in secondary context. I tried pthread_cancel(), but it only works
 > >  >  > >>>>>>> when hitting a cancelation point, e.g. pthread_testcancel(). Setting
 > >  >  > >>>>>>> pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS) did not help. Is
 > >  >  > >>>>>>> there a code snippet or even an example program showing how to cancel a
 > >  >  > >>>>>>> pthread in primary context?
 > >  >  > >>>>>> pthread_kill or pthread_cancel should result in sending a signal to
 > >  >  > >>>>>> the target thread, so should cause this thread to switch to secondary
 > >  >  > >>>>>> mode to handle it. If you want to wait for the target thread to be
 > >  >  > >>>>>> canceled, you should use pthread_cancel and pthread_join.
 > >  >  > >>>>> There is no way to cancel a pthread in primary mode from another pthread?
 > >  >  > >>>> No. You always need secondary mode to effectively delete a thread. The
 > >  >  > >>>> same goes for the native skin.
 > >  >  > >>> Ok. I understand what you mean. You want pthread_cancel not to leave
 > >  >  > >>> primary mode. This can easily be done by causing pthread_cancel to use
 > >  >  > >>> the kernel-space real-time pthread_cancel service. This should work
 > >  >  > >>> with no further modification.
 > >  >  > >> I want to cancel/delete a task running in primary mode, e.g.
 > >  >  > >>
 > >  >  > >>   void* work_task(void* dummy)
 > >  >  > >>   {
 > >  >  > >>         int count = 0;
 > >  >  > >>         while (1)
 > >  >  > >>                 count++;
 > >  >  > >>   }
 > >  >  > >>
 > >  >  > >> from the outside (= another higher priority task). How can I use the
 > >  >  > >> kernel-space real-time pthread_cancel service? My POSIX app is runs in
 > >  >  > >> user-land.
 > >  >  > > 
 > >  >  > > I was thinking about adding a pthread_cancel syscall that would have
 > >  >  > > triggered the kernel-space pthread_cancel. But this will not work:
 > >  >  > > user-space cleanup handlers would no longer get executed. However,
 > >  >  > > this can work for pthread_kill. Here is a patch which adds the
 > >  >  > > pthread_kill syscall.
 > >  >  > 
 > >  >  > Great, thanks a lot. This seems to work but I'm now fiddling with proper
 > >  >  > cleanup and exit. I have attached my small test program. It behaves
 > >  >  > somehow strange, at least to me:
 > >  >  > 
 > >  >  > - I see task period overruns when the low prio task is started. I
 > >  >  >   suspect some switch to secondary mode in init_task().
 > >  >  > 
 > >  >  > - The program/system hangs after the listed messages:
 > >  >  > 
 > >  >  >   # ./kill_pthread
 > >  >  >   Starting high_prio_task
 > >  >  >   Killed low_prio task: count=3813129, overruns=0
 > >  >  > 
 > >  >  > Any idea what I'm doing wrong?
 > >  >  > 
 > >  >  > This is with Linux 2.4.25 and Xenomai 2.3.x on a MPC5200 board.
 > >  > 
 > >  > Your test runs fine with Xenomai trunk (on ARM). I will now try with
 > >  > current state of the v2.3.x branch.
 > > 
 > > Works with v2.3.x too.
 > 
 > I re-activated my test PC running Linux 2.6.20.21. with Xenomai 2.3.x.
 > There the program runs fine _without_ your pthread_kill patch. For some
 > reason the low_prio_task() is running in secondary mode (do you know
 > why? Is there a function to check the mode?). I added
 > 
 >         struct sched_param  param = { .sched_priority = LOW_PRIO };
 >         pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);
 > 
 > to the head of that function and then I get:
 > 
 >   ./kill_pthread
 >   Starting high_prio_task
 >   BUG: NMI Watchdog detected LOCKUP
 >   Killed low_prio task: count=1588495996, overruns=0
 >   Exiting main
 > 
 > I have attached the corresponding oops in case it's of interest.
 > Unfortunately, with your patch and adding the function
 > __real_pthread_kill() to wrappers.c, the behavior is the same. I'm going
 > to repeat the tests with Xenomai trunk tomorrow.

The oops is due to the NMI watchdog calling some linux domain functions
over Xenomai domain. You should probably use Xenomai watchdog instead.

As for the reason why the watchdog triggers: are you sure you are
running the kernel recompiled after having applied the patch?

-- 


					    Gilles Chanteperdrix.


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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-09 22:52                     ` Gilles Chanteperdrix
@ 2007-12-10  7:27                       ` Wolfgang Grandegger
  2007-12-10 15:20                       ` Wolfgang Grandegger
  1 sibling, 0 replies; 33+ messages in thread
From: Wolfgang Grandegger @ 2007-12-10  7:27 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai-core

Gilles Chanteperdrix wrote:
> Wolfgang Grandegger wrote:
>  > Gilles Chanteperdrix wrote:
>  > > Gilles Chanteperdrix wrote:
>  > >  > Wolfgang Grandegger wrote:
>  > >  >  > Hi Gilles,
>  > >  >  > 
>  > >  >  > Gilles Chanteperdrix wrote:
>  > >  >  > > On Dec 6, 2007 3:05 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>  > >  >  > >> Gilles Chanteperdrix wrote:
>  > >  >  > >>> On Dec 6, 2007 2:28 PM, Gilles Chanteperdrix
>  > >  >  > >>> <gilles.chanteperdrix@xenomai.org> wrote:
>  > >  >  > >>>> On Dec 6, 2007 2:24 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>  > >  >  > >>>>> Gilles Chanteperdrix wrote:
>  > >  >  > >>>>>> On Dec 6, 2007 1:31 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>  > >  >  > >>>>>>> Hello,
>  > >  >  > >>>>>>>
>  > >  >  > >>>>>>> how do I cancel or delete a Xenomai POSIX thread running in primary
>  > >  >  > >>>>>>> context from a higher priority thread? IIUC, pthread_kill() can only be
>  > >  >  > >>>>>>> used in secondary context. I tried pthread_cancel(), but it only works
>  > >  >  > >>>>>>> when hitting a cancelation point, e.g. pthread_testcancel(). Setting
>  > >  >  > >>>>>>> pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS) did not help. Is
>  > >  >  > >>>>>>> there a code snippet or even an example program showing how to cancel a
>  > >  >  > >>>>>>> pthread in primary context?
>  > >  >  > >>>>>> pthread_kill or pthread_cancel should result in sending a signal to
>  > >  >  > >>>>>> the target thread, so should cause this thread to switch to secondary
>  > >  >  > >>>>>> mode to handle it. If you want to wait for the target thread to be
>  > >  >  > >>>>>> canceled, you should use pthread_cancel and pthread_join.
>  > >  >  > >>>>> There is no way to cancel a pthread in primary mode from another pthread?
>  > >  >  > >>>> No. You always need secondary mode to effectively delete a thread. The
>  > >  >  > >>>> same goes for the native skin.
>  > >  >  > >>> Ok. I understand what you mean. You want pthread_cancel not to leave
>  > >  >  > >>> primary mode. This can easily be done by causing pthread_cancel to use
>  > >  >  > >>> the kernel-space real-time pthread_cancel service. This should work
>  > >  >  > >>> with no further modification.
>  > >  >  > >> I want to cancel/delete a task running in primary mode, e.g.
>  > >  >  > >>
>  > >  >  > >>   void* work_task(void* dummy)
>  > >  >  > >>   {
>  > >  >  > >>         int count = 0;
>  > >  >  > >>         while (1)
>  > >  >  > >>                 count++;
>  > >  >  > >>   }
>  > >  >  > >>
>  > >  >  > >> from the outside (= another higher priority task). How can I use the
>  > >  >  > >> kernel-space real-time pthread_cancel service? My POSIX app is runs in
>  > >  >  > >> user-land.
>  > >  >  > > 
>  > >  >  > > I was thinking about adding a pthread_cancel syscall that would have
>  > >  >  > > triggered the kernel-space pthread_cancel. But this will not work:
>  > >  >  > > user-space cleanup handlers would no longer get executed. However,
>  > >  >  > > this can work for pthread_kill. Here is a patch which adds the
>  > >  >  > > pthread_kill syscall.
>  > >  >  > 
>  > >  >  > Great, thanks a lot. This seems to work but I'm now fiddling with proper
>  > >  >  > cleanup and exit. I have attached my small test program. It behaves
>  > >  >  > somehow strange, at least to me:
>  > >  >  > 
>  > >  >  > - I see task period overruns when the low prio task is started. I
>  > >  >  >   suspect some switch to secondary mode in init_task().
>  > >  >  > 
>  > >  >  > - The program/system hangs after the listed messages:
>  > >  >  > 
>  > >  >  >   # ./kill_pthread
>  > >  >  >   Starting high_prio_task
>  > >  >  >   Killed low_prio task: count=3813129, overruns=0
>  > >  >  > 
>  > >  >  > Any idea what I'm doing wrong?
>  > >  >  > 
>  > >  >  > This is with Linux 2.4.25 and Xenomai 2.3.x on a MPC5200 board.
>  > >  > 
>  > >  > Your test runs fine with Xenomai trunk (on ARM). I will now try with
>  > >  > current state of the v2.3.x branch.
>  > > 
>  > > Works with v2.3.x too.
>  > 
>  > I re-activated my test PC running Linux 2.6.20.21. with Xenomai 2.3.x.
>  > There the program runs fine _without_ your pthread_kill patch. For some
>  > reason the low_prio_task() is running in secondary mode (do you know
>  > why? Is there a function to check the mode?). I added
>  > 
>  >         struct sched_param  param = { .sched_priority = LOW_PRIO };
>  >         pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);
>  > 
>  > to the head of that function and then I get:
>  > 
>  >   ./kill_pthread
>  >   Starting high_prio_task
>  >   BUG: NMI Watchdog detected LOCKUP
>  >   Killed low_prio task: count=1588495996, overruns=0
>  >   Exiting main
>  > 
>  > I have attached the corresponding oops in case it's of interest.
>  > Unfortunately, with your patch and adding the function
>  > __real_pthread_kill() to wrappers.c, the behavior is the same. I'm going
>  > to repeat the tests with Xenomai trunk tomorrow.
> 
> The oops is due to the NMI watchdog calling some linux domain functions
> over Xenomai domain. You should probably use Xenomai watchdog instead.

OK, the Xenomai watchdog might be another possibility to kill a pthread
blocking the system.

> As for the reason why the watchdog triggers: are you sure you are
> running the kernel recompiled after having applied the patch?

Yes, because:

# grep pthread_kill System.map
c015af9e T pthread_kill
c015f4e6 t __pthread_kill
c0390650 r __ksymtab_pthread_kill
c03968b8 r __kcrctab_pthread_kill
c039ce83 r __kstrtab_pthread_kill

But I will double-check again.

Wolfgang.




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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-09 22:52                     ` Gilles Chanteperdrix
  2007-12-10  7:27                       ` Wolfgang Grandegger
@ 2007-12-10 15:20                       ` Wolfgang Grandegger
  2007-12-10 15:55                         ` Gilles Chanteperdrix
                                           ` (2 more replies)
  1 sibling, 3 replies; 33+ messages in thread
From: Wolfgang Grandegger @ 2007-12-10 15:20 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai-core

Gilles Chanteperdrix wrote:
> Wolfgang Grandegger wrote:
>  > Gilles Chanteperdrix wrote:
>  > > Gilles Chanteperdrix wrote:
>  > >  > Wolfgang Grandegger wrote:
>  > >  >  > Hi Gilles,
>  > >  >  > 
>  > >  >  > Gilles Chanteperdrix wrote:
>  > >  >  > > On Dec 6, 2007 3:05 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>  > >  >  > >> Gilles Chanteperdrix wrote:
>  > >  >  > >>> On Dec 6, 2007 2:28 PM, Gilles Chanteperdrix
>  > >  >  > >>> <gilles.chanteperdrix@xenomai.org> wrote:
>  > >  >  > >>>> On Dec 6, 2007 2:24 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>  > >  >  > >>>>> Gilles Chanteperdrix wrote:
>  > >  >  > >>>>>> On Dec 6, 2007 1:31 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>  > >  >  > >>>>>>> Hello,
>  > >  >  > >>>>>>>
>  > >  >  > >>>>>>> how do I cancel or delete a Xenomai POSIX thread running in primary
>  > >  >  > >>>>>>> context from a higher priority thread? IIUC, pthread_kill() can only be
>  > >  >  > >>>>>>> used in secondary context. I tried pthread_cancel(), but it only works
>  > >  >  > >>>>>>> when hitting a cancelation point, e.g. pthread_testcancel(). Setting
>  > >  >  > >>>>>>> pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS) did not help. Is
>  > >  >  > >>>>>>> there a code snippet or even an example program showing how to cancel a
>  > >  >  > >>>>>>> pthread in primary context?
>  > >  >  > >>>>>> pthread_kill or pthread_cancel should result in sending a signal to
>  > >  >  > >>>>>> the target thread, so should cause this thread to switch to secondary
>  > >  >  > >>>>>> mode to handle it. If you want to wait for the target thread to be
>  > >  >  > >>>>>> canceled, you should use pthread_cancel and pthread_join.
>  > >  >  > >>>>> There is no way to cancel a pthread in primary mode from another pthread?
>  > >  >  > >>>> No. You always need secondary mode to effectively delete a thread. The
>  > >  >  > >>>> same goes for the native skin.
>  > >  >  > >>> Ok. I understand what you mean. You want pthread_cancel not to leave
>  > >  >  > >>> primary mode. This can easily be done by causing pthread_cancel to use
>  > >  >  > >>> the kernel-space real-time pthread_cancel service. This should work
>  > >  >  > >>> with no further modification.
>  > >  >  > >> I want to cancel/delete a task running in primary mode, e.g.
>  > >  >  > >>
>  > >  >  > >>   void* work_task(void* dummy)
>  > >  >  > >>   {
>  > >  >  > >>         int count = 0;
>  > >  >  > >>         while (1)
>  > >  >  > >>                 count++;
>  > >  >  > >>   }
>  > >  >  > >>
>  > >  >  > >> from the outside (= another higher priority task). How can I use the
>  > >  >  > >> kernel-space real-time pthread_cancel service? My POSIX app is runs in
>  > >  >  > >> user-land.
>  > >  >  > > 
>  > >  >  > > I was thinking about adding a pthread_cancel syscall that would have
>  > >  >  > > triggered the kernel-space pthread_cancel. But this will not work:
>  > >  >  > > user-space cleanup handlers would no longer get executed. However,
>  > >  >  > > this can work for pthread_kill. Here is a patch which adds the
>  > >  >  > > pthread_kill syscall.
>  > >  >  > 
>  > >  >  > Great, thanks a lot. This seems to work but I'm now fiddling with proper
>  > >  >  > cleanup and exit. I have attached my small test program. It behaves
>  > >  >  > somehow strange, at least to me:
>  > >  >  > 
>  > >  >  > - I see task period overruns when the low prio task is started. I
>  > >  >  >   suspect some switch to secondary mode in init_task().
>  > >  >  > 
>  > >  >  > - The program/system hangs after the listed messages:
>  > >  >  > 
>  > >  >  >   # ./kill_pthread
>  > >  >  >   Starting high_prio_task
>  > >  >  >   Killed low_prio task: count=3813129, overruns=0
>  > >  >  > 
>  > >  >  > Any idea what I'm doing wrong?
>  > >  >  > 
>  > >  >  > This is with Linux 2.4.25 and Xenomai 2.3.x on a MPC5200 board.
>  > >  > 
>  > >  > Your test runs fine with Xenomai trunk (on ARM). I will now try with
>  > >  > current state of the v2.3.x branch.
>  > > 
>  > > Works with v2.3.x too.
>  > 
>  > I re-activated my test PC running Linux 2.6.20.21. with Xenomai 2.3.x.
>  > There the program runs fine _without_ your pthread_kill patch. For some
>  > reason the low_prio_task() is running in secondary mode (do you know
>  > why? Is there a function to check the mode?). I added
>  > 
>  >         struct sched_param  param = { .sched_priority = LOW_PRIO };
>  >         pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);

After adding pthread_getschedparam() I realized, that policy was 1 and
prio 10 and not as expected 5. The corresponding attribute settings
before calling pthread_create have been ignored somehow. Am I doing
something wrong in task_init()?

>  > to the head of that function and then I get:
>  > 
>  >   ./kill_pthread
>  >   Starting high_prio_task
>  >   BUG: NMI Watchdog detected LOCKUP
>  >   Killed low_prio task: count=1588495996, overruns=0
>  >   Exiting main
>  > 
>  > I have attached the corresponding oops in case it's of interest.
>  > Unfortunately, with your patch and adding the function
>  > __real_pthread_kill() to wrappers.c, the behavior is the same. I'm going
>  > to repeat the tests with Xenomai trunk tomorrow.
> 
> The oops is due to the NMI watchdog calling some linux domain functions
> over Xenomai domain. You should probably use Xenomai watchdog instead.
> 
> As for the reason why the watchdog triggers: are you sure you are
> running the kernel recompiled after having applied the patch?

Indeed, after a "make clean; make bzImage" of the kernel it behaves
differently. Wired, may be some dependency issue.

  # ./kill_pthread
  Starting high_prio_task
  low_prio_task: policy=1 prio=10
  Killed low_prio task: count=172709970, overruns=0

  [1]+  Stopped                 ./kill_pthread

The low_prio_task() seems to be aborted and the process is stopped. If I
do a "kill %1" though, the system hangs. I'm now trying Xenomai trunk
with Linux 2.6.23.

Wolfgang.



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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-10 15:20                       ` Wolfgang Grandegger
@ 2007-12-10 15:55                         ` Gilles Chanteperdrix
  2007-12-10 21:39                           ` Wolfgang Grandegger
  2007-12-10 21:21                         ` Gilles Chanteperdrix
  2007-12-10 22:11                         ` Gilles Chanteperdrix
  2 siblings, 1 reply; 33+ messages in thread
From: Gilles Chanteperdrix @ 2007-12-10 15:55 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: xenomai-core

On Dec 10, 2007 4:20 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>
> Gilles Chanteperdrix wrote:
> > Wolfgang Grandegger wrote:
> >  > Gilles Chanteperdrix wrote:
> >  > > Gilles Chanteperdrix wrote:
> >  > >  > Wolfgang Grandegger wrote:
> >  > >  >  > Hi Gilles,
> >  > >  >  >
> >  > >  >  > Gilles Chanteperdrix wrote:
> >  > >  >  > > On Dec 6, 2007 3:05 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
> >  > >  >  > >> Gilles Chanteperdrix wrote:
> >  > >  >  > >>> On Dec 6, 2007 2:28 PM, Gilles Chanteperdrix
> >  > >  >  > >>> <gilles.chanteperdrix@xenomai.org> wrote:
> >  > >  >  > >>>> On Dec 6, 2007 2:24 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
> >  > >  >  > >>>>> Gilles Chanteperdrix wrote:
> >  > >  >  > >>>>>> On Dec 6, 2007 1:31 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
> >  > >  >  > >>>>>>> Hello,
> >  > >  >  > >>>>>>>
> >  > >  >  > >>>>>>> how do I cancel or delete a Xenomai POSIX thread running in primary
> >  > >  >  > >>>>>>> context from a higher priority thread? IIUC, pthread_kill() can only be
> >  > >  >  > >>>>>>> used in secondary context. I tried pthread_cancel(), but it only works
> >  > >  >  > >>>>>>> when hitting a cancelation point, e.g. pthread_testcancel(). Setting
> >  > >  >  > >>>>>>> pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS) did not help. Is
> >  > >  >  > >>>>>>> there a code snippet or even an example program showing how to cancel a
> >  > >  >  > >>>>>>> pthread in primary context?
> >  > >  >  > >>>>>> pthread_kill or pthread_cancel should result in sending a signal to
> >  > >  >  > >>>>>> the target thread, so should cause this thread to switch to secondary
> >  > >  >  > >>>>>> mode to handle it. If you want to wait for the target thread to be
> >  > >  >  > >>>>>> canceled, you should use pthread_cancel and pthread_join.
> >  > >  >  > >>>>> There is no way to cancel a pthread in primary mode from another pthread?
> >  > >  >  > >>>> No. You always need secondary mode to effectively delete a thread. The
> >  > >  >  > >>>> same goes for the native skin.
> >  > >  >  > >>> Ok. I understand what you mean. You want pthread_cancel not to leave
> >  > >  >  > >>> primary mode. This can easily be done by causing pthread_cancel to use
> >  > >  >  > >>> the kernel-space real-time pthread_cancel service. This should work
> >  > >  >  > >>> with no further modification.
> >  > >  >  > >> I want to cancel/delete a task running in primary mode, e.g.
> >  > >  >  > >>
> >  > >  >  > >>   void* work_task(void* dummy)
> >  > >  >  > >>   {
> >  > >  >  > >>         int count = 0;
> >  > >  >  > >>         while (1)
> >  > >  >  > >>                 count++;
> >  > >  >  > >>   }
> >  > >  >  > >>
> >  > >  >  > >> from the outside (= another higher priority task). How can I use the
> >  > >  >  > >> kernel-space real-time pthread_cancel service? My POSIX app is runs in
> >  > >  >  > >> user-land.
> >  > >  >  > >
> >  > >  >  > > I was thinking about adding a pthread_cancel syscall that would have
> >  > >  >  > > triggered the kernel-space pthread_cancel. But this will not work:
> >  > >  >  > > user-space cleanup handlers would no longer get executed. However,
> >  > >  >  > > this can work for pthread_kill. Here is a patch which adds the
> >  > >  >  > > pthread_kill syscall.
> >  > >  >  >
> >  > >  >  > Great, thanks a lot. This seems to work but I'm now fiddling with proper
> >  > >  >  > cleanup and exit. I have attached my small test program. It behaves
> >  > >  >  > somehow strange, at least to me:
> >  > >  >  >
> >  > >  >  > - I see task period overruns when the low prio task is started. I
> >  > >  >  >   suspect some switch to secondary mode in init_task().
> >  > >  >  >
> >  > >  >  > - The program/system hangs after the listed messages:
> >  > >  >  >
> >  > >  >  >   # ./kill_pthread
> >  > >  >  >   Starting high_prio_task
> >  > >  >  >   Killed low_prio task: count=3813129, overruns=0
> >  > >  >  >
> >  > >  >  > Any idea what I'm doing wrong?
> >  > >  >  >
> >  > >  >  > This is with Linux 2.4.25 and Xenomai 2.3.x on a MPC5200 board.
> >  > >  >
> >  > >  > Your test runs fine with Xenomai trunk (on ARM). I will now try with
> >  > >  > current state of the v2.3.x branch.
> >  > >
> >  > > Works with v2.3.x too.
> >  >
> >  > I re-activated my test PC running Linux 2.6.20.21. with Xenomai 2.3.x.
> >  > There the program runs fine _without_ your pthread_kill patch. For some
> >  > reason the low_prio_task() is running in secondary mode (do you know
> >  > why? Is there a function to check the mode?). I added
> >  >
> >  >         struct sched_param  param = { .sched_priority = LOW_PRIO };
> >  >         pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);
>
> After adding pthread_getschedparam() I realized, that policy was 1 and
> prio 10 and not as expected 5. The corresponding attribute settings
> before calling pthread_create have been ignored somehow. Am I doing
> something wrong in task_init()?
>
> >  > to the head of that function and then I get:
> >  >
> >  >   ./kill_pthread
> >  >   Starting high_prio_task
> >  >   BUG: NMI Watchdog detected LOCKUP
> >  >   Killed low_prio task: count=1588495996, overruns=0
> >  >   Exiting main
> >  >
> >  > I have attached the corresponding oops in case it's of interest.
> >  > Unfortunately, with your patch and adding the function
> >  > __real_pthread_kill() to wrappers.c, the behavior is the same. I'm going
> >  > to repeat the tests with Xenomai trunk tomorrow.
> >
> > The oops is due to the NMI watchdog calling some linux domain functions
> > over Xenomai domain. You should probably use Xenomai watchdog instead.
> >
> > As for the reason why the watchdog triggers: are you sure you are
> > running the kernel recompiled after having applied the patch?
>
> Indeed, after a "make clean; make bzImage" of the kernel it behaves
> differently. Wired, may be some dependency issue.
>
>   # ./kill_pthread
>   Starting high_prio_task
>   low_prio_task: policy=1 prio=10
>   Killed low_prio task: count=172709970, overruns=0
>
>   [1]+  Stopped                 ./kill_pthread

What you are observing is probably a difference between linuxthreads
and NPTL: with linuxthreads, SIGSTOP can be sent to a particular
thread and will cause this thread only to stop. With NPTL, it seems
that the effect of SIGSTOP is global, it affects the entire process. I
will test tonight on my x86 box to see if I observe the same effect.

>
> The low_prio_task() seems to be aborted and the process is stopped. If I
> do a "kill %1" though, the system hangs. I'm now trying Xenomai trunk
> with Linux 2.6.23.

That is expected: you installed a handler for SIGTERM which does not
call exit or do not call anything which will end the application. So,
sending SIGTERM simply unblocks all thread, and the low priority
thread, now running in secondary mode, blocks the CPU. If you enable
Linux soft lockup detector, you will see a warning on the console.

IMHO, a handler for SIGTERM should reinstall the default signal
handler, and raise the SIGTERM signal anew. In other words, you should
add at the end of the sighand function:
signal(sig, SIG_DFL);
raise(sig);

>
> Wolfgang.
>
>



-- 
                                               Gilles Chanteperdrix


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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-10 15:20                       ` Wolfgang Grandegger
  2007-12-10 15:55                         ` Gilles Chanteperdrix
@ 2007-12-10 21:21                         ` Gilles Chanteperdrix
  2007-12-10 21:37                           ` Wolfgang Grandegger
  2007-12-10 22:11                         ` Gilles Chanteperdrix
  2 siblings, 1 reply; 33+ messages in thread
From: Gilles Chanteperdrix @ 2007-12-10 21:21 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: xenomai-core

Wolfgang Grandegger wrote:
 > Gilles Chanteperdrix wrote:
 > > Wolfgang Grandegger wrote:
 > >  > Gilles Chanteperdrix wrote:
 > >  > > Gilles Chanteperdrix wrote:
 > >  > >  > Wolfgang Grandegger wrote:
 > >  > >  >  > Hi Gilles,
 > >  > >  >  > 
 > >  > >  >  > Gilles Chanteperdrix wrote:
 > >  > >  >  > > On Dec 6, 2007 3:05 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
 > >  > >  >  > >> Gilles Chanteperdrix wrote:
 > >  > >  >  > >>> On Dec 6, 2007 2:28 PM, Gilles Chanteperdrix
 > >  > >  >  > >>> <gilles.chanteperdrix@xenomai.org> wrote:
 > >  > >  >  > >>>> On Dec 6, 2007 2:24 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
 > >  > >  >  > >>>>> Gilles Chanteperdrix wrote:
 > >  > >  >  > >>>>>> On Dec 6, 2007 1:31 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
 > >  > >  >  > >>>>>>> Hello,
 > >  > >  >  > >>>>>>>
 > >  > >  >  > >>>>>>> how do I cancel or delete a Xenomai POSIX thread running in primary
 > >  > >  >  > >>>>>>> context from a higher priority thread? IIUC, pthread_kill() can only be
 > >  > >  >  > >>>>>>> used in secondary context. I tried pthread_cancel(), but it only works
 > >  > >  >  > >>>>>>> when hitting a cancelation point, e.g. pthread_testcancel(). Setting
 > >  > >  >  > >>>>>>> pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS) did not help. Is
 > >  > >  >  > >>>>>>> there a code snippet or even an example program showing how to cancel a
 > >  > >  >  > >>>>>>> pthread in primary context?
 > >  > >  >  > >>>>>> pthread_kill or pthread_cancel should result in sending a signal to
 > >  > >  >  > >>>>>> the target thread, so should cause this thread to switch to secondary
 > >  > >  >  > >>>>>> mode to handle it. If you want to wait for the target thread to be
 > >  > >  >  > >>>>>> canceled, you should use pthread_cancel and pthread_join.
 > >  > >  >  > >>>>> There is no way to cancel a pthread in primary mode from another pthread?
 > >  > >  >  > >>>> No. You always need secondary mode to effectively delete a thread. The
 > >  > >  >  > >>>> same goes for the native skin.
 > >  > >  >  > >>> Ok. I understand what you mean. You want pthread_cancel not to leave
 > >  > >  >  > >>> primary mode. This can easily be done by causing pthread_cancel to use
 > >  > >  >  > >>> the kernel-space real-time pthread_cancel service. This should work
 > >  > >  >  > >>> with no further modification.
 > >  > >  >  > >> I want to cancel/delete a task running in primary mode, e.g.
 > >  > >  >  > >>
 > >  > >  >  > >>   void* work_task(void* dummy)
 > >  > >  >  > >>   {
 > >  > >  >  > >>         int count = 0;
 > >  > >  >  > >>         while (1)
 > >  > >  >  > >>                 count++;
 > >  > >  >  > >>   }
 > >  > >  >  > >>
 > >  > >  >  > >> from the outside (= another higher priority task). How can I use the
 > >  > >  >  > >> kernel-space real-time pthread_cancel service? My POSIX app is runs in
 > >  > >  >  > >> user-land.
 > >  > >  >  > > 
 > >  > >  >  > > I was thinking about adding a pthread_cancel syscall that would have
 > >  > >  >  > > triggered the kernel-space pthread_cancel. But this will not work:
 > >  > >  >  > > user-space cleanup handlers would no longer get executed. However,
 > >  > >  >  > > this can work for pthread_kill. Here is a patch which adds the
 > >  > >  >  > > pthread_kill syscall.
 > >  > >  >  > 
 > >  > >  >  > Great, thanks a lot. This seems to work but I'm now fiddling with proper
 > >  > >  >  > cleanup and exit. I have attached my small test program. It behaves
 > >  > >  >  > somehow strange, at least to me:
 > >  > >  >  > 
 > >  > >  >  > - I see task period overruns when the low prio task is started. I
 > >  > >  >  >   suspect some switch to secondary mode in init_task().
 > >  > >  >  > 
 > >  > >  >  > - The program/system hangs after the listed messages:
 > >  > >  >  > 
 > >  > >  >  >   # ./kill_pthread
 > >  > >  >  >   Starting high_prio_task
 > >  > >  >  >   Killed low_prio task: count=3813129, overruns=0
 > >  > >  >  > 
 > >  > >  >  > Any idea what I'm doing wrong?
 > >  > >  >  > 
 > >  > >  >  > This is with Linux 2.4.25 and Xenomai 2.3.x on a MPC5200 board.
 > >  > >  > 
 > >  > >  > Your test runs fine with Xenomai trunk (on ARM). I will now try with
 > >  > >  > current state of the v2.3.x branch.
 > >  > > 
 > >  > > Works with v2.3.x too.
 > >  > 
 > >  > I re-activated my test PC running Linux 2.6.20.21. with Xenomai 2.3.x.
 > >  > There the program runs fine _without_ your pthread_kill patch. For some
 > >  > reason the low_prio_task() is running in secondary mode (do you know
 > >  > why? Is there a function to check the mode?). I added
 > >  > 
 > >  >         struct sched_param  param = { .sched_priority = LOW_PRIO };
 > >  >         pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);
 > 
 > After adding pthread_getschedparam() I realized, that policy was 1 and
 > prio 10 and not as expected 5. The corresponding attribute settings
 > before calling pthread_create have been ignored somehow. Am I doing
 > something wrong in task_init()?

No, I think there is rather something wrong in Xenomai user-space
library. __pthread_trampoline should call __wrap_pthread_setschedparam
instead of __real_pthread_setschedparam.

-- 


					    Gilles Chanteperdrix.


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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-10 21:21                         ` Gilles Chanteperdrix
@ 2007-12-10 21:37                           ` Wolfgang Grandegger
  0 siblings, 0 replies; 33+ messages in thread
From: Wolfgang Grandegger @ 2007-12-10 21:37 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai-core

Gilles Chanteperdrix wrote:
> Wolfgang Grandegger wrote:
>  > Gilles Chanteperdrix wrote:
>  > > Wolfgang Grandegger wrote:
>  > >  > Gilles Chanteperdrix wrote:
>  > >  > > Gilles Chanteperdrix wrote:
>  > >  > >  > Wolfgang Grandegger wrote:
>  > >  > >  >  > Hi Gilles,
>  > >  > >  >  > 
>  > >  > >  >  > Gilles Chanteperdrix wrote:
>  > >  > >  >  > > On Dec 6, 2007 3:05 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>  > >  > >  >  > >> Gilles Chanteperdrix wrote:
>  > >  > >  >  > >>> On Dec 6, 2007 2:28 PM, Gilles Chanteperdrix
>  > >  > >  >  > >>> <gilles.chanteperdrix@xenomai.org> wrote:
>  > >  > >  >  > >>>> On Dec 6, 2007 2:24 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>  > >  > >  >  > >>>>> Gilles Chanteperdrix wrote:
>  > >  > >  >  > >>>>>> On Dec 6, 2007 1:31 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>  > >  > >  >  > >>>>>>> Hello,
>  > >  > >  >  > >>>>>>>
>  > >  > >  >  > >>>>>>> how do I cancel or delete a Xenomai POSIX thread running in primary
>  > >  > >  >  > >>>>>>> context from a higher priority thread? IIUC, pthread_kill() can only be
>  > >  > >  >  > >>>>>>> used in secondary context. I tried pthread_cancel(), but it only works
>  > >  > >  >  > >>>>>>> when hitting a cancelation point, e.g. pthread_testcancel(). Setting
>  > >  > >  >  > >>>>>>> pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS) did not help. Is
>  > >  > >  >  > >>>>>>> there a code snippet or even an example program showing how to cancel a
>  > >  > >  >  > >>>>>>> pthread in primary context?
>  > >  > >  >  > >>>>>> pthread_kill or pthread_cancel should result in sending a signal to
>  > >  > >  >  > >>>>>> the target thread, so should cause this thread to switch to secondary
>  > >  > >  >  > >>>>>> mode to handle it. If you want to wait for the target thread to be
>  > >  > >  >  > >>>>>> canceled, you should use pthread_cancel and pthread_join.
>  > >  > >  >  > >>>>> There is no way to cancel a pthread in primary mode from another pthread?
>  > >  > >  >  > >>>> No. You always need secondary mode to effectively delete a thread. The
>  > >  > >  >  > >>>> same goes for the native skin.
>  > >  > >  >  > >>> Ok. I understand what you mean. You want pthread_cancel not to leave
>  > >  > >  >  > >>> primary mode. This can easily be done by causing pthread_cancel to use
>  > >  > >  >  > >>> the kernel-space real-time pthread_cancel service. This should work
>  > >  > >  >  > >>> with no further modification.
>  > >  > >  >  > >> I want to cancel/delete a task running in primary mode, e.g.
>  > >  > >  >  > >>
>  > >  > >  >  > >>   void* work_task(void* dummy)
>  > >  > >  >  > >>   {
>  > >  > >  >  > >>         int count = 0;
>  > >  > >  >  > >>         while (1)
>  > >  > >  >  > >>                 count++;
>  > >  > >  >  > >>   }
>  > >  > >  >  > >>
>  > >  > >  >  > >> from the outside (= another higher priority task). How can I use the
>  > >  > >  >  > >> kernel-space real-time pthread_cancel service? My POSIX app is runs in
>  > >  > >  >  > >> user-land.
>  > >  > >  >  > > 
>  > >  > >  >  > > I was thinking about adding a pthread_cancel syscall that would have
>  > >  > >  >  > > triggered the kernel-space pthread_cancel. But this will not work:
>  > >  > >  >  > > user-space cleanup handlers would no longer get executed. However,
>  > >  > >  >  > > this can work for pthread_kill. Here is a patch which adds the
>  > >  > >  >  > > pthread_kill syscall.
>  > >  > >  >  > 
>  > >  > >  >  > Great, thanks a lot. This seems to work but I'm now fiddling with proper
>  > >  > >  >  > cleanup and exit. I have attached my small test program. It behaves
>  > >  > >  >  > somehow strange, at least to me:
>  > >  > >  >  > 
>  > >  > >  >  > - I see task period overruns when the low prio task is started. I
>  > >  > >  >  >   suspect some switch to secondary mode in init_task().
>  > >  > >  >  > 
>  > >  > >  >  > - The program/system hangs after the listed messages:
>  > >  > >  >  > 
>  > >  > >  >  >   # ./kill_pthread
>  > >  > >  >  >   Starting high_prio_task
>  > >  > >  >  >   Killed low_prio task: count=3813129, overruns=0
>  > >  > >  >  > 
>  > >  > >  >  > Any idea what I'm doing wrong?
>  > >  > >  >  > 
>  > >  > >  >  > This is with Linux 2.4.25 and Xenomai 2.3.x on a MPC5200 board.
>  > >  > >  > 
>  > >  > >  > Your test runs fine with Xenomai trunk (on ARM). I will now try with
>  > >  > >  > current state of the v2.3.x branch.
>  > >  > > 
>  > >  > > Works with v2.3.x too.
>  > >  > 
>  > >  > I re-activated my test PC running Linux 2.6.20.21. with Xenomai 2.3.x.
>  > >  > There the program runs fine _without_ your pthread_kill patch. For some
>  > >  > reason the low_prio_task() is running in secondary mode (do you know
>  > >  > why? Is there a function to check the mode?). I added
>  > >  > 
>  > >  >         struct sched_param  param = { .sched_priority = LOW_PRIO };
>  > >  >         pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);
>  > 
>  > After adding pthread_getschedparam() I realized, that policy was 1 and
>  > prio 10 and not as expected 5. The corresponding attribute settings
>  > before calling pthread_create have been ignored somehow. Am I doing
>  > something wrong in task_init()?
> 
> No, I think there is rather something wrong in Xenomai user-space
> library. __pthread_trampoline should call __wrap_pthread_setschedparam
> instead of __real_pthread_setschedparam.

OK, I have realized that it's correct with Linux 2.4 but wrong with 2.6.

Wolfgang.


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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-10 15:55                         ` Gilles Chanteperdrix
@ 2007-12-10 21:39                           ` Wolfgang Grandegger
  2007-12-10 21:46                             ` Wolfgang Grandegger
  2007-12-10 21:56                             ` Gilles Chanteperdrix
  0 siblings, 2 replies; 33+ messages in thread
From: Wolfgang Grandegger @ 2007-12-10 21:39 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai-core

Gilles Chanteperdrix wrote:
> On Dec 10, 2007 4:20 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>> Gilles Chanteperdrix wrote:
>>> Wolfgang Grandegger wrote:
>>>  > Gilles Chanteperdrix wrote:
>>>  > > Gilles Chanteperdrix wrote:
>>>  > >  > Wolfgang Grandegger wrote:
>>>  > >  >  > Hi Gilles,
>>>  > >  >  >
>>>  > >  >  > Gilles Chanteperdrix wrote:
>>>  > >  >  > > On Dec 6, 2007 3:05 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>>>  > >  >  > >> Gilles Chanteperdrix wrote:
>>>  > >  >  > >>> On Dec 6, 2007 2:28 PM, Gilles Chanteperdrix
>>>  > >  >  > >>> <gilles.chanteperdrix@xenomai.org> wrote:
>>>  > >  >  > >>>> On Dec 6, 2007 2:24 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>>>  > >  >  > >>>>> Gilles Chanteperdrix wrote:
>>>  > >  >  > >>>>>> On Dec 6, 2007 1:31 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>>>  > >  >  > >>>>>>> Hello,
>>>  > >  >  > >>>>>>>
>>>  > >  >  > >>>>>>> how do I cancel or delete a Xenomai POSIX thread running in primary
>>>  > >  >  > >>>>>>> context from a higher priority thread? IIUC, pthread_kill() can only be
>>>  > >  >  > >>>>>>> used in secondary context. I tried pthread_cancel(), but it only works
>>>  > >  >  > >>>>>>> when hitting a cancelation point, e.g. pthread_testcancel(). Setting
>>>  > >  >  > >>>>>>> pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS) did not help. Is
>>>  > >  >  > >>>>>>> there a code snippet or even an example program showing how to cancel a
>>>  > >  >  > >>>>>>> pthread in primary context?
>>>  > >  >  > >>>>>> pthread_kill or pthread_cancel should result in sending a signal to
>>>  > >  >  > >>>>>> the target thread, so should cause this thread to switch to secondary
>>>  > >  >  > >>>>>> mode to handle it. If you want to wait for the target thread to be
>>>  > >  >  > >>>>>> canceled, you should use pthread_cancel and pthread_join.
>>>  > >  >  > >>>>> There is no way to cancel a pthread in primary mode from another pthread?
>>>  > >  >  > >>>> No. You always need secondary mode to effectively delete a thread. The
>>>  > >  >  > >>>> same goes for the native skin.
>>>  > >  >  > >>> Ok. I understand what you mean. You want pthread_cancel not to leave
>>>  > >  >  > >>> primary mode. This can easily be done by causing pthread_cancel to use
>>>  > >  >  > >>> the kernel-space real-time pthread_cancel service. This should work
>>>  > >  >  > >>> with no further modification.
>>>  > >  >  > >> I want to cancel/delete a task running in primary mode, e.g.
>>>  > >  >  > >>
>>>  > >  >  > >>   void* work_task(void* dummy)
>>>  > >  >  > >>   {
>>>  > >  >  > >>         int count = 0;
>>>  > >  >  > >>         while (1)
>>>  > >  >  > >>                 count++;
>>>  > >  >  > >>   }
>>>  > >  >  > >>
>>>  > >  >  > >> from the outside (= another higher priority task). How can I use the
>>>  > >  >  > >> kernel-space real-time pthread_cancel service? My POSIX app is runs in
>>>  > >  >  > >> user-land.
>>>  > >  >  > >
>>>  > >  >  > > I was thinking about adding a pthread_cancel syscall that would have
>>>  > >  >  > > triggered the kernel-space pthread_cancel. But this will not work:
>>>  > >  >  > > user-space cleanup handlers would no longer get executed. However,
>>>  > >  >  > > this can work for pthread_kill. Here is a patch which adds the
>>>  > >  >  > > pthread_kill syscall.
>>>  > >  >  >
>>>  > >  >  > Great, thanks a lot. This seems to work but I'm now fiddling with proper
>>>  > >  >  > cleanup and exit. I have attached my small test program. It behaves
>>>  > >  >  > somehow strange, at least to me:
>>>  > >  >  >
>>>  > >  >  > - I see task period overruns when the low prio task is started. I
>>>  > >  >  >   suspect some switch to secondary mode in init_task().
>>>  > >  >  >
>>>  > >  >  > - The program/system hangs after the listed messages:
>>>  > >  >  >
>>>  > >  >  >   # ./kill_pthread
>>>  > >  >  >   Starting high_prio_task
>>>  > >  >  >   Killed low_prio task: count=3813129, overruns=0
>>>  > >  >  >
>>>  > >  >  > Any idea what I'm doing wrong?
>>>  > >  >  >
>>>  > >  >  > This is with Linux 2.4.25 and Xenomai 2.3.x on a MPC5200 board.
>>>  > >  >
>>>  > >  > Your test runs fine with Xenomai trunk (on ARM). I will now try with
>>>  > >  > current state of the v2.3.x branch.
>>>  > >
>>>  > > Works with v2.3.x too.
>>>  >
>>>  > I re-activated my test PC running Linux 2.6.20.21. with Xenomai 2.3.x.
>>>  > There the program runs fine _without_ your pthread_kill patch. For some
>>>  > reason the low_prio_task() is running in secondary mode (do you know
>>>  > why? Is there a function to check the mode?). I added
>>>  >
>>>  >         struct sched_param  param = { .sched_priority = LOW_PRIO };
>>>  >         pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);
>> After adding pthread_getschedparam() I realized, that policy was 1 and
>> prio 10 and not as expected 5. The corresponding attribute settings
>> before calling pthread_create have been ignored somehow. Am I doing
>> something wrong in task_init()?
>>
>>>  > to the head of that function and then I get:
>>>  >
>>>  >   ./kill_pthread
>>>  >   Starting high_prio_task
>>>  >   BUG: NMI Watchdog detected LOCKUP
>>>  >   Killed low_prio task: count=1588495996, overruns=0
>>>  >   Exiting main
>>>  >
>>>  > I have attached the corresponding oops in case it's of interest.
>>>  > Unfortunately, with your patch and adding the function
>>>  > __real_pthread_kill() to wrappers.c, the behavior is the same. I'm going
>>>  > to repeat the tests with Xenomai trunk tomorrow.
>>>
>>> The oops is due to the NMI watchdog calling some linux domain functions
>>> over Xenomai domain. You should probably use Xenomai watchdog instead.
>>>
>>> As for the reason why the watchdog triggers: are you sure you are
>>> running the kernel recompiled after having applied the patch?
>> Indeed, after a "make clean; make bzImage" of the kernel it behaves
>> differently. Wired, may be some dependency issue.
>>
>>   # ./kill_pthread
>>   Starting high_prio_task
>>   low_prio_task: policy=1 prio=10
>>   Killed low_prio task: count=172709970, overruns=0
>>
>>   [1]+  Stopped                 ./kill_pthread
> 
> What you are observing is probably a difference between linuxthreads
> and NPTL: with linuxthreads, SIGSTOP can be sent to a particular
> thread and will cause this thread only to stop. With NPTL, it seems
> that the effect of SIGSTOP is global, it affects the entire process. I
> will test tonight on my x86 box to see if I observe the same effect.

Ah, the man page says:

 Note  that  pthread_kill()  only causes the signal to be handled in the
 context of the given thread; the signal action  (termination  or  stop-
 ping) affects the process as a whole.

Wolfgang.



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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-10 21:39                           ` Wolfgang Grandegger
@ 2007-12-10 21:46                             ` Wolfgang Grandegger
  2007-12-11 13:20                               ` Wolfgang Grandegger
  2007-12-10 21:56                             ` Gilles Chanteperdrix
  1 sibling, 1 reply; 33+ messages in thread
From: Wolfgang Grandegger @ 2007-12-10 21:46 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: xenomai-core

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

Wolfgang Grandegger wrote:
> Gilles Chanteperdrix wrote:
>> On Dec 10, 2007 4:20 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>>> Gilles Chanteperdrix wrote:
>>>> Wolfgang Grandegger wrote:
>>>>  > Gilles Chanteperdrix wrote:
>>>>  > > Gilles Chanteperdrix wrote:
>>>>  > >  > Wolfgang Grandegger wrote:
>>>>  > >  >  > Hi Gilles,
>>>>  > >  >  >
>>>>  > >  >  > Gilles Chanteperdrix wrote:
>>>>  > >  >  > > On Dec 6, 2007 3:05 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>>>>  > >  >  > >> Gilles Chanteperdrix wrote:
>>>>  > >  >  > >>> On Dec 6, 2007 2:28 PM, Gilles Chanteperdrix
>>>>  > >  >  > >>> <gilles.chanteperdrix@xenomai.org> wrote:
>>>>  > >  >  > >>>> On Dec 6, 2007 2:24 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>>>>  > >  >  > >>>>> Gilles Chanteperdrix wrote:
>>>>  > >  >  > >>>>>> On Dec 6, 2007 1:31 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>>>>  > >  >  > >>>>>>> Hello,
>>>>  > >  >  > >>>>>>>
>>>>  > >  >  > >>>>>>> how do I cancel or delete a Xenomai POSIX thread running in primary
>>>>  > >  >  > >>>>>>> context from a higher priority thread? IIUC, pthread_kill() can only be
>>>>  > >  >  > >>>>>>> used in secondary context. I tried pthread_cancel(), but it only works
>>>>  > >  >  > >>>>>>> when hitting a cancelation point, e.g. pthread_testcancel(). Setting
>>>>  > >  >  > >>>>>>> pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS) did not help. Is
>>>>  > >  >  > >>>>>>> there a code snippet or even an example program showing how to cancel a
>>>>  > >  >  > >>>>>>> pthread in primary context?
>>>>  > >  >  > >>>>>> pthread_kill or pthread_cancel should result in sending a signal to
>>>>  > >  >  > >>>>>> the target thread, so should cause this thread to switch to secondary
>>>>  > >  >  > >>>>>> mode to handle it. If you want to wait for the target thread to be
>>>>  > >  >  > >>>>>> canceled, you should use pthread_cancel and pthread_join.
>>>>  > >  >  > >>>>> There is no way to cancel a pthread in primary mode from another pthread?
>>>>  > >  >  > >>>> No. You always need secondary mode to effectively delete a thread. The
>>>>  > >  >  > >>>> same goes for the native skin.
>>>>  > >  >  > >>> Ok. I understand what you mean. You want pthread_cancel not to leave
>>>>  > >  >  > >>> primary mode. This can easily be done by causing pthread_cancel to use
>>>>  > >  >  > >>> the kernel-space real-time pthread_cancel service. This should work
>>>>  > >  >  > >>> with no further modification.
>>>>  > >  >  > >> I want to cancel/delete a task running in primary mode, e.g.
>>>>  > >  >  > >>
>>>>  > >  >  > >>   void* work_task(void* dummy)
>>>>  > >  >  > >>   {
>>>>  > >  >  > >>         int count = 0;
>>>>  > >  >  > >>         while (1)
>>>>  > >  >  > >>                 count++;
>>>>  > >  >  > >>   }
>>>>  > >  >  > >>
>>>>  > >  >  > >> from the outside (= another higher priority task). How can I use the
>>>>  > >  >  > >> kernel-space real-time pthread_cancel service? My POSIX app is runs in
>>>>  > >  >  > >> user-land.
>>>>  > >  >  > >
>>>>  > >  >  > > I was thinking about adding a pthread_cancel syscall that would have
>>>>  > >  >  > > triggered the kernel-space pthread_cancel. But this will not work:
>>>>  > >  >  > > user-space cleanup handlers would no longer get executed. However,
>>>>  > >  >  > > this can work for pthread_kill. Here is a patch which adds the
>>>>  > >  >  > > pthread_kill syscall.
>>>>  > >  >  >
>>>>  > >  >  > Great, thanks a lot. This seems to work but I'm now fiddling with proper
>>>>  > >  >  > cleanup and exit. I have attached my small test program. It behaves
>>>>  > >  >  > somehow strange, at least to me:
>>>>  > >  >  >
>>>>  > >  >  > - I see task period overruns when the low prio task is started. I
>>>>  > >  >  >   suspect some switch to secondary mode in init_task().
>>>>  > >  >  >
>>>>  > >  >  > - The program/system hangs after the listed messages:
>>>>  > >  >  >
>>>>  > >  >  >   # ./kill_pthread
>>>>  > >  >  >   Starting high_prio_task
>>>>  > >  >  >   Killed low_prio task: count=3813129, overruns=0
>>>>  > >  >  >
>>>>  > >  >  > Any idea what I'm doing wrong?
>>>>  > >  >  >
>>>>  > >  >  > This is with Linux 2.4.25 and Xenomai 2.3.x on a MPC5200 board.
>>>>  > >  >
>>>>  > >  > Your test runs fine with Xenomai trunk (on ARM). I will now try with
>>>>  > >  > current state of the v2.3.x branch.
>>>>  > >
>>>>  > > Works with v2.3.x too.
>>>>  >
>>>>  > I re-activated my test PC running Linux 2.6.20.21. with Xenomai 2.3.x.
>>>>  > There the program runs fine _without_ your pthread_kill patch. For some
>>>>  > reason the low_prio_task() is running in secondary mode (do you know
>>>>  > why? Is there a function to check the mode?). I added
>>>>  >
>>>>  >         struct sched_param  param = { .sched_priority = LOW_PRIO };
>>>>  >         pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);
>>> After adding pthread_getschedparam() I realized, that policy was 1 and
>>> prio 10 and not as expected 5. The corresponding attribute settings
>>> before calling pthread_create have been ignored somehow. Am I doing
>>> something wrong in task_init()?
>>>
>>>>  > to the head of that function and then I get:
>>>>  >
>>>>  >   ./kill_pthread
>>>>  >   Starting high_prio_task
>>>>  >   BUG: NMI Watchdog detected LOCKUP
>>>>  >   Killed low_prio task: count=1588495996, overruns=0
>>>>  >   Exiting main
>>>>  >
>>>>  > I have attached the corresponding oops in case it's of interest.
>>>>  > Unfortunately, with your patch and adding the function
>>>>  > __real_pthread_kill() to wrappers.c, the behavior is the same. I'm going
>>>>  > to repeat the tests with Xenomai trunk tomorrow.
>>>>
>>>> The oops is due to the NMI watchdog calling some linux domain functions
>>>> over Xenomai domain. You should probably use Xenomai watchdog instead.
>>>>
>>>> As for the reason why the watchdog triggers: are you sure you are
>>>> running the kernel recompiled after having applied the patch?
>>> Indeed, after a "make clean; make bzImage" of the kernel it behaves
>>> differently. Wired, may be some dependency issue.
>>>
>>>   # ./kill_pthread
>>>   Starting high_prio_task
>>>   low_prio_task: policy=1 prio=10
>>>   Killed low_prio task: count=172709970, overruns=0
>>>
>>>   [1]+  Stopped                 ./kill_pthread
>> What you are observing is probably a difference between linuxthreads
>> and NPTL: with linuxthreads, SIGSTOP can be sent to a particular
>> thread and will cause this thread only to stop. With NPTL, it seems
>> that the effect of SIGSTOP is global, it affects the entire process. I
>> will test tonight on my x86 box to see if I observe the same effect.
> 
> Ah, the man page says:
> 
>  Note  that  pthread_kill()  only causes the signal to be handled in the
>  context of the given thread; the signal action  (termination  or  stop-
>  ping) affects the process as a whole.

The attached test application using a more sophisticated signal handling
works fine on my MPC5200-board running Linux 2.6.23 and Xenomai trunk.
Going to try it tomorrow on my PC.

Wolfgang.

[-- Attachment #2: kill_pthread.c --]
[-- Type: text/x-csrc, Size: 5523 bytes --]

#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <sys/mman.h>

static int count;
static int goon = 1;

static pthread_t id_low;
static pthread_t id_high;

#define LOW_PRIO 5
#define HIGH_PRIO 10

#undef WITH_PRINTF
#undef WITH_SIGXCPU

void init_task(int prio);

void* low_prio_task(void* dummy)
{
        struct sched_param  param;
        int policy;

        pthread_getschedparam(pthread_self(), &policy, &param);
        printf("%s: policy=%d prio=%d\n",
               __FUNCTION__, policy, param.sched_priority);

        param.sched_priority = LOW_PRIO;
        pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);

        while (goon) {
#ifdef WITH_PRINTF
		pthread_set_mode_np(0, PTHREAD_PRIMARY);
                printf("%s %d\n", __FUNCTION__, count);
#endif
                count++;
        }
        printf("Exiting %s, count=%d\n", __FUNCTION__, count);
        return 0;
}

void* high_prio_task(void* dummy)
{
        struct timespec tstart = { .tv_sec = 0, .tv_nsec = 0};
#ifdef WITH_PRINTF
        struct timespec tperiod = { .tv_sec = 0, .tv_nsec = 10000000 };
#else
        struct timespec tperiod = { .tv_sec = 0, .tv_nsec = 1000000 };
#endif
        unsigned long overruns = 0;
        int tick = 0, step = 0, loop = 0, err;
        struct sched_param  param = { .sched_priority = HIGH_PRIO };

        printf("Starting %s\n", __FUNCTION__);

        pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);

#ifdef WITH_SIGXCPU
        pthread_set_mode_np(0, PTHREAD_WARNSW);
#endif
        err = pthread_make_periodic_np(pthread_self(), &tstart, &tperiod);
        if (err)
                return (void *)err;

        while (1) {
                err = pthread_wait_np(&overruns);
#if 0
                if (err) {
                        pthread_kill(id_low, SIGSTOP);
                        printf("%s overruns=%lu, tick=%d, count=%d, err=%d\n",
                               __FUNCTION__, overruns, tick, count, err);
                        return 0;
                }
#endif
                if  (step == 0 && loop > 100) {
                        loop = 0;
                        step = 1;
                        init_task(LOW_PRIO);
                }
                else if (step == 1 && loop > 500) {
                        loop = 0;
                        step = 2;
                        //goon = 0;
                        pthread_kill(id_low, SIGUSR1);
                        printf("SIGUSER1 to id_low: count=%d, overruns=%lu\n",
                               count, overruns);
                }
                else if (step == 2 && loop > 500) {
			loop = 0;
			step = 1;
			pthread_kill(id_low, SIGUSR2);
                        printf("SIGUSER2 to id_low: count=%d, overruns=%lu\n",
                               count, overruns);
		}
                tick++;
                loop++;
        }
        printf("Exiting %s\n", __FUNCTION__);
        return 0;
}

void init_task(int prio)
{
   struct sched_param parm;
   pthread_attr_t attr;

   pthread_attr_init(&attr);
   if (prio == HIGH_PRIO)
           pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
   else
           pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
   pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
   parm.sched_priority = prio;
   pthread_attr_setschedparam(&attr, &parm);

   if (prio == HIGH_PRIO) {
           pthread_create(&id_high, &attr, high_prio_task, NULL);
           pthread_set_name_np(id_high,"high_prio");
   } else {
           pthread_create(&id_low, &attr, low_prio_task, NULL);
           pthread_set_name_np(id_low,"low_prio");
   }
}

void catch_signal(int sig)
{
        printf("Signal %d catched\n", sig);
}

#ifdef WITH_SIGXCPU
void catch_switch(int sig)
{
        void *bt[32];
        int nentries;

        printf("Signal %d catched\n", sig);

        /* 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

static void suspend_signal_handler(int sig)
{
   sigset_t signal_set;

   printf("suspend signal handler\n");
   sigfillset (&signal_set);
   sigdelset (&signal_set, SIGUSR2);
   sigsuspend(&signal_set);

   return;
}

static void resume_signal_handler(int sig)
{
   printf("resume signal handler\n");
   return;
}


void init_signals(sigset_t *mask)
{
   struct sigaction sigusr1, sigusr2;

   sigemptyset(mask);
   sigaddset(mask, SIGINT);
   sigaddset(mask, SIGTERM);
   sigaddset(mask, SIGHUP);
   sigaddset(mask, SIGALRM);

   pthread_sigmask(SIG_BLOCK, mask, NULL);

   /*
    * Install the signal handlers for suspend/resume.
    */

   sigemptyset (&sigusr1.sa_mask);
   sigusr1.sa_flags = 0;
   sigusr1.sa_handler = suspend_signal_handler;
   sigaction(SIGUSR1, &sigusr1, NULL);

   sigemptyset (&sigusr2.sa_mask);
   sigusr2.sa_flags = 0;
   sigusr2.sa_handler = resume_signal_handler;
   sigaction(SIGUSR2, &sigusr2, NULL);

}

int main(int argc, char *argv[])
{
	sigset_t mask;
	int sig;

        mlockall(MCL_CURRENT|MCL_FUTURE);

#ifdef WITH_SIGXCPU
        signal(SIGXCPU, catch_switch);
#endif
#if 0
        signal(SIGTERM, catch_signal);
        signal(SIGINT, catch_signal);
        signal(SIGHUP, catch_signal);
#else
	init_signals(&mask);
#endif

        init_task(HIGH_PRIO);


#if 0
        pthread_join(id_high, NULL);
#else
	sigwait(&mask, &sig);
#endif

        printf("Exiting %s\n", __FUNCTION__);
        return 0;
}

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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-10 21:39                           ` Wolfgang Grandegger
  2007-12-10 21:46                             ` Wolfgang Grandegger
@ 2007-12-10 21:56                             ` Gilles Chanteperdrix
  1 sibling, 0 replies; 33+ messages in thread
From: Gilles Chanteperdrix @ 2007-12-10 21:56 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: xenomai-core

Wolfgang Grandegger wrote:
 > Gilles Chanteperdrix wrote:
 > > On Dec 10, 2007 4:20 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
 > >> Gilles Chanteperdrix wrote:
 > >>> Wolfgang Grandegger wrote:
 > >>   # ./kill_pthread
 > >>   Starting high_prio_task
 > >>   low_prio_task: policy=1 prio=10
 > >>   Killed low_prio task: count=172709970, overruns=0
 > >>
 > >>   [1]+  Stopped                 ./kill_pthread
 > > 
 > > What you are observing is probably a difference between linuxthreads
 > > and NPTL: with linuxthreads, SIGSTOP can be sent to a particular
 > > thread and will cause this thread only to stop. With NPTL, it seems
 > > that the effect of SIGSTOP is global, it affects the entire process. I
 > > will test tonight on my x86 box to see if I observe the same effect.
 > 
 > Ah, the man page says:
 > 
 >  Note  that  pthread_kill()  only causes the signal to be handled in the
 >  context of the given thread; the signal action  (termination  or  stop-
 >  ping) affects the process as a whole.

I can confirm the same effect on plain Linux. So, the newly added
pthread_kill is not to blame (yet).

-- 


					    Gilles Chanteperdrix.


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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-10 15:20                       ` Wolfgang Grandegger
  2007-12-10 15:55                         ` Gilles Chanteperdrix
  2007-12-10 21:21                         ` Gilles Chanteperdrix
@ 2007-12-10 22:11                         ` Gilles Chanteperdrix
  2007-12-11  7:45                           ` Wolfgang Grandegger
  2 siblings, 1 reply; 33+ messages in thread
From: Gilles Chanteperdrix @ 2007-12-10 22:11 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: xenomai-core

Wolfgang Grandegger wrote:
 > After adding pthread_getschedparam() I realized, that policy was 1 and
 > prio 10 and not as expected 5. The corresponding attribute settings
 > before calling pthread_create have been ignored somehow. Am I doing
 > something wrong in task_init()?

Wait, what you observe here is that the low prio task inherits
scheduling parameter from the high prio task. The default value for the
inheritsched attribute is PTHREAD_INHERIT_SCHED. So, if you want to set
explicitely the scheduling parameter, you should call
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);

-- 


					    Gilles Chanteperdrix.


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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-10 22:11                         ` Gilles Chanteperdrix
@ 2007-12-11  7:45                           ` Wolfgang Grandegger
  0 siblings, 0 replies; 33+ messages in thread
From: Wolfgang Grandegger @ 2007-12-11  7:45 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai-core

Gilles Chanteperdrix wrote:
> Wolfgang Grandegger wrote:
>  > After adding pthread_getschedparam() I realized, that policy was 1 and
>  > prio 10 and not as expected 5. The corresponding attribute settings
>  > before calling pthread_create have been ignored somehow. Am I doing
>  > something wrong in task_init()?
> 
> Wait, what you observe here is that the low prio task inherits
> scheduling parameter from the high prio task. The default value for the
> inheritsched attribute is PTHREAD_INHERIT_SCHED. So, if you want to set
> explicitely the scheduling parameter, you should call
> pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);

You are right. With PTHREAD_EXPLICIT_SCHED it works as expected with
2.6. With 2.4, it seems to be the default. I'm not really an advanced
POSIX/PTHREAD programmer :-(.

Wolfgang,


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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-10 21:46                             ` Wolfgang Grandegger
@ 2007-12-11 13:20                               ` Wolfgang Grandegger
  2007-12-11 13:23                                 ` Gilles Chanteperdrix
  0 siblings, 1 reply; 33+ messages in thread
From: Wolfgang Grandegger @ 2007-12-11 13:20 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai-core

Wolfgang Grandegger wrote:
> The attached test application using a more sophisticated signal handling
> works fine on my MPC5200-board running Linux 2.6.23 and Xenomai trunk.
> Going to try it tomorrow on my PC.

It works fine as well on my PC with Linux 2.6.23 and Xenomai trunk and
now also with Linux 2.4.25 and Xenomai 2.3.x :-). Just to understand it
right: The task signaled with pthread_kill() will be suspended and
switches to secondary mode if it was running in primary mode. The signal
will then be handled by Linux as usual. When the task resumes, does it
get switched back to primary mode automatically?

Great, the only open issue is why executing init_task() switches to
secondary mode resulting in period overruns in high_prio_task(). Is that
obvious to you?

Thanks a lot.

Wolfgang.


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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-11 13:20                               ` Wolfgang Grandegger
@ 2007-12-11 13:23                                 ` Gilles Chanteperdrix
  2007-12-11 14:39                                   ` Wolfgang Grandegger
  0 siblings, 1 reply; 33+ messages in thread
From: Gilles Chanteperdrix @ 2007-12-11 13:23 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: xenomai-core

On Dec 11, 2007 2:20 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
> Wolfgang Grandegger wrote:
> > The attached test application using a more sophisticated signal handling
> > works fine on my MPC5200-board running Linux 2.6.23 and Xenomai trunk.
> > Going to try it tomorrow on my PC.
>
> It works fine as well on my PC with Linux 2.6.23 and Xenomai trunk and
> now also with Linux 2.4.25 and Xenomai 2.3.x :-). Just to understand it
> right: The task signaled with pthread_kill() will be suspended and
> switches to secondary mode if it was running in primary mode. The signal
> will then be handled by Linux as usual. When the task resumes, does it
> get switched back to primary mode automatically?

No, it will get swtiched back to primary mode only if it calls a
service needing primary mode.

>
> Great, the only open issue is why executing init_task() switches to
> secondary mode resulting in period overruns in high_prio_task(). Is that
> obvious to you?

init_task calls pthread_create, which needs running in secondary mode
to create a thread. We can not create a task without help from
secondary mode.


-- 
                                               Gilles Chanteperdrix


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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-11 13:23                                 ` Gilles Chanteperdrix
@ 2007-12-11 14:39                                   ` Wolfgang Grandegger
  2007-12-11 19:59                                     ` Gilles Chanteperdrix
  0 siblings, 1 reply; 33+ messages in thread
From: Wolfgang Grandegger @ 2007-12-11 14:39 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai-core

Gilles Chanteperdrix wrote:
> On Dec 11, 2007 2:20 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>> Wolfgang Grandegger wrote:
>>> The attached test application using a more sophisticated signal handling
>>> works fine on my MPC5200-board running Linux 2.6.23 and Xenomai trunk.
>>> Going to try it tomorrow on my PC.
>> It works fine as well on my PC with Linux 2.6.23 and Xenomai trunk and
>> now also with Linux 2.4.25 and Xenomai 2.3.x :-). Just to understand it
>> right: The task signaled with pthread_kill() will be suspended and
>> switches to secondary mode if it was running in primary mode. The signal
>> will then be handled by Linux as usual. When the task resumes, does it
>> get switched back to primary mode automatically?
> 
> No, it will get swtiched back to primary mode only if it calls a
> service needing primary mode.

OK.

>> Great, the only open issue is why executing init_task() switches to
>> secondary mode resulting in period overruns in high_prio_task(). Is that
>> obvious to you?
> 
> init_task calls pthread_create, which needs running in secondary mode
> to create a thread. We can not create a task without help from
> secondary mode.

OK.

I was a bit quick with my assumption that it works with 2.4. It actually
only works, if I have a pthread_set_mode_np() in the while loop of the
primary task:

        while (1) {
		pthread_set_mode_np(0, PTHREAD_PRIMARY);
                count++;
        }

Without pthread_set_mode_np(), the system hangs after the following
output lines:

  bash-2.05b# ./kill_pthread2
  Starting high_prio_task
  low_prio_task: policy=1 prio=5
  SIGUSER1 to id_low: count=17497245, overruns=0

It seems to hang when the low_prio_task() calls pthread_wait_np()
thereafter. Any quick idea where the problem is?

Wolfgang.



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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-11 14:39                                   ` Wolfgang Grandegger
@ 2007-12-11 19:59                                     ` Gilles Chanteperdrix
  2007-12-12  7:56                                       ` Wolfgang Grandegger
  0 siblings, 1 reply; 33+ messages in thread
From: Gilles Chanteperdrix @ 2007-12-11 19:59 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: xenomai-core

Wolfgang Grandegger wrote:
 > Gilles Chanteperdrix wrote:
 > > On Dec 11, 2007 2:20 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
 > >> Wolfgang Grandegger wrote:
 > >>> The attached test application using a more sophisticated signal handling
 > >>> works fine on my MPC5200-board running Linux 2.6.23 and Xenomai trunk.
 > >>> Going to try it tomorrow on my PC.
 > >> It works fine as well on my PC with Linux 2.6.23 and Xenomai trunk and
 > >> now also with Linux 2.4.25 and Xenomai 2.3.x :-). Just to understand it
 > >> right: The task signaled with pthread_kill() will be suspended and
 > >> switches to secondary mode if it was running in primary mode. The signal
 > >> will then be handled by Linux as usual. When the task resumes, does it
 > >> get switched back to primary mode automatically?
 > > 
 > > No, it will get swtiched back to primary mode only if it calls a
 > > service needing primary mode.
 > 
 > OK.
 > 
 > >> Great, the only open issue is why executing init_task() switches to
 > >> secondary mode resulting in period overruns in high_prio_task(). Is that
 > >> obvious to you?
 > > 
 > > init_task calls pthread_create, which needs running in secondary mode
 > > to create a thread. We can not create a task without help from
 > > secondary mode.
 > 
 > OK.
 > 
 > I was a bit quick with my assumption that it works with 2.4. It actually
 > only works, if I have a pthread_set_mode_np() in the while loop of the
 > primary task:
 > 
 >         while (1) {
 > 		pthread_set_mode_np(0, PTHREAD_PRIMARY);
 >                 count++;
 >         }
 > 
 > Without pthread_set_mode_np(), the system hangs after the following
 > output lines:
 > 
 >   bash-2.05b# ./kill_pthread2
 >   Starting high_prio_task
 >   low_prio_task: policy=1 prio=5
 >   SIGUSER1 to id_low: count=17497245, overruns=0
 > 
 > It seems to hang when the low_prio_task() calls pthread_wait_np()
 > thereafter. Any quick idea where the problem is?

I am clueless. Are you sure you recompiled the kernel after applying the
patch adding the pthread_kill syscall ?

-- 


					    Gilles Chanteperdrix.


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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-11 19:59                                     ` Gilles Chanteperdrix
@ 2007-12-12  7:56                                       ` Wolfgang Grandegger
  2007-12-12  9:07                                         ` Gilles Chanteperdrix
  0 siblings, 1 reply; 33+ messages in thread
From: Wolfgang Grandegger @ 2007-12-12  7:56 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai-core

Gilles Chanteperdrix wrote:
> Wolfgang Grandegger wrote:
>  > Gilles Chanteperdrix wrote:
>  > > On Dec 11, 2007 2:20 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>  > >> Wolfgang Grandegger wrote:
>  > >>> The attached test application using a more sophisticated signal handling
>  > >>> works fine on my MPC5200-board running Linux 2.6.23 and Xenomai trunk.
>  > >>> Going to try it tomorrow on my PC.
>  > >> It works fine as well on my PC with Linux 2.6.23 and Xenomai trunk and
>  > >> now also with Linux 2.4.25 and Xenomai 2.3.x :-). Just to understand it
>  > >> right: The task signaled with pthread_kill() will be suspended and
>  > >> switches to secondary mode if it was running in primary mode. The signal
>  > >> will then be handled by Linux as usual. When the task resumes, does it
>  > >> get switched back to primary mode automatically?
>  > > 
>  > > No, it will get swtiched back to primary mode only if it calls a
>  > > service needing primary mode.
>  > 
>  > OK.
>  > 
>  > >> Great, the only open issue is why executing init_task() switches to
>  > >> secondary mode resulting in period overruns in high_prio_task(). Is that
>  > >> obvious to you?
>  > > 
>  > > init_task calls pthread_create, which needs running in secondary mode
>  > > to create a thread. We can not create a task without help from
>  > > secondary mode.
>  > 
>  > OK.
>  > 
>  > I was a bit quick with my assumption that it works with 2.4. It actually
>  > only works, if I have a pthread_set_mode_np() in the while loop of the
>  > primary task:
>  > 
>  >         while (1) {
>  > 		pthread_set_mode_np(0, PTHREAD_PRIMARY);
>  >                 count++;
>  >         }
>  > 
>  > Without pthread_set_mode_np(), the system hangs after the following
>  > output lines:
>  > 
>  >   bash-2.05b# ./kill_pthread2
>  >   Starting high_prio_task
>  >   low_prio_task: policy=1 prio=5
>  >   SIGUSER1 to id_low: count=17497245, overruns=0
>  > 
>  > It seems to hang when the low_prio_task() calls pthread_wait_np()
>  > thereafter. Any quick idea where the problem is?
> 
> I am clueless. Are you sure you recompiled the kernel after applying the
> patch adding the pthread_kill syscall ?

Well, I tried with v2.3.2, v2.3.x and also trunk, which does not require
the patch. Unfortunately, all versions show the same behavior.

Wolfgang.



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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-12  7:56                                       ` Wolfgang Grandegger
@ 2007-12-12  9:07                                         ` Gilles Chanteperdrix
  2007-12-12  9:59                                           ` Wolfgang Grandegger
  0 siblings, 1 reply; 33+ messages in thread
From: Gilles Chanteperdrix @ 2007-12-12  9:07 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: xenomai-core

Wolfgang Grandegger wrote:
 > Gilles Chanteperdrix wrote:
 > > Wolfgang Grandegger wrote:
 > >  > Gilles Chanteperdrix wrote:
 > >  > > On Dec 11, 2007 2:20 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
 > >  > >> Wolfgang Grandegger wrote:
 > >  > >>> The attached test application using a more sophisticated signal handling
 > >  > >>> works fine on my MPC5200-board running Linux 2.6.23 and Xenomai trunk.
 > >  > >>> Going to try it tomorrow on my PC.
 > >  > >> It works fine as well on my PC with Linux 2.6.23 and Xenomai trunk and
 > >  > >> now also with Linux 2.4.25 and Xenomai 2.3.x :-). Just to understand it
 > >  > >> right: The task signaled with pthread_kill() will be suspended and
 > >  > >> switches to secondary mode if it was running in primary mode. The signal
 > >  > >> will then be handled by Linux as usual. When the task resumes, does it
 > >  > >> get switched back to primary mode automatically?
 > >  > > 
 > >  > > No, it will get swtiched back to primary mode only if it calls a
 > >  > > service needing primary mode.
 > >  > 
 > >  > OK.
 > >  > 
 > >  > >> Great, the only open issue is why executing init_task() switches to
 > >  > >> secondary mode resulting in period overruns in high_prio_task(). Is that
 > >  > >> obvious to you?
 > >  > > 
 > >  > > init_task calls pthread_create, which needs running in secondary mode
 > >  > > to create a thread. We can not create a task without help from
 > >  > > secondary mode.
 > >  > 
 > >  > OK.
 > >  > 
 > >  > I was a bit quick with my assumption that it works with 2.4. It actually
 > >  > only works, if I have a pthread_set_mode_np() in the while loop of the
 > >  > primary task:
 > >  > 
 > >  >         while (1) {
 > >  > 		pthread_set_mode_np(0, PTHREAD_PRIMARY);
 > >  >                 count++;
 > >  >         }
 > >  > 
 > >  > Without pthread_set_mode_np(), the system hangs after the following
 > >  > output lines:
 > >  > 
 > >  >   bash-2.05b# ./kill_pthread2
 > >  >   Starting high_prio_task
 > >  >   low_prio_task: policy=1 prio=5
 > >  >   SIGUSER1 to id_low: count=17497245, overruns=0
 > >  > 
 > >  > It seems to hang when the low_prio_task() calls pthread_wait_np()
 > >  > thereafter. Any quick idea where the problem is?
 > > 
 > > I am clueless. Are you sure you recompiled the kernel after applying the
 > > patch adding the pthread_kill syscall ?
 > 
 > Well, I tried with v2.3.2, v2.3.x and also trunk, which does not require
 > the patch. Unfortunately, all versions show the same behavior.

Did you check all the system call return values to see if one of them is
not failing ?

-- 


					    Gilles Chanteperdrix.


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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-12  9:07                                         ` Gilles Chanteperdrix
@ 2007-12-12  9:59                                           ` Wolfgang Grandegger
  2007-12-12 20:08                                             ` Gilles Chanteperdrix
  0 siblings, 1 reply; 33+ messages in thread
From: Wolfgang Grandegger @ 2007-12-12  9:59 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai-core

Gilles Chanteperdrix wrote:
> Wolfgang Grandegger wrote:
>  > Gilles Chanteperdrix wrote:
>  > > Wolfgang Grandegger wrote:
>  > >  > Gilles Chanteperdrix wrote:
>  > >  > > On Dec 11, 2007 2:20 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>  > >  > >> Wolfgang Grandegger wrote:
>  > >  > >>> The attached test application using a more sophisticated signal handling
>  > >  > >>> works fine on my MPC5200-board running Linux 2.6.23 and Xenomai trunk.
>  > >  > >>> Going to try it tomorrow on my PC.
>  > >  > >> It works fine as well on my PC with Linux 2.6.23 and Xenomai trunk and
>  > >  > >> now also with Linux 2.4.25 and Xenomai 2.3.x :-). Just to understand it
>  > >  > >> right: The task signaled with pthread_kill() will be suspended and
>  > >  > >> switches to secondary mode if it was running in primary mode. The signal
>  > >  > >> will then be handled by Linux as usual. When the task resumes, does it
>  > >  > >> get switched back to primary mode automatically?
>  > >  > > 
>  > >  > > No, it will get swtiched back to primary mode only if it calls a
>  > >  > > service needing primary mode.
>  > >  > 
>  > >  > OK.
>  > >  > 
>  > >  > >> Great, the only open issue is why executing init_task() switches to
>  > >  > >> secondary mode resulting in period overruns in high_prio_task(). Is that
>  > >  > >> obvious to you?
>  > >  > > 
>  > >  > > init_task calls pthread_create, which needs running in secondary mode
>  > >  > > to create a thread. We can not create a task without help from
>  > >  > > secondary mode.
>  > >  > 
>  > >  > OK.
>  > >  > 
>  > >  > I was a bit quick with my assumption that it works with 2.4. It actually
>  > >  > only works, if I have a pthread_set_mode_np() in the while loop of the
>  > >  > primary task:
>  > >  > 
>  > >  >         while (1) {
>  > >  > 		pthread_set_mode_np(0, PTHREAD_PRIMARY);
>  > >  >                 count++;
>  > >  >         }
>  > >  > 
>  > >  > Without pthread_set_mode_np(), the system hangs after the following
>  > >  > output lines:
>  > >  > 
>  > >  >   bash-2.05b# ./kill_pthread2
>  > >  >   Starting high_prio_task
>  > >  >   low_prio_task: policy=1 prio=5
>  > >  >   SIGUSER1 to id_low: count=17497245, overruns=0
>  > >  > 
>  > >  > It seems to hang when the low_prio_task() calls pthread_wait_np()
>  > >  > thereafter. Any quick idea where the problem is?
>  > > 
>  > > I am clueless. Are you sure you recompiled the kernel after applying the
>  > > patch adding the pthread_kill syscall ?
>  > 
>  > Well, I tried with v2.3.2, v2.3.x and also trunk, which does not require
>  > the patch. Unfortunately, all versions show the same behavior.
> 
> Did you check all the system call return values to see if one of them is
> not failing ?

pthread_kill() returns always 0, or what do you exactly mean. I also
checked with printk() that ksrc/skins/posix/signal.c:pthread_kill() gets
called. I realized the following behaviour if I call a printf after a
certain count value:

  void* low_prio_task(void* dummy)
  {
     while (1) {
		count++;
		if (count == 100000000)
			printf("Wakeup\n");
        }
     return 0;
  }

Then the program goes on when the above count value is reached:

  Starting high_prio_task
  low_prio_task: policy=1 prio=5
  SIGUSER1 to id_low: count=13819079, overruns=0
  ... blocks for a while ...
  SIGUSER2 to id_low: count=27681649, overruns=0
  suspend signal handler
  resume signal handler
  SIGUSER1 to id_low: count=100000000, overruns=0
  SIGUSER2 to id_low: count=100000000, overruns=0
  resume signal handler
  suspend signal handler
  SIGUSER1 to id_low: count=100000000, overruns=0
  SIGUSER2 to id_low: count=100000000, overruns=0
  ...

This shows that the task did not get suspended before the printf is
executed. And thereafter it never really resumes.

Wolfgang.


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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-12  9:59                                           ` Wolfgang Grandegger
@ 2007-12-12 20:08                                             ` Gilles Chanteperdrix
  2007-12-12 21:00                                               ` Wolfgang Grandegger
  0 siblings, 1 reply; 33+ messages in thread
From: Gilles Chanteperdrix @ 2007-12-12 20:08 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: xenomai-core

Wolfgang Grandegger wrote:
 > Gilles Chanteperdrix wrote:
 > > Wolfgang Grandegger wrote:
 > >  > Gilles Chanteperdrix wrote:
 > >  > > Wolfgang Grandegger wrote:
 > >  > >  > Gilles Chanteperdrix wrote:
 > >  > >  > > On Dec 11, 2007 2:20 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
 > >  > >  > >> Wolfgang Grandegger wrote:
 > >  > >  > >>> The attached test application using a more sophisticated signal handling
 > >  > >  > >>> works fine on my MPC5200-board running Linux 2.6.23 and Xenomai trunk.
 > >  > >  > >>> Going to try it tomorrow on my PC.
 > >  > >  > >> It works fine as well on my PC with Linux 2.6.23 and Xenomai trunk and
 > >  > >  > >> now also with Linux 2.4.25 and Xenomai 2.3.x :-). Just to understand it
 > >  > >  > >> right: The task signaled with pthread_kill() will be suspended and
 > >  > >  > >> switches to secondary mode if it was running in primary mode. The signal
 > >  > >  > >> will then be handled by Linux as usual. When the task resumes, does it
 > >  > >  > >> get switched back to primary mode automatically?
 > >  > >  > > 
 > >  > >  > > No, it will get swtiched back to primary mode only if it calls a
 > >  > >  > > service needing primary mode.
 > >  > >  > 
 > >  > >  > OK.
 > >  > >  > 
 > >  > >  > >> Great, the only open issue is why executing init_task() switches to
 > >  > >  > >> secondary mode resulting in period overruns in high_prio_task(). Is that
 > >  > >  > >> obvious to you?
 > >  > >  > > 
 > >  > >  > > init_task calls pthread_create, which needs running in secondary mode
 > >  > >  > > to create a thread. We can not create a task without help from
 > >  > >  > > secondary mode.
 > >  > >  > 
 > >  > >  > OK.
 > >  > >  > 
 > >  > >  > I was a bit quick with my assumption that it works with 2.4. It actually
 > >  > >  > only works, if I have a pthread_set_mode_np() in the while loop of the
 > >  > >  > primary task:
 > >  > >  > 
 > >  > >  >         while (1) {
 > >  > >  > 		pthread_set_mode_np(0, PTHREAD_PRIMARY);
 > >  > >  >                 count++;
 > >  > >  >         }
 > >  > >  > 
 > >  > >  > Without pthread_set_mode_np(), the system hangs after the following
 > >  > >  > output lines:
 > >  > >  > 
 > >  > >  >   bash-2.05b# ./kill_pthread2
 > >  > >  >   Starting high_prio_task
 > >  > >  >   low_prio_task: policy=1 prio=5
 > >  > >  >   SIGUSER1 to id_low: count=17497245, overruns=0
 > >  > >  > 
 > >  > >  > It seems to hang when the low_prio_task() calls pthread_wait_np()
 > >  > >  > thereafter. Any quick idea where the problem is?
 > >  > > 
 > >  > > I am clueless. Are you sure you recompiled the kernel after applying the
 > >  > > patch adding the pthread_kill syscall ?
 > >  > 
 > >  > Well, I tried with v2.3.2, v2.3.x and also trunk, which does not require
 > >  > the patch. Unfortunately, all versions show the same behavior.
 > > 
 > > Did you check all the system call return values to see if one of them is
 > > not failing ?
 > 
 > pthread_kill() returns always 0, or what do you exactly mean. I also
 > checked with printk() that ksrc/skins/posix/signal.c:pthread_kill() gets
 > called. I realized the following behaviour if I call a printf after a
 > certain count value:
 > 
 >   void* low_prio_task(void* dummy)
 >   {
 >      while (1) {
 > 		count++;
 > 		if (count == 100000000)
 > 			printf("Wakeup\n");
 >         }
 >      return 0;
 >   }
 > 
 > Then the program goes on when the above count value is reached:
 > 
 >   Starting high_prio_task
 >   low_prio_task: policy=1 prio=5
 >   SIGUSER1 to id_low: count=13819079, overruns=0
 >   ... blocks for a while ...
 >   SIGUSER2 to id_low: count=27681649, overruns=0
 >   suspend signal handler
 >   resume signal handler
 >   SIGUSER1 to id_low: count=100000000, overruns=0
 >   SIGUSER2 to id_low: count=100000000, overruns=0
 >   resume signal handler
 >   suspend signal handler
 >   SIGUSER1 to id_low: count=100000000, overruns=0
 >   SIGUSER2 to id_low: count=100000000, overruns=0
 >   ...
 > 
 > This shows that the task did not get suspended before the printf is
 > executed. And thereafter it never really resumes.

I tested the last program you posted, and it works on ARM (where I am
using linuxthreads, not NPTL), as far as I can tell. Could you send the
one that does not work ?

-- 


					    Gilles Chanteperdrix.


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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-12 20:08                                             ` Gilles Chanteperdrix
@ 2007-12-12 21:00                                               ` Wolfgang Grandegger
  2007-12-12 21:48                                                 ` Gilles Chanteperdrix
  0 siblings, 1 reply; 33+ messages in thread
From: Wolfgang Grandegger @ 2007-12-12 21:00 UTC (permalink / raw)
  To: Gilles Chanteperdrix; +Cc: xenomai-core

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

Gilles Chanteperdrix wrote:
> Wolfgang Grandegger wrote:
>  > Gilles Chanteperdrix wrote:
>  > > Wolfgang Grandegger wrote:
>  > >  > Gilles Chanteperdrix wrote:
>  > >  > > Wolfgang Grandegger wrote:
>  > >  > >  > Gilles Chanteperdrix wrote:
>  > >  > >  > > On Dec 11, 2007 2:20 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
>  > >  > >  > >> Wolfgang Grandegger wrote:
>  > >  > >  > >>> The attached test application using a more sophisticated signal handling
>  > >  > >  > >>> works fine on my MPC5200-board running Linux 2.6.23 and Xenomai trunk.
>  > >  > >  > >>> Going to try it tomorrow on my PC.
>  > >  > >  > >> It works fine as well on my PC with Linux 2.6.23 and Xenomai trunk and
>  > >  > >  > >> now also with Linux 2.4.25 and Xenomai 2.3.x :-). Just to understand it
>  > >  > >  > >> right: The task signaled with pthread_kill() will be suspended and
>  > >  > >  > >> switches to secondary mode if it was running in primary mode. The signal
>  > >  > >  > >> will then be handled by Linux as usual. When the task resumes, does it
>  > >  > >  > >> get switched back to primary mode automatically?
>  > >  > >  > > 
>  > >  > >  > > No, it will get swtiched back to primary mode only if it calls a
>  > >  > >  > > service needing primary mode.
>  > >  > >  > 
>  > >  > >  > OK.
>  > >  > >  > 
>  > >  > >  > >> Great, the only open issue is why executing init_task() switches to
>  > >  > >  > >> secondary mode resulting in period overruns in high_prio_task(). Is that
>  > >  > >  > >> obvious to you?
>  > >  > >  > > 
>  > >  > >  > > init_task calls pthread_create, which needs running in secondary mode
>  > >  > >  > > to create a thread. We can not create a task without help from
>  > >  > >  > > secondary mode.
>  > >  > >  > 
>  > >  > >  > OK.
>  > >  > >  > 
>  > >  > >  > I was a bit quick with my assumption that it works with 2.4. It actually
>  > >  > >  > only works, if I have a pthread_set_mode_np() in the while loop of the
>  > >  > >  > primary task:
>  > >  > >  > 
>  > >  > >  >         while (1) {
>  > >  > >  > 		pthread_set_mode_np(0, PTHREAD_PRIMARY);
>  > >  > >  >                 count++;
>  > >  > >  >         }
>  > >  > >  > 
>  > >  > >  > Without pthread_set_mode_np(), the system hangs after the following
>  > >  > >  > output lines:
>  > >  > >  > 
>  > >  > >  >   bash-2.05b# ./kill_pthread2
>  > >  > >  >   Starting high_prio_task
>  > >  > >  >   low_prio_task: policy=1 prio=5
>  > >  > >  >   SIGUSER1 to id_low: count=17497245, overruns=0
>  > >  > >  > 
>  > >  > >  > It seems to hang when the low_prio_task() calls pthread_wait_np()
>  > >  > >  > thereafter. Any quick idea where the problem is?
>  > >  > > 
>  > >  > > I am clueless. Are you sure you recompiled the kernel after applying the
>  > >  > > patch adding the pthread_kill syscall ?
>  > >  > 
>  > >  > Well, I tried with v2.3.2, v2.3.x and also trunk, which does not require
>  > >  > the patch. Unfortunately, all versions show the same behavior.
>  > > 
>  > > Did you check all the system call return values to see if one of them is
>  > > not failing ?
>  > 
>  > pthread_kill() returns always 0, or what do you exactly mean. I also
>  > checked with printk() that ksrc/skins/posix/signal.c:pthread_kill() gets
>  > called. I realized the following behaviour if I call a printf after a
>  > certain count value:
>  > 
>  >   void* low_prio_task(void* dummy)
>  >   {
>  >      while (1) {
>  > 		count++;
>  > 		if (count == 100000000)
>  > 			printf("Wakeup\n");
>  >         }
>  >      return 0;
>  >   }
>  > 
>  > Then the program goes on when the above count value is reached:
>  > 
>  >   Starting high_prio_task
>  >   low_prio_task: policy=1 prio=5
>  >   SIGUSER1 to id_low: count=13819079, overruns=0
>  >   ... blocks for a while ...
>  >   SIGUSER2 to id_low: count=27681649, overruns=0
>  >   suspend signal handler
>  >   resume signal handler
>  >   SIGUSER1 to id_low: count=100000000, overruns=0
>  >   SIGUSER2 to id_low: count=100000000, overruns=0
>  >   resume signal handler
>  >   suspend signal handler
>  >   SIGUSER1 to id_low: count=100000000, overruns=0
>  >   SIGUSER2 to id_low: count=100000000, overruns=0
>  >   ...
>  > 
>  > This shows that the task did not get suspended before the printf is
>  > executed. And thereafter it never really resumes.
> 
> I tested the last program you posted, and it works on ARM (where I am
> using linuxthreads, not NPTL), as far as I can tell. Could you send the
> one that does not work ?

Attached. On my MPC5200 it works with pthread_set_mode_np() in the
counter loop of low_prio_thread(), but fails without.

Thanks.

Wolfgang.



[-- Attachment #2: kill_pthread.c --]
[-- Type: text/x-csrc, Size: 4834 bytes --]

#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <sys/mman.h>

static unsigned long count;

static pthread_t id_low;
static pthread_t id_high;

#define LOW_PRIO 5
#define HIGH_PRIO 10

void init_task(int prio);

void* low_prio_task(void* dummy)
{
        struct sched_param  param;
        int policy;

        pthread_getschedparam(pthread_self(), &policy, &param);
        printf("Starting %s: policy=%d prio=%d\n",
               __FUNCTION__, policy, param.sched_priority);

	/* Switch back to primary mode */
        pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);

        while (1) {
#if 0
		pthread_set_mode_np(0, PTHREAD_PRIMARY);
#endif
		count++;
        }
        printf("Exiting %s, count=%lu\n", __FUNCTION__, count);
        return 0;
}

void* high_prio_task(void* dummy)
{
        struct timespec tstart = { .tv_sec = 0, .tv_nsec = 0};
#if 0
        struct timespec tperiod = { .tv_sec = 0, .tv_nsec = 10000000 };
#else
        struct timespec tperiod = { .tv_sec = 0, .tv_nsec = 1000000 };
#endif
        unsigned long overruns = 0;
        int tick = 0, step = 0, loop = 0, err;
        struct sched_param  param = { .sched_priority = HIGH_PRIO };
        int policy;

        pthread_getschedparam(pthread_self(), &policy, &param);
        printf("Starting %s: policy=%d prio=%d\n",
               __FUNCTION__, policy, param.sched_priority);

        err = pthread_make_periodic_np(pthread_self(), &tstart, &tperiod);
        if (err) {
		perror("pthread_make_periodic_np");
		return (void *)err;
	}

        while (1) {
                err = pthread_wait_np(&overruns);
#if 0
                if (err) {
                        err = pthread_kill(id_low, SIGUSR1);
			if (err) {
				perror("pthread_kill");
				break;
			}
                        printf("%s overruns=%lu, tick=%d, count=%lu, err=%d\n",
                               __FUNCTION__, overruns, tick, count, err);
                        loop = 0;
                        step = 2;
                }
#endif
                if  (step == 0 && loop >= 100) {
                        loop = 0;
                        step = 1;
                        init_task(LOW_PRIO);
                }
                else if (step == 1 && loop >= 500) {
                        loop = 0;
                        step = 2;
                        err = pthread_kill(id_low, SIGUSR1);
			if (err) {
				perror("pthread_kill");
				break;
			}
                        printf("SIGUSER1 to id_low: count=%lu, overruns=%lu\n",
                               count, overruns);
                }
                else if (step == 2 && loop >= 500) {
			loop = 0;
			step = 1;
                        printf("SIGUSER2 to id_low: count=%lu, overruns=%lu\n",
                               count, overruns);
			err = pthread_kill(id_low, SIGUSR2);
			if (err) {
				perror("pthread_kill");
				break;
			}
		}
                tick++;
                loop++;
        }
        printf("Exiting %s\n", __FUNCTION__);
	return 0;
}

void init_task(int prio)
{
	struct sched_param parm;
	pthread_attr_t attr;

	pthread_attr_init(&attr);
	pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
	if (prio == HIGH_PRIO)
		pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
	else
		pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
	parm.sched_priority = prio;
	pthread_attr_setschedparam(&attr, &parm);

	if (prio == HIGH_PRIO) {
		pthread_create(&id_high, &attr, high_prio_task, NULL);
		pthread_set_name_np(id_high,"high_prio");
	} else {
		pthread_create(&id_low, &attr, low_prio_task, NULL);
		pthread_set_name_np(id_low,"low_prio");
	}
}

static void suspend_signal_handler(int sig)
{
	sigset_t signal_set;

	printf("suspend signal handler\n");
	sigfillset (&signal_set);
	sigdelset (&signal_set, SIGUSR2);
	sigsuspend(&signal_set);

	return;
}

static void resume_signal_handler(int sig)
{
	printf("resume signal handler\n");
	return;
}


void init_signals(sigset_t *mask)
{
	struct sigaction sigusr1, sigusr2;

	sigemptyset(mask);
	sigaddset(mask, SIGINT);
	sigaddset(mask, SIGTERM);
	sigaddset(mask, SIGHUP);
	sigaddset(mask, SIGALRM);

	pthread_sigmask(SIG_BLOCK, mask, NULL);

	/*
	 * Install the signal handlers for suspend/resume.
	 */
	sigemptyset (&sigusr1.sa_mask);
	sigusr1.sa_flags = 0;
	sigusr1.sa_handler = suspend_signal_handler;
	sigaction(SIGUSR1, &sigusr1, NULL);

	sigemptyset (&sigusr2.sa_mask);
	sigusr2.sa_flags = 0;
	sigusr2.sa_handler = resume_signal_handler;
	sigaction(SIGUSR2, &sigusr2, NULL);

}

int main(int argc, char *argv[])
{
	sigset_t mask;
	int sig;

        mlockall(MCL_CURRENT|MCL_FUTURE);

	init_signals(&mask);

        init_task(HIGH_PRIO);

	sigwait(&mask, &sig);

        printf("Exiting %s\n", __FUNCTION__);
        return 0;
}

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

* Re: [Xenomai-core] How to cancel a Xenomai POSIX thread
  2007-12-12 21:00                                               ` Wolfgang Grandegger
@ 2007-12-12 21:48                                                 ` Gilles Chanteperdrix
  0 siblings, 0 replies; 33+ messages in thread
From: Gilles Chanteperdrix @ 2007-12-12 21:48 UTC (permalink / raw)
  To: Wolfgang Grandegger; +Cc: xenomai-core

Wolfgang Grandegger wrote:
 > Gilles Chanteperdrix wrote:
 > > Wolfgang Grandegger wrote:
 > >  > Gilles Chanteperdrix wrote:
 > >  > > Wolfgang Grandegger wrote:
 > >  > >  > Gilles Chanteperdrix wrote:
 > >  > >  > > Wolfgang Grandegger wrote:
 > >  > >  > >  > Gilles Chanteperdrix wrote:
 > >  > >  > >  > > On Dec 11, 2007 2:20 PM, Wolfgang Grandegger <wg@domain.hid> wrote:
 > >  > >  > >  > >> Wolfgang Grandegger wrote:
 > >  > >  > >  > >>> The attached test application using a more sophisticated signal handling
 > >  > >  > >  > >>> works fine on my MPC5200-board running Linux 2.6.23 and Xenomai trunk.
 > >  > >  > >  > >>> Going to try it tomorrow on my PC.
 > >  > >  > >  > >> It works fine as well on my PC with Linux 2.6.23 and Xenomai trunk and
 > >  > >  > >  > >> now also with Linux 2.4.25 and Xenomai 2.3.x :-). Just to understand it
 > >  > >  > >  > >> right: The task signaled with pthread_kill() will be suspended and
 > >  > >  > >  > >> switches to secondary mode if it was running in primary mode. The signal
 > >  > >  > >  > >> will then be handled by Linux as usual. When the task resumes, does it
 > >  > >  > >  > >> get switched back to primary mode automatically?
 > >  > >  > >  > > 
 > >  > >  > >  > > No, it will get swtiched back to primary mode only if it calls a
 > >  > >  > >  > > service needing primary mode.
 > >  > >  > >  > 
 > >  > >  > >  > OK.
 > >  > >  > >  > 
 > >  > >  > >  > >> Great, the only open issue is why executing init_task() switches to
 > >  > >  > >  > >> secondary mode resulting in period overruns in high_prio_task(). Is that
 > >  > >  > >  > >> obvious to you?
 > >  > >  > >  > > 
 > >  > >  > >  > > init_task calls pthread_create, which needs running in secondary mode
 > >  > >  > >  > > to create a thread. We can not create a task without help from
 > >  > >  > >  > > secondary mode.
 > >  > >  > >  > 
 > >  > >  > >  > OK.
 > >  > >  > >  > 
 > >  > >  > >  > I was a bit quick with my assumption that it works with 2.4. It actually
 > >  > >  > >  > only works, if I have a pthread_set_mode_np() in the while loop of the
 > >  > >  > >  > primary task:
 > >  > >  > >  > 
 > >  > >  > >  >         while (1) {
 > >  > >  > >  > 		pthread_set_mode_np(0, PTHREAD_PRIMARY);
 > >  > >  > >  >                 count++;
 > >  > >  > >  >         }
 > >  > >  > >  > 
 > >  > >  > >  > Without pthread_set_mode_np(), the system hangs after the following
 > >  > >  > >  > output lines:
 > >  > >  > >  > 
 > >  > >  > >  >   bash-2.05b# ./kill_pthread2
 > >  > >  > >  >   Starting high_prio_task
 > >  > >  > >  >   low_prio_task: policy=1 prio=5
 > >  > >  > >  >   SIGUSER1 to id_low: count=17497245, overruns=0
 > >  > >  > >  > 
 > >  > >  > >  > It seems to hang when the low_prio_task() calls pthread_wait_np()
 > >  > >  > >  > thereafter. Any quick idea where the problem is?
 > >  > >  > > 
 > >  > >  > > I am clueless. Are you sure you recompiled the kernel after applying the
 > >  > >  > > patch adding the pthread_kill syscall ?
 > >  > >  > 
 > >  > >  > Well, I tried with v2.3.2, v2.3.x and also trunk, which does not require
 > >  > >  > the patch. Unfortunately, all versions show the same behavior.
 > >  > > 
 > >  > > Did you check all the system call return values to see if one of them is
 > >  > > not failing ?
 > >  > 
 > >  > pthread_kill() returns always 0, or what do you exactly mean. I also
 > >  > checked with printk() that ksrc/skins/posix/signal.c:pthread_kill() gets
 > >  > called. I realized the following behaviour if I call a printf after a
 > >  > certain count value:
 > >  > 
 > >  >   void* low_prio_task(void* dummy)
 > >  >   {
 > >  >      while (1) {
 > >  > 		count++;
 > >  > 		if (count == 100000000)
 > >  > 			printf("Wakeup\n");
 > >  >         }
 > >  >      return 0;
 > >  >   }
 > >  > 
 > >  > Then the program goes on when the above count value is reached:
 > >  > 
 > >  >   Starting high_prio_task
 > >  >   low_prio_task: policy=1 prio=5
 > >  >   SIGUSER1 to id_low: count=13819079, overruns=0
 > >  >   ... blocks for a while ...
 > >  >   SIGUSER2 to id_low: count=27681649, overruns=0
 > >  >   suspend signal handler
 > >  >   resume signal handler
 > >  >   SIGUSER1 to id_low: count=100000000, overruns=0
 > >  >   SIGUSER2 to id_low: count=100000000, overruns=0
 > >  >   resume signal handler
 > >  >   suspend signal handler
 > >  >   SIGUSER1 to id_low: count=100000000, overruns=0
 > >  >   SIGUSER2 to id_low: count=100000000, overruns=0
 > >  >   ...
 > >  > 
 > >  > This shows that the task did not get suspended before the printf is
 > >  > executed. And thereafter it never really resumes.
 > > 
 > > I tested the last program you posted, and it works on ARM (where I am
 > > using linuxthreads, not NPTL), as far as I can tell. Could you send the
 > > one that does not work ?
 > 
 > Attached. On my MPC5200 it works with pthread_set_mode_np() in the
 > counter loop of low_prio_thread(), but fails without.

This one works here. Maybe there is a problem with the I-pipe patch not
invoking signals handlers in some obscure case ?

-- 


					    Gilles Chanteperdrix.


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

end of thread, other threads:[~2007-12-12 21:48 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-12-06 12:31 [Xenomai-core] How to cancel a Xenomai POSIX thread Wolfgang Grandegger
2007-12-06 13:13 ` Gilles Chanteperdrix
2007-12-06 13:24   ` Wolfgang Grandegger
2007-12-06 13:28     ` Gilles Chanteperdrix
2007-12-06 13:44       ` Gilles Chanteperdrix
2007-12-06 14:05         ` Wolfgang Grandegger
2007-12-06 14:21           ` Gilles Chanteperdrix
2007-12-07 14:03             ` Wolfgang Grandegger
2007-12-07 21:23               ` Gilles Chanteperdrix
2007-12-07 22:10                 ` Gilles Chanteperdrix
2007-12-09 21:55                   ` Wolfgang Grandegger
2007-12-09 22:52                     ` Gilles Chanteperdrix
2007-12-10  7:27                       ` Wolfgang Grandegger
2007-12-10 15:20                       ` Wolfgang Grandegger
2007-12-10 15:55                         ` Gilles Chanteperdrix
2007-12-10 21:39                           ` Wolfgang Grandegger
2007-12-10 21:46                             ` Wolfgang Grandegger
2007-12-11 13:20                               ` Wolfgang Grandegger
2007-12-11 13:23                                 ` Gilles Chanteperdrix
2007-12-11 14:39                                   ` Wolfgang Grandegger
2007-12-11 19:59                                     ` Gilles Chanteperdrix
2007-12-12  7:56                                       ` Wolfgang Grandegger
2007-12-12  9:07                                         ` Gilles Chanteperdrix
2007-12-12  9:59                                           ` Wolfgang Grandegger
2007-12-12 20:08                                             ` Gilles Chanteperdrix
2007-12-12 21:00                                               ` Wolfgang Grandegger
2007-12-12 21:48                                                 ` Gilles Chanteperdrix
2007-12-10 21:56                             ` Gilles Chanteperdrix
2007-12-10 21:21                         ` Gilles Chanteperdrix
2007-12-10 21:37                           ` Wolfgang Grandegger
2007-12-10 22:11                         ` Gilles Chanteperdrix
2007-12-11  7:45                           ` Wolfgang Grandegger
2007-12-06 13:47       ` Wolfgang Grandegger

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.