Skip to content

Commit 4ebc75c

Browse files
authored
Update libreactor (#5678)
* Use all cpu cores by default The previous setup only used every other core * Update ubuntu and gcc * Copy sources at the end to avoid rebuilding cached docker layers Also remove unecessary call to "make clean" * Use multi-stage docker build for a much smaller final image * Update to the latest version libreactor And use reactor_server abstraction * Set CFLAGS to enable gcc -O3 optimization Also set warning flags * Update README * Remove "broken" tag
1 parent 9001e48 commit 4ebc75c

File tree

7 files changed

+104
-186
lines changed

7 files changed

+104
-186
lines changed

frameworks/C/libreactor/Makefile

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
CC = gcc-6
2-
PROG = libreactor
3-
OBJS = src/setup.o src/main.o
4-
CFLAGS = -std=gnu11 -Wall -O3 -march=native -mtune=native -flto -fuse-linker-plugin -Isrc
5-
LDADD = -lreactor -ldynamic -lclo
1+
PROG = libreactor
2+
OBJS = src/setup.o src/main.o
3+
CFLAGS = -std=gnu11 -Wall -Wextra -Wpedantic -O3
4+
LDFLAGS = -pthread
5+
LDADD = -lreactor -ldynamic -lclo -flto
66

77
$(PROG): $(OBJS)
8-
$(CC) -o $@ $^ $(CFLAGS) $(LDADD)
8+
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) $(LDADD)
99

1010
clean:
1111
rm -f $(PROG) $(OBJS)

frameworks/C/libreactor/README.md

+20-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1-
# libreactor
1+
# libreactor Benchmarking Test
22

3-
Benchmarks for the [libreactor](https://github.com/fredrikwidlund/libreactor) library.
3+
### Test Type Implementation Source Code
4+
5+
* [JSON](src/main.c)
6+
* [PLAINTEXT](src/main.c)
7+
8+
9+
## Important Libraries
10+
* [libreactor](https://github.com/fredrikwidlund/libreactor)
11+
* [libclo](https://github.com/fredrikwidlund/libclo/)
12+
* [libdynamic](https://github.com/fredrikwidlund/libdynamic/)
13+
14+
## Test URLs
15+
### JSON
16+
17+
http://localhost:8080/json
18+
19+
### PLAINTEXT
20+
21+
http://localhost:8080/plaintext

frameworks/C/libreactor/benchmark_config.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@
1919
"database_os": "Linux",
2020
"display_name": "libreactor",
2121
"notes": "",
22-
"versus": "None",
23-
"tags": ["broken"]
22+
"versus": "None"
2423
}
2524
}
2625
]
+37-24
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,46 @@
1-
FROM ubuntu:16.04
1+
FROM ubuntu:18.04 as builder
22

33
RUN apt-get update -yqq
4-
RUN apt-get install -yqq software-properties-common python-software-properties wget make
4+
RUN apt-get install -yqq wget make automake libtool file gcc-8 g++-8
55

6-
RUN add-apt-repository ppa:ubuntu-toolchain-r/test -y && \
7-
apt-get update -yqq && \
8-
apt-get install -yqq gcc-6 g++-6
9-
10-
ADD ./ /libreactor
116
WORKDIR /libreactor
127

13-
RUN wget -q https://github.com/fredrikwidlund/libdynamic/releases/download/v1.1.0/libdynamic-1.1.0.tar.gz && \
14-
tar xfz libdynamic-1.1.0.tar.gz && \
15-
cd libdynamic-1.1.0 && \
16-
./configure CC=gcc-6 AR=gcc-ar-6 NM=gcc-nm-6 RANLIB=gcc-ranlib-6 && \
17-
make && make install
8+
ENV CC=gcc-8 AR=gcc-ar-8 NM=gcc-nm-8 RANLIB=gcc-ranlib-8
9+
10+
RUN wget -q https://github.com/akheron/jansson/archive/v2.12.tar.gz -O jansson-2.12.tar.gz && \
11+
tar xfz jansson-2.12.tar.gz && \
12+
cd jansson-2.12 && \
13+
autoreconf -fi && \
14+
./configure && \
15+
make install
16+
17+
RUN wget -q https://github.com/fredrikwidlund/libdynamic/releases/download/v1.3.0/libdynamic-1.3.0.tar.gz && \
18+
tar xfz libdynamic-1.3.0.tar.gz && \
19+
cd libdynamic-1.3.0 && \
20+
./configure --prefix=/usr && \
21+
make install
22+
23+
RUN wget -q https://github.com/fredrikwidlund/libclo/releases/download/v1.0.0/libclo-1.0.0.tar.gz && \
24+
tar xfz libclo-1.0.0.tar.gz && \
25+
cd libclo-1.0.0 && \
26+
./configure && \
27+
make install
1828

19-
RUN wget -q https://github.com/fredrikwidlund/libreactor/releases/download/v1.0.0/libreactor-1.0.0.tar.gz && \
20-
tar xfz libreactor-1.0.0.tar.gz && \
21-
cd libreactor-1.0.0 && \
22-
./configure CC=gcc-6 AR=gcc-ar-6 NM=gcc-nm-6 RANLIB=gcc-ranlib-6 && \
23-
make && make install
29+
RUN wget -q https://github.com/fredrikwidlund/libreactor/releases/download/v1.0.1/libreactor-1.0.1.tar.gz && \
30+
tar xfz libreactor-1.0.1.tar.gz && \
31+
cd libreactor-1.0.1 && \
32+
./configure --prefix=/usr CFLAGS="-Wall -Wextra -Wpedantic -O3" && \
33+
make install
2434

25-
RUN wget -q https://github.com/fredrikwidlund/libclo/releases/download/v0.1.0/libclo-0.1.0.tar.gz && \
26-
tar xfz libclo-0.1.0.tar.gz && \
27-
cd libclo-0.1.0 && \
28-
./configure CC=gcc-6 AR=gcc-ar-6 NM=gcc-nm-6 RANLIB=gcc-ranlib-6 && \
29-
make && make install
35+
COPY src/ /libreactor/src/
36+
COPY Makefile /libreactor/Makefile
3037

31-
RUN make clean && make
38+
RUN make
39+
40+
41+
FROM ubuntu:18.04
42+
43+
WORKDIR /libreactor
44+
COPY --from=builder /libreactor .
3245

33-
CMD ["./libreactor"]
46+
CMD ["./libreactor"]

frameworks/C/libreactor/src/main.c

+27-120
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,8 @@
11
#include <stdio.h>
22
#include <stdlib.h>
33
#include <stdint.h>
4-
#include <stdarg.h>
5-
#include <signal.h>
64
#include <unistd.h>
7-
#include <setjmp.h>
8-
#include <errno.h>
95
#include <string.h>
10-
#include <pthread.h>
11-
#include <sys/socket.h>
12-
#include <sys/resource.h>
13-
#include <sys/param.h>
14-
#include <sys/wait.h>
15-
#include <sys/queue.h>
16-
#include <linux/sched.h>
17-
#include <netdb.h>
186
#include <err.h>
197

208
#include <dynamic.h>
@@ -23,118 +11,37 @@
2311

2412
#include "setup.h"
2513

26-
static char date[] = "Thu, 01 Jan 1970 00:00:00 GMT";
27-
28-
static int timer_event(void *state, int type, void *data)
29-
{
30-
(void) state;
31-
(void) data;
32-
if (type != REACTOR_TIMER_EVENT_CALL)
33-
err(1, "timer");
34-
35-
reactor_http_date(date);
36-
return REACTOR_OK;
37-
}
38-
39-
static int plaintext(reactor_http *http)
14+
static reactor_status tfb(reactor_event *event)
4015
{
41-
char content_length[11], *body = "Hello, World!";
42-
size_t size;
43-
44-
size = strlen(body);
45-
reactor_util_u32toa(size, content_length);
46-
reactor_http_send_response(http, (reactor_http_response[]){{
47-
.version = 1,
48-
.status = 200,
49-
.reason = {"OK", 2},
50-
.headers = 4,
51-
.header[0] = {{"Server", 6}, {"libreactor", 10}},
52-
.header[1] = {{"Date", 4}, {date, strlen(date)}},
53-
.header[2] = {{"Content-Type", 12}, {"text/plain", 10}},
54-
.header[3] = {{"Content-Length", 14}, {content_length, strlen(content_length)}},
55-
.body = {body, size}
56-
}});
57-
return REACTOR_OK;
16+
reactor_server_session *session = (reactor_server_session *) event->data;
17+
18+
if (reactor_vector_equal(session->request->target, reactor_vector_string("/json"))) {
19+
char json_msg[32];
20+
(void) clo_encode((clo[]) {clo_object({"message", clo_string("Hello, World!")})}, json_msg, sizeof(json_msg));
21+
reactor_server_ok(session, reactor_vector_string("application/json"), reactor_vector_string(json_msg));
22+
return REACTOR_OK;
23+
}
24+
else if (reactor_vector_equal(session->request->target, reactor_vector_string("/plaintext"))) {
25+
reactor_server_ok(session, reactor_vector_string("text/plain"), reactor_vector_string("Hello, World!"));
26+
return REACTOR_OK;
27+
}
28+
else {
29+
reactor_server_ok(session, reactor_vector_string("text/plain"), reactor_vector_string("Hello from libreactor!\n"));
30+
return REACTOR_OK;
31+
}
5832
}
5933

60-
static int json(reactor_http *http)
61-
{
62-
char body[4096], content_length[11];
63-
size_t size;
64-
65-
(void) clo_encode((clo[]) {clo_object({"message", clo_string("Hello, World!")})}, body, sizeof(body));
66-
size = strlen(body);
67-
reactor_util_u32toa(size, content_length);
68-
reactor_http_send_response(http, (reactor_http_response[]){{
69-
.version = 1,
70-
.status = 200,
71-
.reason = {"OK", 2},
72-
.headers = 4,
73-
.header[0] = {{"Server", 6}, {"libreactor", 10}},
74-
.header[1] = {{"Date", 4}, {date, strlen(date)}},
75-
.header[2] = {{"Content-Type", 12}, {"application/json", 16}},
76-
.header[3] = {{"Content-Length", 14}, {content_length, strlen(content_length)}},
77-
.body = {body, size}
78-
}});
79-
return REACTOR_OK;
80-
}
81-
82-
int http_event(void *state, int type, void *data)
83-
{
84-
reactor_http *http = state;
85-
reactor_http_request *request;
86-
87-
if (reactor_unlikely(type != REACTOR_HTTP_EVENT_REQUEST))
88-
{
89-
reactor_http_close(http);
90-
free(http);
91-
return REACTOR_ABORT;
92-
}
93-
request = data;
94-
95-
if (reactor_http_header_value(&request->path, "/plaintext"))
96-
return plaintext(http);
97-
else if (reactor_http_header_value(&request->path, "/json"))
98-
return json(http);
99-
else
100-
{
101-
reactor_http_send_response(http, (reactor_http_response[]){{
102-
.version = 1,
103-
.status = 404,
104-
.reason = {"Not Found", 9},
105-
.headers = 3,
106-
.header[0] = {{"Server", 6}, {"libreactor", 10}},
107-
.header[1] = {{"Date", 4}, {date, strlen(date)}},
108-
.header[2] = {{"Content-Length", 14}, {"0", 1}},
109-
.body = {NULL, 0}
110-
}});
111-
return REACTOR_OK;
112-
}
113-
}
114-
115-
static int tcp_event(void *state, int type, void *data)
116-
{
117-
reactor_http *http;
118-
119-
if (type != REACTOR_TCP_EVENT_ACCEPT)
120-
err(1, "tcp");
121-
122-
http = malloc(sizeof *http);
123-
if (!http)
124-
abort();
125-
(void) reactor_http_open(http, http_event, http, *(int *) data, REACTOR_HTTP_FLAG_SERVER);
126-
return REACTOR_OK;
127-
}
12834

12935
int main()
13036
{
131-
reactor_timer timer;
132-
reactor_tcp tcp;
37+
reactor_server server;
13338

134-
setup(1, 0);
135-
(void) reactor_core_construct();
136-
(void) reactor_timer_open(&timer, timer_event, &timer, 1, 1000000000);
137-
(void) reactor_tcp_open(&tcp, tcp_event, &tcp, "0.0.0.0", "8080", REACTOR_TCP_FLAG_SERVER);
138-
(void) reactor_core_run();
139-
reactor_core_destruct();
140-
}
39+
setup();
40+
reactor_construct();
41+
reactor_server_construct(&server, NULL, NULL);
42+
reactor_server_route(&server, tfb, NULL);
43+
(void) reactor_server_open(&server, "0.0.0.0", "8080");
44+
45+
reactor_run();
46+
reactor_destruct();
47+
}

frameworks/C/libreactor/src/setup.c

+12-31
Original file line numberDiff line numberDiff line change
@@ -19,30 +19,7 @@ struct cpu
1919
cpu_set_t set;
2020
};
2121

22-
int realtime(void)
23-
{
24-
struct sched_param param;
25-
struct rlimit rlim;
26-
int e;
27-
28-
e = sched_getparam(0, &param);
29-
if (e == -1)
30-
return -1;
31-
32-
param.sched_priority = sched_get_priority_max(SCHED_FIFO);
33-
rlim = (struct rlimit) {.rlim_cur = param.sched_priority, .rlim_max = param.sched_priority};
34-
e = prlimit(0, RLIMIT_RTPRIO, &rlim, NULL);
35-
if (e == -1)
36-
return -1;
37-
38-
e = sched_setscheduler(0, SCHED_FIFO, &param);
39-
if (e == -1)
40-
return -1;
41-
42-
return 0;
43-
}
44-
45-
static void cpu_list(vector *list, int sib)
22+
static void cpu_list(vector *list, int use_all_cores)
4623
{
4724
struct cpu cpu;
4825
char path[1024], buf[1024];
@@ -64,8 +41,13 @@ static void cpu_list(vector *list, int sib)
6441
close(fd);
6542

6643
id = strtoul(buf, NULL, 0);
67-
if (!sib && id != i)
68-
continue;
44+
45+
if (use_all_cores){
46+
id = i; /* add every cpu (whether physical or logical) to the list */
47+
}
48+
else if (id != i){
49+
continue; /* ignore sibling CPUs */
50+
}
6951

7052
cpu = (struct cpu) {0};
7153
cpu.id = id;
@@ -75,7 +57,7 @@ static void cpu_list(vector *list, int sib)
7557
}
7658
}
7759

78-
void setup(size_t skip, int sib)
60+
void setup()
7961
{
8062
vector list;
8163
struct cpu *cpu;
@@ -84,11 +66,10 @@ void setup(size_t skip, int sib)
8466
pid_t cpid;
8567

8668
signal(SIGPIPE, SIG_IGN);
87-
cpu_list(&list, sib);
88-
for (i = 0; i < vector_size(&list); i ++)
69+
cpu_list(&list, 1);
70+
71+
for (i = 0; i < vector_size(&list); i++)
8972
{
90-
if (i % skip != 0)
91-
continue;
9273
cpu = vector_at(&list, i);
9374
cpid = fork();
9475
if (cpid == -1)

frameworks/C/libreactor/src/setup.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#ifndef SETUP_H_INCLUDED
22
#define SETUP_H_INCLUDED
33

4-
void setup(size_t, int);
4+
void setup();
55

66
#endif /* SETUP_H_INCLUDED */

0 commit comments

Comments
 (0)