Brief Description
This change is applicable to Classic architecture only. Engine Performance improvement - reduce setting of FPE handler.
Purpose
During GBAK performance testing, it was discovered that approximately 5% of time was spent setting/resetting the InterBase Floating Point Exception handler. By changing when the FPE is reset we free up virtually all this time, with minimal customer impact.
Customers are only impacted if they use the Shared or backend libraries, Have their own FPE handler, and reset their FPE handler while being attached to a database.
Feature Description
Functional Changes
Prior to this change, InterBase managed FPE handlers as follows:
On entry to each API call, we would fetch the current (client's) FPE handler
setting, and set the FPE signal to go to our handler. On exit from each API
call we would reset SIGFPE to the client's handler. The InterBase FPE handler
(isc_ipc.c:overflow_handler) simply ignored an FPE. The point of this
methodology was to use the InterBase FPE handler to ignore any FPE's that occur
while executing within the engine. FPE's that occur when outside the engine
would follow whatever protocol the client had setup. (And, if the customer had
no FPE handler, would result in a client core-drop).
In the new methodology, the following is used:
Each API call increments/decrements a counter to indicate when we're in the
engine. For each ATTACHMENT (database or service) we setup the isc FPE handler.
The isc handler checks the API counter to decide if the FPE occurred while
within engine code. If so, we ignore the FPE. Otherwise, we chain to the
client's FPE handler, if it exists.when there are no active ATTACHMENT's, we
remove the isc FPE handler.
Notes:
FPE's are rare, in general. Programs having FPE handlers are even rarer, in
general. It's unlikely that customer programs care about having FPE handlers
Support generally recommends customers doing signal handling of any form use
PIPE.
Issues
Migration
Applications using Remote or PIPE show no difference.
Applications never having an instance of an FPE show no difference.
Applications which never setup their own FPE handler differ as follows: An FPE
occurring in CLIENT code will no longer core drop but will silently have the
FPE ignored, if the FPE occurs after the first database attach.
Applications which setup their own FPE handlers differ as follows: If the FPE
handler is setup before the first attach, and never changed, no difference is
shown. If the FPE handler is setup or changed after the first attach, the
client's handler will be called instead of the ISC handler for FPE's that occur
within the engine. (Clients can evade this change by calling private API
isc_reset_fpe() to inform the engine when changes in client FPE handler have
been made)
It is possible for an FPE to be "delayed" until an engine operation
completes. This would be significant for applications that use SIGFPE for their
own purposes (e.g.: not to indicate a Floating Point Exception). This is
similar to how the engine postpones processing of SIGUSR1 and SIGUSR2 under
some instances. While the client's FPE handler will be invoked, it will be via
the isc generic signal handler routine (isc_ipc.c:signal_handler).
I can imagine difficulties if a client tries to load/unload isc libraries
dynamically. These would be resolved by the customer resetting the signal
handler when the isc libraries are unloaded.