initial implementation of thread-safe buffers which can be read and written at will

from many many threads
master
Bartek Kostrzewa 2010-11-11 19:46:50 +01:00
parent 565b1e5391
commit 58fc1cb2a4
8 changed files with 234 additions and 0 deletions

33
frame-server/Buffer.cpp Normal file
View File

@ -0,0 +1,33 @@
#include "Buffer.h"
Buffer::Buffer( int _id )
{
id = _id;
// allocate memory
}
Buffer::~Buffer()
{
// deallocate memory
}
void Buffer::set(frame_t data)
{
{
Glib::Mutex::Lock lock(mutex_);
frame = data;
}
}
frame_t Buffer::get()
{
Glib::Mutex::Lock lock(mutex_);
return frame;
}
int Buffer::get_id()
{
Glib::Mutex::Lock lock(mutex_);
return id;
}

22
frame-server/Buffer.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef __BUFFER_H_
#define __BUFFER_H_
#include <glibmm.h>
#include "defines.h"
class Buffer : public sigc::trackable
{
public:
Buffer(int _id);
~Buffer();
void set(frame_t);
frame_t get();
int get_id();
private:
int id;
frame_t frame;
Glib::Mutex mutex_;
};
#endif

43
frame-server/Buffers.cpp Normal file
View File

@ -0,0 +1,43 @@
#include "Buffers.h"
Buffers::Buffers()
{
id = 0;
}
Buffers::Buffers(int _bufnum)
{
id = 0;
for( int i = 0; i < _bufnum; i++)
add();
}
Buffers::~Buffers()
{
Glib::Mutex::Lock lock(mutex_);
buffers.clear();
}
Buffer* Buffers::get(int index)
{
Glib::Mutex::Lock lock(mutex_);
return buffers[index];
}
void Buffers::add()
{
Glib::Mutex::Lock lock(mutex_);
id += 1;
buffers.push_back( new Buffer(id) );
}
void Buffers::remove(int _id)
{
Glib::Mutex::Lock lock(mutex_);
int size = buffers.size();
for( int i = 0; i < size; i++ )
{
if( buffers[i]->get_id() == _id )
buffers.erase( buffers.begin()+i );
}
}

26
frame-server/Buffers.h Normal file
View File

@ -0,0 +1,26 @@
#include <glibmm.h>
#include <vector>
#include "defines.h"
#include "Buffer.h"
using namespace std;
class Buffers : public sigc::trackable
{
public:
Buffers();
Buffers(int);
~Buffers();
void add();
void remove(int);
Buffer* get(int);
private:
vector<Buffer*> buffers;
int id;
Glib::Mutex mutex_;
};

21
frame-server/defines.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef __DEFINES_H_
#define __DEFINES_H_
#define BUFLEN 1024
#define WIDTH 12
#define HEIGHT 7
#define SEGWIDTH 12
// not used for simplicity
//#define SEGHEIGHT 1
struct segment_t {
char r,g,b;
};
struct frame_t
{
char windows[HEIGHT][WIDTH];
segment_t segments[SEGWIDTH];
};
#endif

2
frame-server/maketest Executable file
View File

@ -0,0 +1,2 @@
#!/bin/bash
g++ -O2 -pipe -fomit-frame-pointer `pkg-config --libs --cflags glibmm-2.4` `pkg-config --libs --cflags gthread-2.0` -o test Buffer.cpp Buffers.cpp test.cpp

BIN
frame-server/test Executable file

Binary file not shown.

87
frame-server/test.cpp Normal file
View File

@ -0,0 +1,87 @@
#include <glibmm.h>
#include <vector>
#include <iostream>
#include "defines.h"
#include "Buffer.h"
#include "Buffers.h"
#define NUMBUFS 10000
#define NUMTHREADS 10
using namespace std;
Buffers* buffers;
void reader(void);
void writer(void);
int main(void)
{
Glib::thread_init();
Glib::RefPtr<Glib::MainLoop> Main = Glib::MainLoop::create();
buffers = new Buffers(NUMBUFS);
vector<Glib::Thread*> readers;
vector<Glib::Thread*> writers;
for(int i = 0; i < NUMTHREADS; i++)
{
readers.push_back( Glib::Thread::create( sigc::ptr_fun( &reader), false ) );
writers.push_back( Glib::Thread::create( sigc::ptr_fun( &writer), false ) );
}
Main->run();
/*while(1) {
usleep( 10000 );
}*/
return 0;
}
void reader(void)
{
bool quit = false;
frame_t frame;
int bufnum = 0;
while( !quit )
{
bufnum = rand()%NUMBUFS;
frame = buffers->get(bufnum)->get();
// cout << "read " << bufnum << endl;
usleep( rand()%250 );
}
}
void writer(void)
{
frame_t frame;
bool quit = false;
int bufnum = 0;
while( !quit )
{
bufnum = rand()%NUMBUFS;
for(int i = 0; i < 7; i++)
{
for(int j = 0; j < 12; j++)
{
frame.windows[i][j] = rand()%255;
}
}
for(int i = 0; i < 12; i++)
{
frame.segments[i].r = rand()%255;
frame.segments[i].g = rand()%255;
frame.segments[i].b = rand()%255;
}
buffers->get(bufnum)->set( frame );
// cout << "wrote " << bufnum << endl;
usleep( rand()%250 );
}
}