Răsfoiți Sursa

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
Marc Richards 5 ani în urmă
părinte
comite
4ebc75cbb3

+ 6 - 6
frameworks/C/libreactor/Makefile

@@ -1,11 +1,11 @@
-CC     = gcc-6
-PROG   = libreactor
-OBJS   = src/setup.o src/main.o
-CFLAGS = -std=gnu11 -Wall -O3 -march=native -mtune=native -flto -fuse-linker-plugin -Isrc
-LDADD  = -lreactor -ldynamic -lclo
+PROG    = libreactor
+OBJS    = src/setup.o src/main.o
+CFLAGS  = -std=gnu11 -Wall -Wextra -Wpedantic -O3
+LDFLAGS = -pthread
+LDADD   = -lreactor -ldynamic -lclo -flto
 
 $(PROG): $(OBJS)
-	$(CC) -o $@ $^ $(CFLAGS) $(LDADD)
+	$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS) $(LDADD)
 
 clean:
 	rm -f $(PROG) $(OBJS)

+ 20 - 2
frameworks/C/libreactor/README.md

@@ -1,3 +1,21 @@
-# libreactor
+# libreactor Benchmarking Test
 
-Benchmarks for the [libreactor](https://github.com/fredrikwidlund/libreactor) library.
+### Test Type Implementation Source Code
+
+* [JSON](src/main.c)
+* [PLAINTEXT](src/main.c)
+
+
+## Important Libraries
+* [libreactor](https://github.com/fredrikwidlund/libreactor)
+* [libclo](https://github.com/fredrikwidlund/libclo/)
+* [libdynamic](https://github.com/fredrikwidlund/libdynamic/)
+
+## Test URLs
+### JSON
+
+http://localhost:8080/json
+
+### PLAINTEXT
+
+http://localhost:8080/plaintext

+ 1 - 2
frameworks/C/libreactor/benchmark_config.json

@@ -19,8 +19,7 @@
         "database_os": "Linux",
         "display_name": "libreactor",
         "notes": "",
-        "versus": "None",
-        "tags": ["broken"]
+        "versus": "None"
       }
     }
   ]

+ 37 - 24
frameworks/C/libreactor/libreactor.dockerfile

@@ -1,33 +1,46 @@
-FROM ubuntu:16.04
+FROM ubuntu:18.04 as builder
 
 RUN apt-get update -yqq
-RUN apt-get install -yqq software-properties-common python-software-properties wget make
+RUN apt-get install -yqq wget make automake libtool file gcc-8 g++-8
 
-RUN add-apt-repository ppa:ubuntu-toolchain-r/test -y && \
-    apt-get update -yqq && \
-    apt-get install -yqq gcc-6 g++-6
-
-ADD ./ /libreactor
 WORKDIR /libreactor
 
-RUN wget -q https://github.com/fredrikwidlund/libdynamic/releases/download/v1.1.0/libdynamic-1.1.0.tar.gz && \
-    tar xfz libdynamic-1.1.0.tar.gz && \
-    cd libdynamic-1.1.0 && \
-    ./configure CC=gcc-6 AR=gcc-ar-6 NM=gcc-nm-6 RANLIB=gcc-ranlib-6 && \
-    make && make install
+ENV CC=gcc-8 AR=gcc-ar-8 NM=gcc-nm-8 RANLIB=gcc-ranlib-8
+
+RUN wget -q https://github.com/akheron/jansson/archive/v2.12.tar.gz -O jansson-2.12.tar.gz && \
+    tar xfz jansson-2.12.tar.gz && \
+    cd jansson-2.12 && \
+    autoreconf -fi && \
+    ./configure && \
+    make install
+
+RUN wget -q https://github.com/fredrikwidlund/libdynamic/releases/download/v1.3.0/libdynamic-1.3.0.tar.gz && \
+    tar xfz libdynamic-1.3.0.tar.gz && \
+    cd libdynamic-1.3.0 && \
+    ./configure --prefix=/usr && \
+    make install
+
+RUN wget -q https://github.com/fredrikwidlund/libclo/releases/download/v1.0.0/libclo-1.0.0.tar.gz && \
+    tar xfz libclo-1.0.0.tar.gz && \
+    cd libclo-1.0.0 && \
+    ./configure && \
+    make install
 
-RUN wget -q https://github.com/fredrikwidlund/libreactor/releases/download/v1.0.0/libreactor-1.0.0.tar.gz && \
-    tar xfz libreactor-1.0.0.tar.gz && \
-    cd libreactor-1.0.0 && \
-    ./configure CC=gcc-6 AR=gcc-ar-6 NM=gcc-nm-6 RANLIB=gcc-ranlib-6 && \
-    make && make install
+RUN wget -q https://github.com/fredrikwidlund/libreactor/releases/download/v1.0.1/libreactor-1.0.1.tar.gz && \
+    tar xfz libreactor-1.0.1.tar.gz && \
+    cd libreactor-1.0.1 && \
+    ./configure --prefix=/usr CFLAGS="-Wall -Wextra -Wpedantic -O3" && \
+    make install
 
-RUN wget -q https://github.com/fredrikwidlund/libclo/releases/download/v0.1.0/libclo-0.1.0.tar.gz && \
-    tar xfz libclo-0.1.0.tar.gz && \
-    cd libclo-0.1.0 && \
-    ./configure CC=gcc-6 AR=gcc-ar-6 NM=gcc-nm-6 RANLIB=gcc-ranlib-6 && \
-    make && make install
+COPY src/ /libreactor/src/
+COPY Makefile /libreactor/Makefile
 
-RUN make clean && make
+RUN make
+
+
+FROM ubuntu:18.04
+
+WORKDIR /libreactor
+COPY --from=builder /libreactor .
 
-CMD ["./libreactor"]
+CMD ["./libreactor"]

+ 27 - 120
frameworks/C/libreactor/src/main.c

@@ -1,20 +1,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
-#include <stdarg.h>
-#include <signal.h>
 #include <unistd.h>
-#include <setjmp.h>
-#include <errno.h>
 #include <string.h>
-#include <pthread.h>
-#include <sys/socket.h>
-#include <sys/resource.h>
-#include <sys/param.h>
-#include <sys/wait.h>
-#include <sys/queue.h>
-#include <linux/sched.h>
-#include <netdb.h>
 #include <err.h>
 
 #include <dynamic.h>
@@ -23,118 +11,37 @@
 
 #include "setup.h"
 
-static char date[] = "Thu, 01 Jan 1970 00:00:00 GMT";
-
-static int timer_event(void *state, int type, void *data)
-{
-  (void) state;
-  (void) data;
-  if (type != REACTOR_TIMER_EVENT_CALL)
-    err(1, "timer");
-
-  reactor_http_date(date);
-  return REACTOR_OK;
-}
-
-static int plaintext(reactor_http *http)
+static reactor_status tfb(reactor_event *event)
 {
-  char content_length[11], *body = "Hello, World!";
-  size_t size;
-
-  size = strlen(body);
-  reactor_util_u32toa(size, content_length);
-  reactor_http_send_response(http, (reactor_http_response[]){{
-        .version = 1,
-	.status = 200,
-	.reason = {"OK", 2},
-	.headers = 4,
-        .header[0] = {{"Server", 6}, {"libreactor", 10}},
-        .header[1] = {{"Date", 4}, {date, strlen(date)}},
-	.header[2] = {{"Content-Type", 12}, {"text/plain", 10}},
-	.header[3] = {{"Content-Length", 14}, {content_length, strlen(content_length)}},
-	.body = {body, size}
-      }});
-  return REACTOR_OK;
+  reactor_server_session *session = (reactor_server_session *) event->data;
+
+  if (reactor_vector_equal(session->request->target, reactor_vector_string("/json"))) {
+    char json_msg[32];
+    (void) clo_encode((clo[]) {clo_object({"message", clo_string("Hello, World!")})}, json_msg, sizeof(json_msg));
+    reactor_server_ok(session, reactor_vector_string("application/json"), reactor_vector_string(json_msg));
+    return REACTOR_OK;
+  }
+  else if (reactor_vector_equal(session->request->target, reactor_vector_string("/plaintext"))) {
+    reactor_server_ok(session, reactor_vector_string("text/plain"), reactor_vector_string("Hello, World!"));
+    return REACTOR_OK;
+  }
+  else {
+    reactor_server_ok(session, reactor_vector_string("text/plain"), reactor_vector_string("Hello from libreactor!\n"));
+    return REACTOR_OK;
+  }
 }
 
-static int json(reactor_http *http)
-{
-  char body[4096], content_length[11];
-  size_t size;
-  
-  (void) clo_encode((clo[]) {clo_object({"message", clo_string("Hello, World!")})}, body, sizeof(body));
-  size = strlen(body);
-  reactor_util_u32toa(size, content_length);
-  reactor_http_send_response(http, (reactor_http_response[]){{
-        .version = 1,
-	.status = 200,
-	.reason = {"OK", 2},
-	.headers = 4,
-        .header[0] = {{"Server", 6}, {"libreactor", 10}},
-        .header[1] = {{"Date", 4}, {date, strlen(date)}},
-	.header[2] = {{"Content-Type", 12}, {"application/json", 16}},
-	.header[3] = {{"Content-Length", 14}, {content_length, strlen(content_length)}},
-	.body = {body, size}
-      }});
-  return REACTOR_OK;
-}
-
-int http_event(void *state, int type, void *data)
-{
-  reactor_http *http = state;
-  reactor_http_request *request;
-
-  if (reactor_unlikely(type != REACTOR_HTTP_EVENT_REQUEST))
-    {
-      reactor_http_close(http);
-      free(http);
-      return REACTOR_ABORT;
-    }
-  request = data;
-  
-  if (reactor_http_header_value(&request->path, "/plaintext"))
-    return plaintext(http);
-  else if (reactor_http_header_value(&request->path, "/json"))
-    return json(http);
-  else
-    {
-      reactor_http_send_response(http, (reactor_http_response[]){{
-	    .version = 1,
-	    .status = 404,
-	    .reason = {"Not Found", 9},
-	    .headers = 3,
-            .header[0] = {{"Server", 6}, {"libreactor", 10}},
-            .header[1] = {{"Date", 4}, {date, strlen(date)}},
-	    .header[2] = {{"Content-Length", 14}, {"0", 1}},
-	    .body = {NULL, 0}
-	  }});
-      return REACTOR_OK;
-    }
-}
-
-static int tcp_event(void *state, int type, void *data)
-{
-  reactor_http *http;
-
-  if (type != REACTOR_TCP_EVENT_ACCEPT)
-    err(1, "tcp");
-
-  http = malloc(sizeof *http);
-  if (!http)
-    abort();
-  (void) reactor_http_open(http, http_event, http, *(int *) data, REACTOR_HTTP_FLAG_SERVER);
-  return REACTOR_OK;
-}
 
 int main()
 {
-  reactor_timer timer;
-  reactor_tcp tcp;
+  reactor_server server;
 
-  setup(1, 0);  
-  (void) reactor_core_construct();
-  (void) reactor_timer_open(&timer, timer_event, &timer, 1, 1000000000);
-  (void) reactor_tcp_open(&tcp, tcp_event, &tcp, "0.0.0.0", "8080", REACTOR_TCP_FLAG_SERVER);
-  (void) reactor_core_run();
-  reactor_core_destruct();
-}
+  setup();
+  reactor_construct();
+  reactor_server_construct(&server, NULL, NULL);
+  reactor_server_route(&server, tfb, NULL);
+  (void) reactor_server_open(&server, "0.0.0.0", "8080");
+
+  reactor_run();
+  reactor_destruct();
+}

+ 12 - 31
frameworks/C/libreactor/src/setup.c

@@ -19,30 +19,7 @@ struct cpu
   cpu_set_t set;
 };
 
-int realtime(void)
-{
-  struct sched_param param;
-  struct rlimit rlim;
-  int e;
-
-  e = sched_getparam(0, &param);
-  if (e == -1)
-    return -1;
-
-  param.sched_priority = sched_get_priority_max(SCHED_FIFO);
-  rlim = (struct rlimit) {.rlim_cur = param.sched_priority, .rlim_max = param.sched_priority};
-  e = prlimit(0, RLIMIT_RTPRIO, &rlim, NULL);
-  if (e == -1)
-    return -1;
-
-  e = sched_setscheduler(0, SCHED_FIFO, &param);
-  if (e == -1)
-    return -1;
-
-  return 0;
-}
-
-static void cpu_list(vector *list, int sib)
+static void cpu_list(vector *list, int use_all_cores)
 {
   struct cpu cpu;
   char path[1024], buf[1024];
@@ -64,8 +41,13 @@ static void cpu_list(vector *list, int sib)
       close(fd);
 
       id = strtoul(buf, NULL, 0);
-      if (!sib && id != i)
-        continue;
+
+      if (use_all_cores){
+        id = i; /* add every cpu (whether physical or logical) to the list */
+      }
+      else if (id != i){
+        continue; /* ignore sibling CPUs */
+      }
 
       cpu = (struct cpu) {0};
       cpu.id = id;
@@ -75,7 +57,7 @@ static void cpu_list(vector *list, int sib)
     }
 }
 
-void setup(size_t skip, int sib)
+void setup()
 {
   vector list;
   struct cpu *cpu;
@@ -84,11 +66,10 @@ void setup(size_t skip, int sib)
   pid_t cpid;
 
   signal(SIGPIPE, SIG_IGN);
-  cpu_list(&list, sib);
-  for (i = 0; i < vector_size(&list); i ++)
+  cpu_list(&list, 1);
+
+  for (i = 0; i < vector_size(&list); i++)
     {
-      if (i % skip != 0)
-        continue;
       cpu = vector_at(&list, i);
       cpid = fork();
       if (cpid == -1)

+ 1 - 1
frameworks/C/libreactor/src/setup.h

@@ -1,6 +1,6 @@
 #ifndef SETUP_H_INCLUDED
 #define SETUP_H_INCLUDED
 
-void setup(size_t, int);
+void setup();
 
 #endif /* SETUP_H_INCLUDED */