By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,305 Members | 1,588 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,305 IT Pros & Developers. It's quick & easy.

can a volatile int be used as a mutex

P: n/a
Hi,

We have a lot of OS's to support. So we created a mutex class with sieze and release like so
class foo{

private:
volatile int m_lock;
public:
Sieze(){ while (m_lock==1) { sleep(1);};m_lock=1;};
Release(){m_lock=0;};
.... // constructors etc

}
Is this legal or do I have to use an OS type call? I thought that volatile guaranteed m_lock to be thread safe, meaning the variable m_lock could not be cashed in a register if the thread was swapped out for another thread.
thanks in advance

tif
Mar 9 '07 #1
Share this Question
Share on Google+
7 Replies


P: n/a

tiffini wrote:
Hi,

We have a lot of OS's to support. So we created a mutex class with sieze and release like so
class foo{

private:
volatile int m_lock;
public:
Sieze(){ while (m_lock==1) { sleep(1);};m_lock=1;};
Release(){m_lock=0;};
... // constructors etc

}
Is this legal or do I have to use an OS type call? I thought that volatile guaranteed m_lock to be thread safe, meaning the variable m_lock could not be cashed in a register if the thread was swapped out for another thread.
thanks in advance

tif
Hiya,

I think this is OT here - maybe post to comp.programming.threads?

I'll try to answer anyway. I don't think this is correct, even on a
single processor.
Sieze(){ while (m_lock==1) { sleep(1);};m_lock=1;};
Imagine thread A checks m_lock, sees it is not 1 and decides to
continue, but then gets rescheduled (say its timeslice expired) before
it writes to m_lock.
A second thread then comes along and sees the same thing, because
thread A didn't get a chance to write to m_lock yet.
Result - two threads running in your code guarded by the mutex.

I think that if you want to build a lock then at some point you need
to use an arch-specific instruction. I could be wrong, though. The
guys in comp.programming.threads would know, and probably try to sell
you lock-free!

Doug

Mar 9 '07 #2

P: n/a
tiffini wrote:
Hi,

We have a lot of OS's to support. So we created a mutex class with
sieze and release like so
class foo{

private:
volatile int m_lock;
public:
Sieze(){ while (m_lock==1) { sleep(1);};m_lock=1;};
Release(){m_lock=0;};
... // constructors etc

}
Is this legal or do I have to use an OS type call? I thought that
volatile guaranteed m_lock to be thread safe, meaning the variable
m_lock could not be cashed in a register if the thread was swapped out
for another thread.
thanks in advance

tif
Your test-and-set is not atomic and will fail miserably in
multi-threaded application.

Fei
Mar 9 '07 #3

P: n/a
On 9 Mar., 18:26, tiffini <tiff...@val13xr8.orgwrote:
Hi,

We have a lot of OS's to support. So we created a mutex class with sieze and release like so

class foo{

private:
volatile int m_lock;
public:
Sieze(){ while (m_lock==1) { sleep(1);};m_lock=1;};
Release(){m_lock=0;};
... // constructors etc

}

Is this legal or do I have to use an OS type call? I thought that volatile guaranteed m_lock to be thread safe, meaning the variable m_lock could not be cashed in a register if the thread was swapped out for another thread.
It is legal C++ but it will not do what you expect. As Doug noted,
your code will fail even when run on a single processor.
I will recommend that you use the OS features on whatever system you
happen to compile for and encapsulate the code in a class as you did
above.

/Peter

Mar 9 '07 #4

P: n/a
Doug wrote:
tiffini wrote:
>Hi,

We have a lot of OS's to support. So we created a mutex class with sieze and release like so
class foo{

private:
volatile int m_lock;
public:
Sieze(){ while (m_lock==1) { sleep(1);};m_lock=1;};
Release(){m_lock=0;};
... // constructors etc

}
Is this legal or do I have to use an OS type call? I thought that volatile guaranteed m_lock to be thread safe, meaning the variable m_lock could not be cashed in a register if the thread was swapped out for another thread.
thanks in advance

tif

Hiya,

I think this is OT here - maybe post to comp.programming.threads?

I'll try to answer anyway. I don't think this is correct, even on a
single processor.
> Sieze(){ while (m_lock==1) { sleep(1);};m_lock=1;};

Imagine thread A checks m_lock, sees it is not 1 and decides to
continue, but then gets rescheduled (say its timeslice expired) before
it writes to m_lock.
A second thread then comes along and sees the same thing, because
thread A didn't get a chance to write to m_lock yet.
Result - two threads running in your code guarded by the mutex.
I thought that the volatile key word is a lock between threads and cannot be cached in a register.
So the while(lock==1} is the atomic check. when each thread is swapped out for the next the register that holds the volatile variable will be written to memory. Then the other thread will read it and variable.

If this is not correct, can you explain how volatile keyword works?
thanks in advance

tiff

>
I think that if you want to build a lock then at some point you need
to use an arch-specific instruction. I could be wrong, though. The
guys in comp.programming.threads would know, and probably try to sell
you lock-free!

Doug
Mar 10 '07 #5

P: n/a
tiffini wrote:
[snip]
I thought that the volatile key word is a lock between threads and cannot
be cached in a register.
So the while(lock==1} is the atomic check. when each thread is swapped
out for the next the register that holds the volatile variable will be
written to memory. Then the other thread will read it and variable.

If this is not correct,
It is not correct: volatile is unrelated to threading. The standard does not
say anything about threading. In particular, it does not define the meaning
of "volatile" with regard to threading.
can you explain how volatile keyword works?
If data is declared volatile, then reads and writes to such data qualify as
observable behavior [1.9/6]. Consequently, such writes and reads cannot be
moved around sequence points, i.e., sequence points define a partial order
on such reads and writes and you can use that to make sure that some
read/write occurs before another read/write. However, such guarantees only
apply to the abstract machine, which as of now is single threaded.

However, the single threaded abstract machine does allow for certain
interrupts: signals. With regard to those, the standard says that volatile
sig_atomic_t data have well-defined values when the program is interrupted
by a signal. The handler can modify volatile sig_atomic_t data. Any attempt
to modify other data is undefined behavior. [1.9/9]

As far as I know, these are the only guarantees made by the standard.
Best

Kai-Uwe Bux
Mar 10 '07 #6

P: n/a
tiffini <ti*****@val13xr8.orgwrote:
Hi,

We have a lot of OS's to support. So we created a mutex class with sieze and release like so
class foo{

private:
volatile int m_lock;
public:
Sieze(){ while (m_lock==1) { sleep(1);};m_lock=1;};
Release(){m_lock=0;};
... // constructors etc

}
Is this legal or do I have to use an OS type call? I thought that volatile guaranteed m_lock to be thread safe, meaning the variable m_lock could not be cashed in a register if the thread was swapped out for another thread.
This article may be useful for you too:
http://www.ddj.com/dept/cpp/184403766

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Mar 13 '07 #7

P: n/a
On Mar 13, 1:43 pm, ricec...@gehennom.invalid (Marcus Kwok) wrote:
This article may be useful for you too:http://www.ddj.com/dept/cpp/184403766
In it's initial explanation of volatile, I agree. As to the author's
implementation, I'm not so sure. I didn't go through it in detail, but
it looked a little suspicious as I was scanning it, and his conclusion
was hardly encouraging:

"A couple of projects I've been involved with use volatile and
LockingPtr to great effect. The code is clean and understandable. I
recall a couple of deadlocks, but I prefer deadlocks to race
conditions because they are so much easier to debug. There were
virtually no problems related to race conditions. But then you never
know."

Um. Yeah. I'll run right out and use that implementation! Not.

Mar 13 '07 #8

This discussion thread is closed

Replies have been disabled for this discussion.