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:
@@ -1951,6 +1951,8 @@ namespace ttmath
|
|||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode err_tmp;
|
ErrorCode err_tmp;
|
||||||
|
|
||||||
|
TTMATH_USE_THREADSAFE_OBJ(history);
|
||||||
|
|
||||||
if( history.Get(x, result, err_tmp) )
|
if( history.Get(x, result, err_tmp) )
|
||||||
{
|
{
|
||||||
|
@@ -2506,7 +2506,19 @@ public:
|
|||||||
{
|
{
|
||||||
operator=(value);
|
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'
|
a method for converting the value into a string with a base equal 'base'
|
||||||
@@ -2793,11 +2805,12 @@ private:
|
|||||||
// (LnSurrounding1() will return one immediately)
|
// (LnSurrounding1() will return one immediately)
|
||||||
uint c = Ln(x);
|
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;
|
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
|
// 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,
|
// the next time we'll get the 'Ln(base)' from the history,
|
||||||
// this 'log_history' can have (16-2+1) items max
|
// this 'log_history' can have (16-2+1) items max
|
||||||
log_history[index] = temp;
|
log_history.val[index] = temp;
|
||||||
|
|
||||||
c += Div(temp);
|
c += Div(temp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// we've calculated the 'Ln(base)' beforehand and we're getting it now
|
// 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;
|
return (c==0)? 0 : 1;
|
||||||
|
@@ -57,7 +57,65 @@ namespace ttmath
|
|||||||
#define __TEXT(quote) quote
|
#define __TEXT(quote) quote
|
||||||
#endif
|
#endif
|
||||||
#define TTMATH_TEXT(quote) __TEXT(quote)
|
#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 char tchar_t;
|
||||||
typedef std::string tstr_t;
|
typedef std::string tstr_t;
|
||||||
typedef std::ostringstream tostrstrm_t;
|
typedef std::ostringstream tostrstrm_t;
|
||||||
@@ -65,6 +123,11 @@ namespace ttmath
|
|||||||
typedef std::istream tistrm_t;
|
typedef std::istream tistrm_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(TTMATH_IMPLEMENT_THREADSAFE_OBJ)
|
||||||
|
#define TTMATH_IMPLEMENT_THREADSAFE_OBJ /* */
|
||||||
|
#define TTMATH_USE_THREADSAFE_OBJ(c) /* */
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#endif // headerfilettmathmathttconfig
|
#endif // headerfilettmathmathttconfig
|
||||||
|
@@ -487,6 +487,7 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TTMATH_IMPLEMENT_THREADSAFE_OBJ
|
||||||
}; // end of class History
|
}; // end of class History
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user