Timer, sigprocmask, etc. as memory mapped regions for performance

Stephen D. Williams (sdw@lig.net)
Mon, 2 Feb 1998 21:36:33 -0500 (EST)


I've been meaning to bring this up:

There are a number of frequently needed and used services that could
be provided for (optionally) as memory mapped regions in a process.

I write very high-speed high-transaction servers. In profiling
servers, especially asynchronous servers that use signals (SIGIO,
which async Sybase uses and is actually pretty slick since you can
have better latency than a select() loop process if you have other
work to be done), it becomes obvious that certain often used and
generally no-work system calls should be optimized.

gettimeofday, sigprocmask, and others fall into this category.

gettimeofday for instance could be a page mapped into every process
that just shares a kernel page with the current timer value.
Completely free instant timers. Maybe mmaping /proc/rtc is a clean
way to do this.

sigprocmask is more difficult, but no less doable. This one actually
I found a way to do completely in the libc library, but haven't had
time to actually implement. I'll describe it here since I want it
done so badly:

The point is to allow the use of signals as a mechanism for a simple
type of multi-threading. (Yes, real threads handle the following with
mutexes, etc, but I needed to have a select loop process also have
signal driven response to outside IO.)

The idea is that you have functions for critical/uncritical marking.
My wrappers keep a depth counter and only block/unblock signals based
on transition from 0/1. Further optimization can be done when you
realize that assuming no collisions, the mask/unmask is really just
changing a long/bitfield.

First you 'wrap' all the signal functions so that a libc signal
handler was the Real signal handler for all signals and that signal
handlers that the application registered were noted in vectors. Calls
to sigprocmask (and family) just modify flags in the library. When a
signal is triggered, the library function looks at the mask, calls the
real handler if unmasked, or calls the Real sigprocmask to block the
signal and records the pending signal. When the application unmasks
the signal, the library calls the real handler and upon return makes
the system call to Really unmask the signal.

This allows you to block/unblock the signal thousands of times a
second with only the cost of a byte/int read/write and no system calls
unless there is a collision.

My first pass at this involved kernel assistance, but I needed to find
a way to do this on any Unix.

In addition, I have many uses for Posix.4, not the least of which is
portable but competitive database servers.

sdw

>From: Perry Harrington <pedward@sun4.apsoft.com>
>Date: Mon, 2 Feb 1998 10:26:27 -0800 (PST)
>Subject: Re: 2 Questions about Linux
>
>> do_gettimeofday within the kernel, gettimeofday outside...
>> resolution should be a few microseconds.
>
>Thanks,
>But what is the overhead of doing this? I'd like not to impact the
>flow of data
>as much as possible (TCP driver). How much CPU can I expect that call
>to
>chew up?
>
>> Tom
>- --Perry
>- --
>Perry Harrington Linux rules all OSes. APSoft ()
>email: perry@apsoft.com Think Blue. /\