Boost shared_mutex is there a total mutex's sharing method I can call?

Started by
16 comments, last by EnlightenedOne 13 years, 6 months ago
I have a problem with using multiple threads and using a barrier, due to debugging and the complexity of states between my many threads I cannot use interrupts and an actual barrier variable.

You can skip to the end line for a rundown of what I need or read the fine print here.

I need an atmoc way to see the number of threads that are waiting inside a shared mutex.

These are the variables I use.

boost::condition_variable_any multiThreadLinkReady;
boost::shared_mutex smutDependancyThreadCustomBarrierReady;
bool boolIsSceneReady;

This is the code I run to wait until they are all ready, I cannot lock with the wait value set, so I need to atomically check this in the other function to garuntee every thread gets awoken when every thread is gathered.

 	void waitUntilAllReady()	{		mutAccessData.lock();		if (boolIsSceneReady == false)		{			intThreadsCaughtCountPost++;			mutAccessData.unlock();			//The thread is set to frozen to be awoken on the next line when the class is ready.			multiThreadLinkReady.wait(smutDependancyThreadCustomBarrierReady);			//So we can reuse this on the next level loaded we need to decrement the counter.			mutAccessData.lock();			intThreadsCaughtCountPost--;			mutAccessData.unlock();		}		else		{			//Not impossible to reach here but very unlikely depends on lots of thread lag.			mutAccessData.unlock();		}	}


Then there is this threaded function which only one thread uses to manage the other threads, I need another if to check that the smutDependancyThreadCustomBarrierReady has the TOTALTHREADSLOADINGSCENE attached to it before allowing notify to be called or my threads never wake up!

	void wakeUpIfAllReady()	{		mutAccessData.lock();		if (intThreadsCaughtCountPost >= TOTALTHREADSLOADINGSCENE)		{			multiThreadLinkReady.notify_all();			boolIsSceneReady = true;		}				mutAccessData.unlock();	}


Does anyone know of a method in boost to perform the function in the title?
Advertisement
I need to access the value total_count in the boost::condition_variable_any why is there not a method for this?
I don't use boost threading so I might be a bit off, but -- When you call wait, it calls unlock on smutDependancyThreadCustomBarrierReady, right? It sounds like you should lock smutDependancyThreadCustomBarrierReady first with a shared_lock and then pass this lock to the wait function?

Also, when you call wait it's actually allowed to resume before notify is called, so, before proceeding with "intThreadsCaughtCountPost--", you should check that boolIsSceneReady is true, and if not, wait again.
See my reply in your other thread on this. I don't think this is a mutex problem, but a semaphore problem. I also offered some other ideas, but need a better understanding of what you're doing to better help.

Cheers,

Bob

[size="3"]Halfway down the trail to Hell...
Hodgman - When you call wait my understanding is that it is added to the condition variables, so when I perform.

multiThreadLinkReady.wait(smutDependancyThreadCustomBarrierReady);

"Also, when you call wait it's actually allowed to resume before notify is called" - The thread is added to those with a shared lock on mutex multiThreadLinkReady. How can a thread resume before it is notified to be awoken?!? if its possible (and I have never seen it) that would change the game alot.

The issue is that the notify function can notify when the boolean is changed before the other thread actually goes into the wait mechanism and is added to the list of threads waiting on the semaphore. I cant obviously change the values in the midst of going into wait with a timed lock because on wait any timed processes the thread had going are also set to wait.

Scourage - I will head to the other thread now.
I tried to modify the boost library but to no avail.

My code.
	void wakeUpIfAllReady()	{		mutAccessData.lock();		if (intThreadsCaughtCountPost >= TOTALTHREADSLOADINGSCENE)		{			if (multiThreadLinkReady.get_total_count() == TOTALTHREADSLOADINGSCENE)			{				multiThreadLinkReady.notify_all();				boolIsSceneReady = true;			}		}				mutAccessData.unlock();	}


Boost file "condition_variable.hpp"

			long get_total_count()			{				long lngTemp = 0;                if(detail::interlocked_read_acquire(&total_count))                {					boost::lock_guard<boost::mutex> internal_lock(internal_mutex);					if (!total_count)					{						return -1;					}					else					{						lngTemp = total_count;					}				}				return lngTemp;			}


I was feeling good about my patch until I had this issue.

modified boost error

Is there a prototype I need to change to hack together this correction?
The code was good I just had to add in a missing

using detail::basic_condition_variable::get_total_count;

So that the any condition variable used it aswell as just the basic.

I hope this is an ethical modification of the library :)
IT WORKED!!!!! :D

I was terrified modifying the boost code but that was so worth it!

I have posted to the boost library a ticket mentioning this concept.
I am going to need to rewrite that class to get rid of the unnecessary integers counting up and down the total gathered threads when I am using part of conditional variable to do that test anyway!

Thanks for your suggestions everyone!

[Edited by - EnlightenedOne on October 10, 2010 5:54:37 PM]
Quote:Original post by EnlightenedOne
"Also, when you call wait it's actually allowed to resume before notify is called" - The thread is added to those with a shared lock on mutex multiThreadLinkReady. How can a thread resume before it is notified to be awoken?!? if its possible (and I have never seen it) that would change the game alot.
From the boost docs on condition_variable_any
Quote:template<typename lock_type> void wait(lock_type& lock)

Effects:
Atomically call lock.unlock() and blocks the current thread. The thread will unblock when notified by a call to this->notify_one() or this->notify_all(), or spuriously. When the thread is unblocked (for whatever reason), the lock is reacquired by invoking lock.lock() before the call to wait returns. The lock is also reacquired by invoking lock.lock() if the function exits with an exception.
Postcondition:
lock is locked by the current thread.
The "or spuriously" part means it can do it whenever it wants to.

This topic is closed to new replies.

Advertisement