5

I am trying to implement Test and Test-and-set in c++.

as per C++ atomic_flag query state we cannot check the flag state, so whats the workaround for that

loop will be like this

std::atomic_flag lock_stream = ATOMIC_FLAG_INIT;
void ttas_lock()
{
    while(lock_Stream);
    while(lock_stream.test_and_set());
    return
}

error: could not convert ‘((ttas*)this)->ttas::lock_stream’ from ‘std::atomic_flag’ to ‘bool’ while(lock_stream)

Community
  • 1
  • 1
Majnu
  • 210
  • 2
  • 10
  • you code isn't clear, do you want to change it from false to true once, and return? – ronalchn Oct 09 '15 at 22:36
  • if lock=false while loop breaks, then i test and set, if false returned i get the lock, wanted to know how to check lock_Stream state, defined as std::atomic_flag lock_stream = ATOMIC_FLAG_INIT; – Majnu Oct 09 '15 at 22:37
  • it sounds like you just want to use a mutex with unique_lock? – ronalchn Oct 09 '15 at 22:41
  • yes, trying to implement TTAS https://en.wikipedia.org/wiki/Test_and_Test-and-set – Majnu Oct 09 '15 at 22:43

2 Answers2

2

If you want to test lock_stream without setting it, you should use std::atomic<bool>.

Therefore, declare it as:

std::atomic<bool> lock_stream = ATOMIC_FLAG_INIT;

Instead of test and set, you just use exchange:

void ttas_lock()
{
    while(lock_stream);
    while(lock_stream.exchange(true)); // this is equivalent to test and set
    return;
}

According to wikipedia, if test and set fails, you should do the test again, which results in:

void ttas_lock()
{
    do {
        while (lock_stream) continue;
    } while (lock_stream.exchange(true)); // actual atomic locking
    return;
}
ronalchn
  • 12,225
  • 10
  • 51
  • 61
  • is there any workaround with test and set instruction? – Majnu Oct 09 '15 at 22:47
  • The exchange is the same as test and set, think of `atomic_flag` as a wrapper around `atomic` – ronalchn Oct 09 '15 at 22:50
  • @J.S No. Some hardware can't necessarily implement the functionality you're looking for, and `atomic_flag` was designed to be the absolutely lowest common denominator. You probably shouldn't use it unless either you're targeting such hardware or what you want to do can be efficiently implemented with it. – bames53 Oct 09 '15 at 22:52
  • @ all Thanks, I implemented using exchange and bool. – Majnu Oct 09 '15 at 23:34
0

Your function:

void ttas_lock()
{
    while(lock_Stream);
    if(!lock_stream.test_and_set()) return;
}

will always return after lock_Stream is false. Not what you want.

Paul Evans
  • 27,315
  • 3
  • 37
  • 54
  • asgn2.cpp:84:15: error: could not convert ‘((ttas*)this)->ttas::lock_stream’ from ‘std::atomic_flag’ to ‘bool’ while(lock_stream). how to read atomic flag value? – Majnu Oct 09 '15 at 22:42
  • @J.S because you want : `std::atomic lock_Stream = ATOMIC_FLAG_INIT;` and then ` while (lock_Stream.test_and_set(std::memory_order_acquire));` then at some later point `lock_Stream.clear(std::memory_order_release);` – Paul Evans Oct 09 '15 at 22:44
  • can you please explain – Majnu Oct 09 '15 at 22:49
  • please see [std::atomic_flag](http://en.cppreference.com/w/cpp/atomic/atomic_flag) – Paul Evans Oct 09 '15 at 22:52