/******************************************************************************
Welcome to GDB Online.
GDB online is an online compiler and debugger tool for C, C++, Python, Java, PHP, Ruby, Perl,
C#, VB, Swift, Pascal, Fortran, Haskell, Objective-C, Assembly, HTML, CSS, JS, SQLite, Prolog.
Cod,e Compile, Run and Debug online from anywhere in world.
*******************************************************************************/
#include <stdio.h>
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <vector>
class Processor
{
public:
int bc_=0;
Processor() {}
void process(size_t byte_count, uint8_t* data)
{
std::this_thread::sleep_for(std::chrono::milliseconds(byte_count));
bc_ += byte_count;
}
int finish() {return bc_;}
};
std::mutex lock{};
std::condition_variable new_data{};
std::vector<uint8_t> pending_bytes{};
bool data_done=false;
// producer
void add_bytes(size_t byte_count, const void *data)
{
if (byte_count == 0)
return;
std::lock_guard<std::mutex> guard(lock);
uint8_t *typed_data = (uint8_t *)data;
pending_bytes.insert(pending_bytes.end(), typed_data,
typed_data + byte_count);
new_data.notify_all();
}
void finish()
{
std::lock_guard<std::mutex> guard(lock);
data_done = true;
new_data.notify_all();
}
// consumer
int process(void)
{
auto data_processor = std::unique_ptr<Processor>(new Processor());
bool done = false;
while (!done)
{
std::unique_lock<std::mutex> guard(lock);
new_data.wait(guard, [&]() {return data_done || pending_bytes.size() > 0;});
size_t byte_count = pending_bytes.size();
std::vector<uint8_t> data_copy;
if (byte_count > 0)
{
data_copy = pending_bytes; // vector copies on assignment
pending_bytes.clear();
}
done = data_done;
guard.unlock();
if (byte_count > 0)
{
data_processor->process(byte_count, data_copy.data());
}
}
std::cout << data_processor->finish();
return data_processor->finish();
}
int main()
{
uint8_t bytes[1024];
std::thread t1(process);
for (int i = 0; i < 22; i++)
{
add_bytes(1024, &bytes);
}
finish();
t1.join();
}