-
Notifications
You must be signed in to change notification settings - Fork 3.2k
/
Copy pathringbuffer.cpp
140 lines (115 loc) · 3.17 KB
/
ringbuffer.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include "tests.h"
#include "swoole_memory.h"
#include <thread>
#define READ_THREAD_N 4
#define WRITE_N 10000
#define PACKET_LEN 90000
//#define PRINT_SERNUM_N 10
static swMemoryPool *pool = NULL;
typedef struct
{
uint32_t id;
uint32_t size;
uint32_t serial_num;
void* ptr;
} pkg;
typedef struct
{
std::thread *thread;
swPipe pipe;
} ThreadObject;
static void thread_read(int i);
static void thread_write(void);
static ThreadObject threads[READ_THREAD_N];
TEST(ringbuffer, thread)
{
int i;
pool = swRingBuffer_new(1024 * 1024 * 4, 1);
ASSERT_NE(pool, nullptr);
for (i = 0; i < READ_THREAD_N; i++)
{
int ret = swPipeUnsock_create(&threads[i].pipe, 1, SOCK_DGRAM);
ASSERT_EQ(ret, 0);
threads[i].thread = new std::thread(thread_read, i);
}
sleep(1);
srand((unsigned int) time(NULL));
thread_write();
for (i = 0; i < READ_THREAD_N; i++)
{
threads[i].thread->join();
threads[i].pipe.close(&threads[i].pipe);
delete threads[i].thread;
}
}
static void thread_write(void)
{
uint32_t size, yield_count = 0, yield_total_count = 0;
void *ptr;
pkg send_pkg;
sw_memset_zero(&send_pkg, sizeof(send_pkg));
int i;
for (i = 0; i < WRITE_N; i++)
{
size = 10000 + rand() % PACKET_LEN;
//printf("[ < %d] alloc size=%d\n", i, size);
yield_count = 0;
do
{
ptr = pool->alloc(pool, size);
if (ptr)
{
break;
}
else
{
yield_count++;
yield_total_count++;
usleep(10);
}
} while (yield_count < 100);
if (!ptr)
{
printf("alloc failed. index=%d, break\n", i);
break;
}
ASSERT_NE(ptr, nullptr);
send_pkg.id = i;
send_pkg.ptr = ptr;
send_pkg.size = size;
send_pkg.serial_num = rand();
//保存长度值
memcpy(ptr, &size, sizeof(size));
//在指针末尾保存一个串号
memcpy((char*) ptr + size - 4, &(send_pkg.serial_num), sizeof(send_pkg.serial_num));
ASSERT_FALSE(threads[i % READ_THREAD_N].pipe.write(&threads[i % READ_THREAD_N].pipe, &send_pkg, sizeof(send_pkg)) < 0);
}
// printf("yield_total_count=%d\n", yield_total_count);
}
static void thread_read(int i)
{
pkg recv_pkg;
uint32_t tmp;
int ret;
uint32_t recv_count = 0;
int j = 0;
swPipe *sock = &threads[i].pipe;
int task_n = WRITE_N / READ_THREAD_N;
for (j = 0; j < task_n; j++)
{
ret = sock->read(sock, &recv_pkg, sizeof(recv_pkg));
ASSERT_FALSE(ret < 0);
memcpy(&tmp, recv_pkg.ptr, sizeof(tmp));
ASSERT_EQ(tmp, recv_pkg.size);
memcpy(&tmp, (char*) recv_pkg.ptr + recv_pkg.size - 4, sizeof(tmp));
ASSERT_EQ(tmp, recv_pkg.serial_num);
#ifdef PRINT_SERNUM_N
if (j % PRINT_SERNUM_N == 0)
{
printf("[ > %d] recv. recv_count=%d, serial_num=%d\n", recv_pkg.id, recv_count, tmp);
}
#endif
pool->free(pool, recv_pkg.ptr);
recv_count++;
}
}