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:
Christian Kaiser 2009-05-07 11:37:10 +00:00
parent 37379d2f1f
commit 00e39d3608
4 changed files with 86 additions and 7 deletions

View File

@ -1951,6 +1951,8 @@ namespace ttmath
}
ErrorCode err_tmp;
TTMATH_USE_THREADSAFE_OBJ(history);
if( history.Get(x, result, err_tmp) )
{

View File

@ -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;

View File

@ -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

View File

@ -487,6 +487,7 @@ public:
return false;
}
TTMATH_IMPLEMENT_THREADSAFE_OBJ
}; // end of class History