Threadsafe?

Hi,
I'm unclear on how to use tthmath in a multithreaded environment. I had look at the source, but I don't want to get it wrong.

In particular, is there a subset of the library that is threadsafe without TTMATH_MULTITHREADS?

Thanks

Added by: tomek, 2011 VI 27, Last modified: 2011 VI 27

Multithread program can be written in this way:

#define TTMATH_MULTITHREADS
#include <ttmath/ttmath.h>
#include <iostream>

TTMATH_MULTITHREADS_HELPER

typedef ttmath::Big<1, 3> Float;

int main()
{
Float a = "234.234", b = "765.345";
std::cout << a*b << std::endl;
}

You should declare TTMATH_MULTITHREADS before including ttmath.h, or better use a compiler option to define it.
And macro TTMATH_MULTITHREADS_HELPER should be used somewhere in your *.cpp file. Under MSWindows the macro is empty, but under posix like systems this macro expands to:

#define TTMATH_MULTITHREADS_HELPER \
namespace ttmath \
{ \
pthread_mutex_t ttmath_mutex = PTHREAD_MUTEX_INITIALIZER; \
}

At the moment synchronizing is only needed in Big::ToString() method. There is a static table there:
static Big<exp,man> log_history[15];
which should be properly initialized. As this is not a POD C++ type then initializing is made at runtime.

But if your floating point values are always printed with the base (radix) 10, and your mantissa is less than or equal to TTMATH_BUILTIN_VARIABLES_SIZE then the logarithm is not calculated but taken from a table (Big::SetLn10() method)
and you don't have to be aware about threads at all.

But I am not sure whether in the future there will be other dependences so it is better for portability to use such macros.

Added by: muir, 2011 VI 27

Thanks, thats very helpful. I don't need ToString while I'm running multiple threads so its ok. I want to avoid using thread synchronisation as it might slow down execution.

Would it be possible to design it to not have thread synchronisation? Or at least to have that option. Either setup before starting threads or per thread setup perhaps?

Added by: tomek, 2011 VI 29

If you don't need Big::ToString() then there are not any synchronisation. Synchronisation is only in Big::ToString() and only once (at first call to ToString). There is double-checked locking pattern there so next calls to ToString are fast as possible.

Check Big::ToString_LogBase() method.

Added by: ~guest, 2011 VI 29

Ok, that sounds good.

I'd like to add that I've been using ttmath for 2 years now, and its been great. Its fast, easy to use, and I've had no problems at all. I'm creating Windows 32 and 64-bit exe files.

Thanks,

Added by: muir, 2021 I 29

I found a problem when defining TTMATH_MULTITHREADS in Windows.

It includes Windows.h in ttmaththreads.h, seriously polluting the namespace of files ttmath is included into, and it impossible to compile my code.

Windows.h is used to implement the class ThreadLock, so I replaced it with

#include <mutex>

and

class ThreadLock
{
std::mutex _mutex;
bool _locked = false;

public:

ThreadLock() = default;

~ThreadLock()
{
if (_locked)
{
_mutex.unlock();
}
}

bool Lock()
{
_mutex.lock();
_locked = true;
return _locked;
}
};

I'm not able to properly test this, but it appears to work.

Added by: tomek, 2021 I 29

I have to think about what to do with it. May static initialization from C++11 will be sufficient.