added thread-safety to static history buffers (factorial and logarithm) for MSVC
git-svn-id: svn://ttmath.org/publicrep/ttmath/branches/chk@135 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
37379d2f1f
commit
00e39d3608
|
@ -1951,6 +1951,8 @@ namespace ttmath
|
|||
}
|
||||
|
||||
ErrorCode err_tmp;
|
||||
|
||||
TTMATH_USE_THREADSAFE_OBJ(history);
|
||||
|
||||
if( history.Get(x, result, err_tmp) )
|
||||
{
|
||||
|
|
|
@ -2506,7 +2506,19 @@ public:
|
|||
{
|
||||
operator=(value);
|
||||
}
|
||||
|
||||
|
||||
class LogHistory
|
||||
{
|
||||
public:
|
||||
Big<exp,man> val[15];
|
||||
|
||||
LogHistory()
|
||||
{
|
||||
for (int i = 0; i < 15; ++i)
|
||||
val[i].SetZero();
|
||||
}
|
||||
TTMATH_IMPLEMENT_THREADSAFE_OBJ
|
||||
};
|
||||
|
||||
/*!
|
||||
a method for converting the value into a string with a base equal 'base'
|
||||
|
@ -2793,11 +2805,12 @@ private:
|
|||
// (LnSurrounding1() will return one immediately)
|
||||
uint c = Ln(x);
|
||||
|
||||
// warning! this 'static' is not thread safe
|
||||
static Big<exp,man> log_history[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
uint index = base - 2;
|
||||
|
||||
if( log_history[index].IsZero() )
|
||||
static LogHistory log_history;
|
||||
TTMATH_USE_THREADSAFE_OBJ(log_history);
|
||||
|
||||
if( log_history.val[index].IsZero() )
|
||||
{
|
||||
// we don't have 'base' in 'log_history' then we calculate it now
|
||||
|
||||
|
@ -2815,14 +2828,14 @@ private:
|
|||
|
||||
// the next time we'll get the 'Ln(base)' from the history,
|
||||
// this 'log_history' can have (16-2+1) items max
|
||||
log_history[index] = temp;
|
||||
log_history.val[index] = temp;
|
||||
|
||||
c += Div(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we've calculated the 'Ln(base)' beforehand and we're getting it now
|
||||
c += Div( log_history[index] );
|
||||
c += Div( log_history.val[index] );
|
||||
}
|
||||
|
||||
return (c==0)? 0 : 1;
|
||||
|
|
|
@ -57,7 +57,65 @@ namespace ttmath
|
|||
#define __TEXT(quote) quote
|
||||
#endif
|
||||
#define TTMATH_TEXT(quote) __TEXT(quote)
|
||||
#else
|
||||
|
||||
#if defined(_MT)
|
||||
class clsCrit
|
||||
{
|
||||
private:
|
||||
mutable CRITICAL_SECTION _Crit;
|
||||
|
||||
clsCrit(const clsCrit&) // inhibit copy (easy mistake to do; use clsCritObj instead!!!)
|
||||
{
|
||||
}
|
||||
clsCrit& operator=(const clsCrit& rhs); // inhibit assignment
|
||||
public:
|
||||
clsCrit(void)
|
||||
{
|
||||
::InitializeCriticalSection(&_Crit);
|
||||
}
|
||||
virtual ~clsCrit(void)
|
||||
{
|
||||
::DeleteCriticalSection(&_Crit);
|
||||
}
|
||||
|
||||
void Enter(void) const
|
||||
{
|
||||
::EnterCriticalSection(&_Crit);
|
||||
}
|
||||
void Leave(void) const
|
||||
{
|
||||
::LeaveCriticalSection(&_Crit);
|
||||
}
|
||||
};
|
||||
|
||||
class clsCritObj
|
||||
{
|
||||
private:
|
||||
const clsCrit& _Crit;
|
||||
|
||||
clsCritObj& operator=(const clsCritObj& rhs); // not applicable
|
||||
public:
|
||||
clsCritObj(const clsCrit& Sync)
|
||||
: _Crit(Sync)
|
||||
{
|
||||
_Crit.Enter();
|
||||
}
|
||||
~clsCritObj(void)
|
||||
{
|
||||
_Crit.Leave();
|
||||
}
|
||||
};
|
||||
#define TTMATH_IMPLEMENT_THREADSAFE_OBJ \
|
||||
private: \
|
||||
clsCrit CritSect; \
|
||||
public: \
|
||||
operator clsCrit&() \
|
||||
{ \
|
||||
return(CritSect); \
|
||||
}
|
||||
#define TTMATH_USE_THREADSAFE_OBJ(c) clsCritObj lock(c)
|
||||
#endif
|
||||
#else // not MS compiler
|
||||
typedef char tchar_t;
|
||||
typedef std::string tstr_t;
|
||||
typedef std::ostringstream tostrstrm_t;
|
||||
|
@ -65,6 +123,11 @@ namespace ttmath
|
|||
typedef std::istream tistrm_t;
|
||||
#endif
|
||||
|
||||
#if !defined(TTMATH_IMPLEMENT_THREADSAFE_OBJ)
|
||||
#define TTMATH_IMPLEMENT_THREADSAFE_OBJ /* */
|
||||
#define TTMATH_USE_THREADSAFE_OBJ(c) /* */
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // headerfilettmathmathttconfig
|
||||
|
|
|
@ -487,6 +487,7 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
TTMATH_IMPLEMENT_THREADSAFE_OBJ
|
||||
}; // end of class History
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue