Pancakes:IPC EntryBased: Difference between revisions
[unchecked revision] | [unchecked revision] |
Content deleted Content added
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 ====
<
RBM rbm;
char buf[128];
Line 18 ⟶ 20:
sz = 128;
rb_read_nbio(&rbm, &buf[0], &sz, 0);
</syntaxhighlight>
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 ====
<
#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 {
uint8 d[];
};
Line 33 ⟶ 47:
struct _RBME {
RB *rb;
};
typedef struct _RBME RBM;
Line 39 ⟶ 53:
int rb_write_nbio(RBM *rbm, void *p, uint32 sz) {
RB volatile *rb;
uint32 *h;
rb = (RB volatile*)rbm->rb;
Line 66 ⟶ 80:
/* not enough space */
if ((w < r) && (w + asz) >= r) {
return 0;
}
Line 72 ⟶ 85:
/* not enough space */
if ((w >= r) && ((rbm->sz - w) + r) < asz) {
return 0;
}
/* write length */
if (w == rbm->sz) {▼
rb->d[w++] = sz >> 8;
if (w >= rbm->sz) {
Line 90 ⟶ 99:
/* split write */
/* copy first part */
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;
uint8 *_p;
_p = (uint8*)p;
Line 216 ⟶ 225:
return 1;
}
</syntaxhighlight>
|