• Advertisement
Sign in to follow this  

Mutex creation in multithreaded library

This topic is 1695 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello,

 

I think I have a kind of chicken-egg problem:

 

I have a library (dll) that is pure C and that is supposed to be thread-safe.

How do I initialize it? I mean, at some point I need to call

 

globalMutex=CreateMutex(0,FALSE,0);
do some other initializations here

The above section of code should be run only the very first time someone calls a function in the library. But what if several threads call the library at the same time? Best would be to have a mutex to make sure the initialization happens only once, but mutexes need to be initialized...

Any idea?

Share this post


Link to post
Share on other sites
Advertisement

Thanks for all the replies.

The library can actually be compiled for many different platforms (also microcontrollers), and is allready in use. For that reason I cannot use an additional function that initializes everything.

I was just wondering if there is an extremely lightweight lock one can build, that is not OS dependent?

Or at least a random/timed mechanism that will reduce the chance for 2 threads entering the initialization section?

Share this post


Link to post
Share on other sites

I was just wondering if there is an extremely lightweight lock one can build, that is not OS dependent?

Boost has a pretty good collection of synchronization tools, although it may not be supported on your microcontrollers.

Share this post


Link to post
Share on other sites
You can build an atomic one-time lock on any CPU that supports atomic compare and swap:
 
 
// Some global
int counter = 0;
 
if (CompareAndSwap(counter, 1) == 0) {
   // Do initialization
}
 
// Carry on
[edit] For completeness: you also need a spinlock that waits until initialization is completed:
// Another global
int initdone = 0;

if (CompareAndSwap(counter, 1)) {
// init
// atomic set initdone to 1
}

while (AtomicCompare(initdone, 0)) {
// No-op
}

// Carry on
Edited by ApochPiQ

Share this post


Link to post
Share on other sites

I also found a platform-independent way of doing it: the Peterson's algorithm

Don't try and implement that unless you're aware of the memory/cache/atomicity/reordering behaviours of your target CPU and compiler.

If you implement that code as-is on any modern CPU, it simply will not work correctly as a critical section... You'd have to insert memory fences, etc, in order to make it function correctly.

e.g. your compiler or CPU might change the order in which the writes to flag[n] and turn actually occur, or the setting of flag[n] to false at the end might actually be committed to RAM before the changes performed inside the critical section are committed!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement