Pancakes:IPC EntryBased: Difference between revisions

[unchecked revision][unchecked revision]
Content deleted Content added
Pancakes (talk | contribs)
added simple lock free single reader and single writer ring buffer implementation
 
m Bot: Replace deprecated source tag with syntaxhighlight
 
(3 intermediate revisions by 2 users not shown)
Line 4:
and one writer are supported.
 
I have tested this code fairly well, and there appears to be no bugs. To get a major increase in speed you can return a pointer to the inside of the buffer for reads but that is not secure unless you trust the writer.
 
This is designed to be used for inter-process communication as if you have threads sharing the same address space you might find a faster method would be to have a ring buffer of static pointers and use those to point to memory and use flags to determine if the memory should be freed after the reader uses it because this would eliminate the need for the writer to copy data into the buffer.
 
==== Example Usage ====
<sourcesyntaxhighlight lang="c">
RBM rbm;
char buf[128];
Line 18 ⟶ 20:
sz = 128;
rb_read_nbio(&rbm, &buf[0], &sz, 0);
</syntaxhighlight>
</source>
The code above will write to the ring buffer, and then read from it. You
can have two separate threads with one reading and one writing. For bi-directional communication just use two different buffers.
 
==== Code ====
<sourcesyntaxhighlight lang="c">
#ifdef B64
typedef unsigned long long uintptr;
#else
typedef unsigned int uintptr;
#endif
typedef unsigned long long uint64;
typedef unsigned int uint32;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef int int32;
#endif
 
struct _RBE {
uint32int32 w;
uint32int32 r;
uint8 d[];
};
Line 33 ⟶ 47:
struct _RBME {
RB *rb;
uint32int32 sz;
};
typedef struct _RBME RBM;
Line 39 ⟶ 53:
int rb_write_nbio(RBM *rbm, void *p, uint32 sz) {
RB volatile *rb;
uint32int32 r;
uint32int32 w;
uint32 *h;
uint8int32 x, y;
uint32int32 asz;
uint32int32 max;
rb = (RB volatile*)rbm->rb;
Line 66 ⟶ 80:
/* not enough space */
if ((w < r) && (w + asz) >= r) {
//printf("##$#\n");
return 0;
}
Line 72 ⟶ 85:
/* not enough space */
if ((w >= r) && ((rbm->sz - w) + r) < asz) {
//printf("LESS THAN\n");
return 0;
}
/* write length */
if (w == rbm->sz) {
w = 0;
}
rb->d[w++] = sz >> 8;
if (w >= rbm->sz) {
Line 90 ⟶ 99:
/* split write */
ifmax (w >= r && (rbm->sz - w) < sz) {;
if (w =>= rbm->r && max < sz) {
/* copy first part */
max = rbm->sz - w;
for (x = 0; x < max; ++x) {
rb->d[w + x] = ((uint8*)p)[x];
Line 126 ⟶ 135:
int rb_read_nbio(RBM *rbm, void *p, uint32 *sz, uint32 *advance) {
RB volatile *rb;
uint32int32 r;
uint32 volatileint32 w;
uint32int32 h;
intint32 x, y;
uint8 *_p;
uint32int32 max;
_p = (uint8*)p;
Line 216 ⟶ 225:
return 1;
}
</syntaxhighlight>
</source>