public inbox for ecos-discuss@sourceware.org
 help / color / mirror / Atom feed
From: Dan Jakubiec <djakubiec@yahoo.com>
To: Nick Garnett <nickg@ecoscentric.com>
Cc: ecos-discuss@sources.redhat.com
Subject: Re: [ECOS] POSIX timer callback context
Date: Wed, 29 Oct 2003 17:04:00 -0000	[thread overview]
Message-ID: <20031029170409.44811.qmail@web21204.mail.yahoo.com> (raw)
In-Reply-To: <m3znfkxfdd.fsf@miso.calivar.com>

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

Hi Nick,

Okay, I see what you're saying.  I had to dig into
this a little more to realize that the eCos POSIX
implementation really treats the whole system as one
single process, with each task just being its own
thread within that process.  So in effect, signal
handling is shared amoung all "tasks" in the system.

However, it seems to me that timer signals would be
more useful if an attempt was made to deliver them
back to the thread that set the timer.  Consider the
scenario where you have N instances of the same task
running in parallel, each wanting to be woken up by
their own independent timers.

POSIX has this to say about signal delivery:

---POSIX---
At the time of generation, a determination shall be
made whether the signal has been generated for the
process or for a specific thread within the process.
Signals which are generated by some action
attributable to a particular thread, such as a
hardware fault, shall be generated for the thread that
caused the signal to be generated. Signals that are
generated in association with a process ID or process
group ID or an asynchronous event, such as terminal
activity, shall be generated for the process.
---POSIX---


It seems like an argument could be made that setting a
timer is an "action attributable to a particular
thread".  Last night I enhanced the POSIX timer code
to record the thread that called timer_settime() in
the timer object.  Then, when the timer goes off, it
tries to deliver the signal to that thread first.  The
changes were fairly minor and they seemed to do what I
want.

So my question for you is: do you think this is a
reasonable way to handle timer signal delivery?  Do
you see any problems with this?

I've attached a diff of my (pending) changes for your
reference if you're interested.

Thanks,

---
Dan Jakubiec
Systech Corp





--- Nick Garnett <nickg@ecoscentric.com> wrote:
> Dan Jakubiec <djakubiec@yahoo.com> writes:
> 
> > I'm using a POSIX timer in my application that I
> > created with timer_create().  It is configured to
> > generate a SIGUSR1 signal when the timer expires,
> and
> > to call a signal handler installed by my app's
> thread.
> >  I also have several different tasks running that
> were
> > all created with pthread_create().
> > 
> > When the timer expires, the signal handler gets
> > executed, but it appears to be executing in a
> another
> > thread's context (i.e. pthread_self() returns the
> > handle for one of my other threads).  Furthermore,
> the
> > thread that installed the handler is waiting in a
> > pselect() call that never gets interrupted with
> EINTR.
> > 
> > This seems like a bug to me, but I wanted to pass
> this
> > by the group before fixing it to make sure I
> wasn't
> > missing anything.  Seems like there is a bit of a
> grey
> > area in the POSIX docs about whether signals get
> > delivered to the "process" or one of its
> "threads". 
> > However, it seems that in eCos it would only make
> > sense to deliver signals to the calling thread
> itself.
> > 
> > Does anyone have any background info on the eCos
> > implementation of POSIX timers, or an opinion on
> how
> > POSIX timer callbacks should be processed?
> 
> This is not a bug. The POSIX spec is fairly clear
> that these are
> process-wide signals that will be delivered to any
> thread that has the
> signal unmasked. There are lots of problems with
> doing thread-specific
> signals here that the POSIX committee decided to
> avoid by
> side-stepping the problem.
> 
> If you want to direct the signal to a specific
> thread then just make
> sure that that thread is the only one with the
> signal unmasked. The
> best way to ensure this is to mask it in the signal
> mask of main()
> before creating any other threads, which will then
> inherit main()'s
> mask, and unmask it in the target thread.
> 
> 
> -- 
> Nick Garnett                    eCos Kernel
> Architect
> http://www.ecoscentric.com      The eCos and RedBoot
> experts
> 

__________________________________
Do you Yahoo!?
Exclusive Video Premiere - Britney Spears
http://launch.yahoo.com/promos/britneyspears/

[-- Attachment #2: timer.pat --]
[-- Type: application/octet-stream, Size: 2437 bytes --]

Index: packages/compat/posix/current/src/time.cxx
===================================================================
RCS file: /cvs/ecos/ecos/packages/compat/posix/current/src/time.cxx,v
retrieving revision 1.9
diff -u -r1.9 time.cxx
--- packages/compat/posix/current/src/time.cxx	31 Jan 2003 11:53:14 -0000	1.9
+++ packages/compat/posix/current/src/time.cxx	29 Oct 2003 16:59:43 -0000
@@ -105,6 +105,7 @@
     cyg_bool            pending;        // is expiry pending?
     int                 overrun;        // Overrun count
     struct sigevent     sigev;          // Sigevent to raise on expiry
+    pthread_info        *caller;        // Thread object that set the timer
     
     // Space for alarm object
     cyg_uint8           alarm_obj[sizeof(Cyg_Alarm)];
@@ -273,7 +274,23 @@
             sigemptyset( &mask );
             sigaddset( &mask, timer->sigev.sigev_signo );
             cyg_posix_signal_sigwait();
-            cyg_posix_pthread_release_thread( &mask );
+
+            // Wake up a thread to handle the signal.  Give preference
+            // to the thread that initially set the timer.
+            if ((timer->caller != NULL) &&
+                (timer->caller->state <= PTHREAD_STATE_RUNNING) &&
+                ((mask & ~timer->caller->sigmask) != 0))
+            {
+                // The original caller can service at least one of
+                // the pending signals.  Interrupt its current wait
+                // and make its ASR pending.
+                timer->caller->thread->set_asr_pending();
+                timer->caller->thread->release();
+
+            } else {
+                // Find another thread that can handle the signal(s).
+                cyg_posix_pthread_release_thread( &mask );
+            }
         }
         else if( timer->sigev.sigev_notify == SIGEV_THREAD )
         {
@@ -439,6 +456,7 @@
 
     timer->armed        = false;
     timer->overrun      = 0;
+    timer->caller       = NULL;
 
     *timer_id = timer->id;
     
@@ -535,6 +553,9 @@
             // If the ABSTIME flag is not set, add the current time
             if( (flags & TIMER_ABSTIME) == 0 )
                 trigger += Cyg_Clock::real_time_clock->current_value();
+
+            // Record the preferred thread context for signal delivery
+            timer->caller = pthread_self_info();
 
             // Set the alarm running.
             timer->alarm->initialize( trigger, interval );

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

-- 
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss

  reply	other threads:[~2003-10-29 17:04 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-10-28 21:09 Dan Jakubiec
2003-10-29 15:33 ` Nick Garnett
2003-10-29 17:04   ` Dan Jakubiec [this message]
2003-10-30 15:32     ` Nick Garnett
2003-10-30 17:00   ` Dan Jakubiec
2003-10-31 18:09     ` Nick Garnett
2003-11-02 23:19       ` Dan Jakubiec
2003-11-03 13:15         ` mbs
2003-11-03 17:57           ` Dan Jakubiec
2003-11-03 18:36             ` mbs
2003-11-03 18:14           ` Dan Jakubiec

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20031029170409.44811.qmail@web21204.mail.yahoo.com \
    --to=djakubiec@yahoo.com \
    --cc=ecos-discuss@sources.redhat.com \
    --cc=nickg@ecoscentric.com \
    /path/to/YOUR_REPLY

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

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).