#include <thread>
#include <chrono>
#include <boost/asio.hpp>
#include <iostream>
#include <atomic>

using namespace std;

int raw_c = 0;
int raw_c2 = 0;
atomic<int> atomic_c = 0;
atomic<int> atomic_c2 = 0;
mutex m;

void serve( int i) {
    raw_c += i;
    raw_c2 += raw_c;
}

void serve_m( int i) {
    lock_guard l(m);
    serve(i);
}

void serve_a(int i) {
    atomic_c += 1;
    atomic_c2 += atomic_c;
}

void serve_am(int i) {
    lock_guard l(m);
    serve_a(i);
}

int main() {
    {
        raw_c = 0;
        raw_c2 = 0;
        atomic_c = 0;
        atomic_c2 = 0;

        thread th1( serve, 1 );
        thread th2( serve, 2 );
        th1.join(); th2.join();

        cout << raw_c << ',' << raw_c2 << ',' << atomic_c << ',' << atomic_c2 << endl;
    }
    {
        raw_c = 0;
        raw_c2 = 0;
        atomic_c = 0;
        atomic_c2 = 0;

        thread th1( serve_m, 1 );
        thread th2( serve_m, 2 );
        th1.join(); th2.join();

        cout << raw_c << ',' << raw_c2 << ',' << atomic_c << ',' << atomic_c2 << endl;
    }
    {
        raw_c = 0;
        raw_c2 = 0;
        atomic_c = 0;
        atomic_c2 = 0;

        thread th1( serve_a, 1 );
        thread th2( serve_a, 2 );
        th1.join(); th2.join();

        cout << raw_c << ',' << raw_c2 << ',' << atomic_c << ',' << atomic_c2 << endl;
    }
    {
        raw_c = 0;
        raw_c2 = 0;
        atomic_c = 0;
        atomic_c2 = 0;

        thread th1( serve_am, 1 );
        thread th2( serve_am, 2 );
        th1.join(); th2.join();

        cout << raw_c << ',' << raw_c2 << ',' << atomic_c << ',' << atomic_c2 << endl;
    }
    return 0;
}

