Question: //Thread 1

```
std::uint64_t getAndResetProcessingTimeInMicro()
{
    auto value = m_cumulatedProcessingTimeCount.load(boost::memory_order_acquire);

    if (value == 0)
        return 0;
    auto processingTime = m_cumulatedProcessingTime.load(boost::memory_order_relaxed);

    resetProcessingTimeInMicro();

    return processingTime / value;
}

```

//Thread 2

```
void addProcessingTimeInMicro(std::uint64_t processedTime)
{ 
    m_cumulatedProcessingTime.fetch_add(processedTime, boost::memory_order_relaxed); 
    //ctxt switch here  //-----HERE------
    m_cumulatedProcessingTimeCount.fetch_add(1, boost::memory_order_release);
}

```

Thread1 compute the average of the processing time, Thread 2 accumulate processing time.

I would like to get the insurance that a context switch can't corrompt the data at HERE place without introduce a lock, can I achieve this result by using atomic object ?

Answer: 
If you want to do two different atomic operations together you need a mutex both when you write and when you read them. Mutexes don't prevent context switches, but used this way guarantee that you don't access half updated states.

Alternatively, if you really don't want to use a mutex, you could use some of the 64 bits of a single uint64\_t to store the count (say the lower 8).
Then you would 

```
m_cumulatedProcessingTime.fetch_add((processedTime << 8) + 1, boost::memory_order_release);

```

and then retrieve it

```
auto value = m_cumulatedProcessingTimeCount.load(boost::memory_order_acquire);
auto time = value >> 8;
auto count = value & 0xff;

```
You can, but you probably don't want to.

You need an [atomic shared\_ptr](http://en.cppreference.com/w/cpp/memory/shared_ptr/atomic) to the struct that holds both variables. The process for reading is just to copy the `shared_ptr` atomically and look at the struct it points to. The process for writing is:

1. Read the atomic `shared_ptr`.
2. Allocate (using `std::make_shared`) a new struct containing the new values for both variables based on the ones in the struct.
3. Attempt an atomic compare/exchange to set the atomic shared\_ptr to point to your new struct.
4. If the compare/exchange succeeds, you are done.
5. Free the new structure you created and go back to step 1. (You are guaranteed some other writer made forward progress.)

You really don't want to do this though. Just use a lock.