OK, I think I have this noodle soup figure out. I put a new version of the gamma patch on SourceForge. Below is the definitions which is the best way to get the logic across. What this boils down to is the following:
Any workable combination of library gamma will do except signgam is never used to reconstruct the gamma function because it is not thread safe. The patch will use gamma() in some cases but will do a run-time check to make sure it is the right type. (The autoconf literature suggests doing that over AC_RUN_ELSEIF().) If the thread safe lgamma_r() is present that is used. Etc.
This patch should work in Chris' case. The tgamma() takes top priority. But even if Chris didn't have tgamma(), gamma() would be used, but the run-time check would indicate that gamma() is actually log gamma and then from there on gnuplot's internal gamma function would be used. lgamma() wouldn't be used for reconstructing gamma.
Dan
/*
Order of preference and why:
tgamma() - It's the true gamma, perfect.
gamma() - If there is a gamma() in the library and no tgamma() there
is a slim chance (now... who knows in the future?) that it
is the true gamma. At run time we will check if it is true
gamma or log gamma. If it is log gamma, it won't be used
because signgam is not thread safe.
lgamma_r() - This is thread safe and will work. Tempted to put this
at higher priority than gamma() but OK here for now.
lngamma() - Gnuplot's version of log gamma as last resort. sgngam is
local to this code so is thread safe.
DO NOT USE:
#elif defined(HAVE_LGAMMA)
# define GAMMA(x) (gp_exp(lgamma(x))*signgam)
because not thread safe.
*/
#ifdef HAVE_TGAMMA
# define GAMMA(x) tgamma(x)
#elif defined(HAVE_GAMMA)
# define GAMMA(x) gp_gamma(x)
#elif defined(HAVE_LGAMMA_R)
static int gamma_sign;
# define GAMMA(x) (gp_exp(lgamma_r(x,&gamma_sign))*gamma_sign) /* Order of multiply important. */
#else
# define GAMMA(x) (gp_exp(lngamma(x))*sgngam) /* Order of multiply important. */
#endif
/*
Order of preference and why:
lgamma() - It's log gamma and we don't need signgam, perfect.
lgamma_r() - This will do if ever lgamma() is deprecated some day because of
its non-thread-friendly, this will do.
gamma() - There is a good chance this could be log gamma, but we use gp_lgamma()
which has a run-time check to make sure. If gamma() is not log gamma
then gp_lgamma() falls back on lngamma().
lngamma() - Gnuplot's version of log gamma as last resort.
*/
#ifdef HAVE_LGAMMA
# define LNGAMMA(x) lgamma(x)
#elif defined(HAVE_LGAMMA_R)
static int bad_sign; /* Born under... */
# define LNGAMMA(x) lgamma_r(x,&bad_sign)
#elif defined(HAVE_GAMMA)
# define LNGAMMA(x) gp_lgamma(x)
#else
# define LNGAMMA(x) lngamma(x)
#endif
|