Synchronization requirements for DbgHelp functions - c++

I recently implemented a utility to write user-mode dumps using MiniDumpWriteDump (part of the Debug Help Library). The implementation is separated into its own process. A target process can launch this utility and communicate with it to trigger writing a minidump.
This is all working as expected. I am not sure, though, how to interpret the rules with respect to concurrency for MiniDumpWriteDump:
All DbgHelp functions, such as this one, are single threaded. Therefore, calls from more than one thread to this function will likely result in unexpected behavior or memory corruption. To avoid this, you must synchronize all concurrent calls from more than one thread to this function.
Does the above refer to calls from different threads to a single process? Or do concurrent calls also require synchronization, if MiniDumpWriteDump is called in different processes (e.g. when each target process launches its own utility process)?

The problem is in the library: "All DbgHelp functions, such as this one, are single threaded".
Therefore, any process invoking this library will have to make sure that only one single thread is using the DbgHelp functions simultaneously.
Just use a lock before you use DbgHelp, that is, if your program using DbgHelp is multi-threaded (otherwise there's no problem).
Another way to remove this limitation is to add a (per-thread) context to the DbgHelp library: you move all (file-scope) static and (program-scope) global variables in a C structure passed as an argument to all library function calls.

Related

How do I associate two Tcl_Interp?

I have a code that looks like this:
myCmd::myCmd(std::string outFile) : _tclInterp(Tcl_CreateInterp()), _outFile(outFile)
{
_myParser = CC::CmdParser(_tclInterp, registerAllCommands);
}
The thread which created the Tcl_CreateInterp() might be different from what is being used in the CC::CmdParser. Internally CC::CmdParser also calls Tcl_DeleteInterp() once all the procedures are complete. It will be a problem if the thread id is different during calls to CreateInterp and DeleteInterp.
How do I associate or tell such that same thread does Tcl_CreateInterp() (in the constructor) and Tcl_DeleteInterp() (in the CmdParser).
NOTE that the CC::CmdParser is a third-party API and I don't have source code.
Tcl interpreter objects internally use thread-specific data extensively in order to avoid most global locks. This goes as far as including thread-specific memory management pools, at least for common allocations, and Tcl code is executed as part of initialising the interpreter state, so it's really not possible to use an interpreter in a different thread from the one in which it was created. The Tcl library checks that you're using it correctly in a few places, at least in some build modes, and will make the process abort() (or Windows's equivalent) if you disobey the rules; that's much friendlier than the crash that would otherwise be coming due to fundamental assumptions not being respected…
This means that you must create, use, and destroy the interpreter on the same thread.
You might be advised to initialise the Tcl interpreter lazily if you can't guarantee that the containing object is used in the same thread that it was created in. You might think that this results in handling of things that isn't really the C++ way, but the thread-bound nature of interpreters means that you've really not got any alternative. (You might want to look at Tcl_CreateExitHandler() for help with cleaning up the interpreter when the thread goes away, but that will only help if Tcl_FinalizeThread() or Tcl_ExitThread() are called; if you're being thread-promiscuous on the C++ side then there's a good chance that you'll be baking in all sorts of problems anyway.)
If the C++ part insists on using multiple threads, you'll have to have a single thread for the Tcl code and use inter-thread messaging to let the other threads tell it things. That's done with Tcl_ThreadQueueEvent(). The canonical way to use that is the thread package, and that includes the canonical example of how to do so (github.com/tcltk/thread/generic/threadCmd.c); most of the complexity in there relates to turning an essentially one-way (but “reliable”) operation into a two-way one that lets you do a procedure call into a different thread; one-way calls are far simpler.

How does C++ allow to wait without excessive CPU usage

For example I have code
while (!something} {
//waiting
}
it does wait for something, but it uses a lot of CPU. C++ have things like thread join, condition variable wait, mutex lock - which allow to wait, so it does check some condition, but it behaves like idle process - not consuming CPU time. How it is done and is there way to make while loop (or any other code) behave like this?
These are features necessarily backed by the operating system.
The OS is responsible for allocating time to your processes and threads, and you require these features to control (or, rather, make requests of) that mechanism.
Your C++ standard library implementation calls platform-specific functions provided by your operating system.
There is no way to replicate that yourself without using the kind of C++ types/functions you've already listed: mutexes & timers (or without calling those OS functions yourself, like we did in the olden days!). All you can do is a spin lock, like the one you already demonstrated.
You can achieve this by calling system calls that block the execution of the thread.
You don't usually call the system directly, but use a wrapper function instead, which is an abstraction over system specific details. This approach allows your program to be portable to different systems.
In fact, this is exactly what the standard functions such as std::condition_variable::wait are: an abstraction over system interface, which in this case blocks the thread. std::cin::operator>> is another example of function call that blocks the execution of the thread.

Is there a way to tell how many on-going threads in the master process from a DLL?

The scenario is here:
If a program is executed, at runtime assume it will link to some DLL files, the (master) program/process may or may not create multi-threading function-calls to the functions in DLLs.
Then is there a way that the DLL, of cause besides parameter-passing, can tell whether the master process, who calls the functions within the DLL at runtime, is in a single or multi-thread manner (For instance, by Open MP)?
You can check and compare the current thread ID to detect calls from different threads. You could also implement a DLLMain() function that gets called for every started and terminated thread. I'm pretty sure you can also retrieve a handle to the current process and enumerate the threads running in it. Only the first version will actually tell you if your code is run from different threads though, I think that e.g. WinSock will create a thread for you, even though your program is single-threaded otherwise.
BTW: Consider adding win32api tag and removing C++ tag.

Question about Windows API and C/C++ run-time library function

When I write C/C++ code for Windows platform, I usually use Windows APIs as necessary. But when it comes to multi-threading, I read the following quotaion from < Windows via C/C++ >
The CreateThread function is the
Windows function that creates a thread.
However, if you are writing C/C++
code, you should never call
CreateThread. Instead, you should use
the Microsoft C++ run-time library
function _beginthreadex. If you do not
use Microsoft's C++ compiler, your
compiler vendor will have its own
alternative to CrateThread. Whatever
this alternative is, you must use it.
AFAIK, a language run-time library for a certain platform is implemented with that platform's APIs. I think it is totally possible to call CreateThread() from my C/C++ code. And I quite did that. But I just don't understand why the above rule should be followed.
Many thanks for your insights.
Of course it's possible to use the Windows API's CreateThread directly.
But that leaves the runtime library uninformed about the new thread.
For the multi-threading support in the runtime library (and that includes functions that rely on static storage, e.g. I imagine it includes strtok) you need to keep the runtime library informed, and not only informed, but partially in charge so that e.g. failure to allocate whatever resources it needs for a thread, results in thread creation failure.
Cheers & hth.,
The c-runtime has numerous stateful variables that hold things, such as the current locale. These values have to be settable per thread otherwise code in oen thread (e.g. calling setlocale) could unduly influence code running in a different thread.
_beginthread wraps your thread in code that performs the necessary allocation AND deallocation of these per thread data structures.
If you call CreateThread directly, the structures will probably be allocated as required, but without the wrapper, the runtime will never know when the thread exits and they will leak.

Thread safety of Matlab engine API

I have discovered through trial and error that the MATLAB engine function is not completely thread safe.
Does anyone know the rules?
Discovered through trial and error:
On Windows, the connection to MATLAB is via COM, so the COM Apartment threading rules apply. All calls must occur in the same thread, but multiple connections can occur in multiple threads as long as each connection is isolated.
From the answers below, it seems that this is not the case on UNIX, where calls can be made from multiple threads as long as the calls are made serially.
From the documentation,
MATLAB libraries are not thread-safe.
If you create multithreaded
applications, make sure only one
thread accesses the engine
application.
When I first started using the engine, I didn't run across any documentation on thread safety, so I assumed that it was not thread-safe.
I use a C++ class to synchronize access to an engine instance. For more parallel processing designs, I instantiate multiple instances of the engine class.
(edit) I'm using MATLAB R14 on Solaris. I open the engine using the 'engOpen' call, and close it using 'engClose'. My platform does not crash when the Close is called by a different thread than the one that called Open.
From a user's perspective, Matlab's interpreter is purely single-threaded. To be safe, you probably need to make all access to the engine from a single thread.
Note that internally, Matlab uses plenty of threads. There are GUI threads, and in the last few versions, the interpreter can use multiple threads behind the scenes. But, the interpreter is semantically equivalent to a single-threaded interpreter (with interrupts).
You can use engOpenSingleUse instead of using engOpen to make more than one thread working separately. (Only Windows)