Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 16 Jan 2000 01:31:31 -0500
From:      "Mikhail Evstiounin" <evstiounin@adelphia.net>
To:        <freebsd-questions@FreeBSD.ORG>
Subject:   Re: Volatile variables
Message-ID:  <010b01bf5feb$54230e00$f8353018@evstiouninadelphia.net.pit.adelphia.net>

next in thread | raw e-mail | index | archive | help
After I reread the whole discussion, I decided to share my expirience in
sighandler writing.
Sorry, If I am annoying sombody.

Sighandler is always an async process, but it's not an async in the same way
as other thread or process. Why? Sighandler gets control in an async way,
but your main process never gets it back until a sighadler returns it. So,
from the point of view of a sighandler, everything happens asynchronously -
process gets interrupted and a sighandler gets control. From the point of
view of a process, this is an async interruption, but with some attributes
of co-processing - it's not going to get control back until a handler
returns it back (I don't discuss longjmp now, but it's control returning).
And you should take that into consideration. Why? Because it's not enough to
use standard synchronization methods to synchronize handler and and your
program, you should take some extra steps. If you write just something like
this (I will use pseudo code since implementation of semaphore are different
in different UNIXes):

int a = 0;
...
    sema s = 1;

    s--;


    a = k + 3;

    s++;
...

void Sighandler( int sig )
{
    s--;
    // use a;
    s++;
}

and program gets interrupted between first pair of s--;...s++;, sighandler
will hang forever on the first s--; - remember, that process will never get
control back until Sighandler finishes and, as a result; will never increase
semaphore - deadlock. The same is true about critical intervals, monitors,
etxc. Where is an exit? Well, the first one is write a sighandler in such
way, that it will create a request and put it to the queue through async
save call and the other thread will take request out of the queue and take
care of them. You can see this approach implemented in operating systems,
drivers, etc. A little bit complex, but works.

Another way to do it is - to use sigblock/sigsetmask to mask all signals
that could interfere with access to a global resource.

int a = 0;
...

    sigblock( sigmask( SIGUSR1 ) );
    sigblock( sigmask( SIGUSR2 ) );


    a = k + 3;

    sigsetmask( 0 ); // too harsh to reenable all signals - just for
simplicity.
...

void SighandlerSigusr1( int sig )
{
    sigblock( sigmask( SIGUSR2 ) );
    // use a;
    sigsetmask( 0 ); // too harsh to reenable all signals - just for
simplicity.
}


A very good example of using sigblock/sigsetmask is in "UNIX network
programming" by W. Richard Stevens, pp. 326-327 (one of many). And this is
an example of Asynchronous IO, basicaly, excatly what initiator of this
thread was asking for.

In the first case, you do not need vilotile. In the second case it's better
to use it - I agree here, not competely, but agree - but it's not enough
just to use vilotile. In my expirience, none of compiler did a fancy
optimizations on a global variable if this variable could be accessed from
another units. Especially, this is true in C++ world with try/catch blocks.
But even in C world,
if compiler sees a statement like this

int a;

void mmm( void )
{
    a = 3;
...
    a = ....
    k = foo( ); // this statement
...
}

It has zero knowledge about foo at this moment and should not make any fancy
optimization.

Again, this is just my expirience and I could be wrong. But with this
non-kernel multithread support (POSIX and other standards), when you can
easily share global data among many threads. A lot of about async safe
function you can find in "Threads Primer" by Bil Lewis and  Daniel J. Berg
and in "Practical UNIX Programming. A guide to comcurrency, Communication,
and Multithreading" by Kay A. Robbins and Steven Robbins. A lot of good in
books written by W. Richard Stevens (network orientation). I am sure that
everybody has his/her favorite book on concurrent programming and can
recomend it to others.




To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-questions" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?010b01bf5feb$54230e00$f8353018>