summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile17
-rw-r--r--cc_const.cc106
-rw-r--r--const.c52
-rw-r--r--list.h107
-rw-r--r--log.c53
-rw-r--r--log.h13
-rw-r--r--stats.h17
-rw-r--r--very_const.c106
8 files changed, 56 insertions, 415 deletions
diff --git a/Makefile b/Makefile
index 43e275c..5952cab 100644
--- a/Makefile
+++ b/Makefile
@@ -1,9 +1,7 @@
TARGET = const
CFLAGS += -Wall -Wextra -Wshadow -pedantic -g
-CFLAGS += $(shell echo $(fast) | sed -e 's/yes/-DFAST_AS_FUCK/g')
-LDLIBS += -L$(shell jemalloc-config --libdir) -Wl,-rpath,$(shell jemalloc-config --libdir) -ljemalloc $(shell jemalloc-config --libs)
-LDLIBS += -lprofiler
-ACO_FLAGS = -Wall -Werror -DACO_USE_VALGRIND
+LDLIBS += -ljemalloc $(shell jemalloc-config --libs)
+ACO_FLAGS = -Wall -Werror
RM ?= rm -f
all: $(TARGET)
@@ -17,15 +15,10 @@ $(ACO): $(ACO_SRC)
log.o: log.c log.h
-$(TARGET): const.c $(ACO) $(ACO_ASM) log.o
+sds.o: sds/sds.c sds/sds.h
+ $(CC) -c -o sds.o -Wall -std=c99 -pedantic -O2 sds/sds.c
-very_const: very_const.c log.o
-
-cc: cc_const.cc log.c log.h
- $(CXX) cc_const.cc log.c -o cc_const $(CFLAGS) $(LDLIBS) -lstdc++ --std=c++14
-
-run: $(TARGET)
- ./$(TARGET)
+$(TARGET): const.c $(ACO) $(ACO_ASM) log.o sds.o
clean:
$(RM) $(TARGET) *.o
diff --git a/cc_const.cc b/cc_const.cc
deleted file mode 100644
index 85e9ec7..0000000
--- a/cc_const.cc
+++ /dev/null
@@ -1,106 +0,0 @@
-#define _GNU_SOURCE
-
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <aio.h>
-
-#include <sys/socket.h>
-#include <sys/epoll.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <sys/epoll.h>
-#include <jemalloc/jemalloc.h>
-
-#include <string>
-
-#include "log.h"
-
-#define PORT 8080
-#define LISTEN_N 50
-#define EVENTS_N 50
-
-void die (const char *msg) {
- (void)msg;
- log_error (" %s", msg);
- log_error (" %s", strerror (errno));
- exit (EXIT_FAILURE);
-}
-
-
-#define assertfd(FD) if (FD < 0) die (#FD " is not a valid file descriptor")
-#define assert(EX) if (!(EX)) die (#EX " is false")
-
-std::string resp =
- "HTTP/1.1 200 OK\r\n"
- "Content-Length: 25\r\n"
- "Content-Type: text/html\r\n"
- "Connection: close\r\n"
- "\r\n"
- "Hello from const server\r\n";
-
-void dostuff (int sock);
-
-int main () {
-
- int sockfd, newsockfd;
- unsigned clilen;
- struct sockaddr_in serv_addr, cli_addr;
- log_set_level (LOG_INFO);
-
-
- sockfd = socket(AF_INET, SOCK_STREAM, 0);
- assertfd (sockfd);
- int enable = 1;
- assert (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) >= 0);
-
- bzero((char *) &serv_addr, sizeof(serv_addr));
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_addr.s_addr = INADDR_ANY;
- serv_addr.sin_port = htons(PORT);
-
- assert (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) >= 0);
-
- struct epoll_event ev, events[EVENTS_N];
- int epollfd = epoll_create1 (0);
- ev.data.ptr = NULL;
- ev.events = EPOLLIN | EPOLLERR;
- assert (epoll_ctl (epollfd, EPOLL_CTL_ADD, sockfd, &ev) == 0);
-
- listen(sockfd, LISTEN_N);
- clilen = sizeof(cli_addr);
- for (;;) {
- /*int nfds = epoll_wait (epollfd, events, EVENTS_N, 3000);
- if (nfds == 0) {
- exit (EXIT_SUCCESS);
- }
- assert (nfds != -1);
- log_trace ("nfds: %d", nfds);
- for (int i = 0; i < nfds; ++i) {*/
- for (;;) { //if (events[i].data.ptr == NULL) {
- newsockfd = accept4(sockfd, (struct sockaddr *) &cli_addr, &clilen, SOCK_NONBLOCK);
- assertfd (newsockfd);
- log_trace ("new: %d", newsockfd);
-
- dostuff (newsockfd);
- //}
- //else {
- // die ("pffff");
- //}
- }
- }
- return 0;
-}
-
-ssize_t write_sock (int sock);
-
-void dostuff (int sock) {
- write_sock (sock);
- close (sock);
-}
-
-inline ssize_t write_sock (int sock) {
-
- return write (sock, resp.c_str (), resp.size ());
-}
diff --git a/const.c b/const.c
index b0ec1e6..592ba6d 100644
--- a/const.c
+++ b/const.c
@@ -15,9 +15,9 @@
#include <jemalloc/jemalloc.h>
#include "libaco/aco.h"
+#include "sds/sds.h"
#include "list.h"
#include "log.h"
-#include "stats.h"
#define PORT 8080
#define LISTEN_N 50
@@ -53,12 +53,9 @@ typedef struct co_ctx {
int main () {
- memset (&stats, 0, sizeof (stats));
-
int sockfd, newsockfd;
unsigned clilen;
struct sockaddr_in serv_addr, cli_addr;
- log_set_level (LOG_INFO);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
@@ -93,13 +90,9 @@ int main () {
for (;;) {
int nfds = epoll_wait (epollfd, events, EVENTS_N, 3000);
if (nfds == 0) {
- report_stat ();
exit (EXIT_SUCCESS);
}
- stats.nfds_cnt++;
- stats.nfds_sum += nfds;
- if (stats.nfds_max < (size_t)nfds)
- stats.nfds_max = (size_t)nfds;
+
assert (nfds != -1);
log_trace ("nfds: %d", nfds);
for (int i = 0; i < nfds; ++i) {
@@ -135,7 +128,6 @@ int main () {
aco_resume (co);
co_cleanup (co);
}
- stats.yield_cnt++;
}
}
}
@@ -154,43 +146,53 @@ void co_cleanup (aco_t *co) {
}
ssize_t write_sock (int sock);
-int check_req_finished (sbo_buf_t *buf);
-
+int check_req_finished (sds buf);
void do_aco_stuff () {
co_ctx_t *ctx = aco_get_arg ();
- sbo_buf_t buf;
- sbo_buf_init0 (&buf);
-
+ sds buf = sdsempty();
for (; ;) {
const int size = 256;
char tmpbuf[size];
ssize_t rv = read (ctx->sock, tmpbuf, size);
+ log_trace("> received %ld bytes, errno = %d", rv, errno);
+ if (rv > 0) {
+ buf = sdscatlen (buf, tmpbuf, (size_t)rv);
+ sds req = sdscatrepr(sdsempty(), tmpbuf, (size_t)rv);
+ log_trace("> %s", req);
+ sdsfree (req);
+ }
if (rv == 0)
break;
- if (rv == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) {
- if (check_req_finished (&buf))
+
+ log_trace("len(buf) = %zu, rv = %zu", sdslen(buf), (size_t)rv);
+ if ((rv == -1) && (errno == EAGAIN || errno == EWOULDBLOCK)) {
+ log_trace("gonna check");
+ if (check_req_finished (buf)) {
+ log_trace("req finished");
break;
- else
+ }
+ else {
+ log_trace("yield");
aco_yield ();
+ }
}
- sbo_buf_grow (&buf, tmpbuf, (size_t)rv);
- log_trace("> received %ld bytes", rv);
}
- sbo_buf_free (&buf);
+ log_trace("gonna write & close");
+
+ sdsfree (buf);
write_sock (ctx->sock);
aco_exit ();
}
-inline int check_req_finished (sbo_buf_t *buf) {
+inline int check_req_finished (sds buf) {
/* Check if we finished transmission (e.g. request ends with "\r\n\r\n") */
- size_t len = sbo_buf_size (buf);
+ size_t len = sdslen (buf);
if (len < 4ULL)
return 0;
- char *base = sbo_buf_mem (buf);
- return strncmp (base + (len - 4), "\r\n\r\n", 4) == 0;
+ return strncmp (buf + (len - 4), "\r\n\r\n", 4) == 0;
}
inline ssize_t write_sock (int sock) {
diff --git a/list.h b/list.h
index 9f6ea60..6644c22 100644
--- a/list.h
+++ b/list.h
@@ -31,110 +31,3 @@ void aco_list_remove (struct aco_list *iter) {
iter->prev->next = iter->next;
iter->next->prev = iter->prev;
}
-
-#define SBO_BUF_SMALL 0x80
-#define SBO_BUF_BIG 0x00
-#define SBO_BUF_MASK 0x80
-#define SBO_BUF_SIZEMASK 0x7f
-#define SBO_BUF_SMALL_MAX_SIZE 0x7f /* 0x80 - 0x1 */
-
-
-typedef struct sbo_buf {
- unsigned char hdr;
- union {
- char small[SBO_BUF_SMALL_MAX_SIZE];
- struct {
- char *base;
- size_t size;
- size_t alloc;
- } big;
- } buf;
-} sbo_buf_t;
-
-
-int sbo_buf_init (sbo_buf_t *buf, char *init, size_t count);
-void sbo_buf_free (sbo_buf_t *buf);
-char *sbo_buf_mem (sbo_buf_t *buf);
-size_t sbo_buf_size (sbo_buf_t *buf);
-int sbo_buf_type (sbo_buf_t *buf);
-int sbo_buf_grow (sbo_buf_t *buf, char *grow, size_t count);
-
-
-int sbo_buf_init0 (sbo_buf_t *buf) {
- memset (buf, 0, sizeof (*buf));
- buf->hdr = 0 | SBO_BUF_SMALL;
- return 0;
-}
-
-
-int sbo_buf_init (sbo_buf_t *buf, char *init, size_t count) {
- if (count <= (size_t)SBO_BUF_SMALL_MAX_SIZE) {
- buf->hdr = 0 | SBO_BUF_SMALL;
- buf->hdr |= (unsigned char) count;
- memcpy (buf->buf.small, init, count);
- }
- else {
- buf->buf.big.base = malloc (count);
- if (!buf->buf.big.base)
- return errno;
- buf->hdr = 0 | SBO_BUF_BIG;
- buf->buf.big.size = count;
- buf->buf.big.alloc = count;
- }
- return 0;
-}
-
-void sbo_buf_free (sbo_buf_t *buf) {
- if (sbo_buf_type (buf) == SBO_BUF_BIG)
- free (buf->buf.big.base);
-}
-
-inline char *sbo_buf_mem (sbo_buf_t *buf) {
- if (sbo_buf_type (buf) == SBO_BUF_BIG)
- return buf->buf.big.base;
- return buf->buf.small;
-}
-
-inline size_t sbo_buf_size (sbo_buf_t *buf) {
- if (sbo_buf_type (buf) == SBO_BUF_BIG)
- return buf->buf.big.size;
-
- return buf->hdr & SBO_BUF_SIZEMASK;
-}
-
-inline int sbo_buf_type (sbo_buf_t *buf) {
- return buf->hdr & SBO_BUF_MASK;
-}
-
-int sbo_buf_grow (sbo_buf_t *buf, char *grow, size_t count) {
- if (count == 0)
- return 0;
- //size_t bufsize = sbo_buf_size (buf);
- if (sbo_buf_type (buf) == SBO_BUF_SMALL) {
- size_t current_size = sbo_buf_size (buf);
- if (current_size + count <= (size_t)SBO_BUF_SMALL_MAX_SIZE) {
- /* no need to become big. just concat two existing buffers */
- char *dst = sbo_buf_mem (buf) + current_size;
- memcpy (dst, grow, count);
- buf->hdr += count;
- return 0;
- }
- /* fallthrough to realloc */
- }
-
- char *base = sbo_buf_mem (buf);
- size_t len = sbo_buf_size (buf);
- char *newbuf = malloc (len + count);
- if (!newbuf)
- return errno;
-
- memcpy (newbuf, base, len);
- memcpy (newbuf + len, grow, count);
- sbo_buf_free (buf);
- buf->hdr = 0 | SBO_BUF_BIG; /* We definitely exceeded small buffer */
- buf->buf.big.base = newbuf;
- buf->buf.big.alloc = len + count;
- buf->buf.big.size = len + count;
-
- return 0;
-} \ No newline at end of file
diff --git a/log.c b/log.c
index 77b81c5..75165f1 100644
--- a/log.c
+++ b/log.c
@@ -24,14 +24,14 @@
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
+
+#include <sys/time.h>
#include <time.h>
#include "log.h"
static struct {
- void *udata;
FILE *fp;
- int level;
int quiet;
} L;
@@ -41,7 +41,7 @@ static const char *level_names[] = {
};
static const char *level_colors[] = {
- "\x1b[94m", "\x1b[36m", "\x1b[32m", "\x1b[33m", "\x1b[31m", "\x1b[35m"
+ "\x1b[35m", "\x1b[36m", "\x1b[32m", "\x1b[33m", "\x1b[31m", "\x1b[91m"
};
@@ -50,39 +50,30 @@ void log_set_fp(FILE *fp) {
}
-void log_set_level(int level) {
- L.level = level;
-}
-
-
void log_set_quiet(int enable) {
L.quiet = enable ? 1 : 0;
}
void log_log(int level, const char *file, int line, const char *fmt, ...) {
- if (level < L.level) {
+ if (L.quiet)
return;
- }
-
- /* Get current time */
- time_t t = time(NULL);
- struct tm *lt = localtime(&t);
-
- /* Log to stderr */
- if (!L.quiet) {
- va_list args;
- char buf[16];
- buf[strftime(buf, sizeof(buf), "%H:%M:%S", lt)] = '\0';
-
- fprintf(
- stderr, "%s %s%-5s\x1b[0m \x1b[96m%s:%d:\x1b[0m ",
- buf, level_colors[level], level_names[level], file, line);
-
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- va_end(args);
- fprintf(stderr, "\n");
- fflush(stderr);
- }
+
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ struct tm *lt = localtime(&tv.tv_sec);
+
+ va_list args;
+ char timebuf[16];
+ timebuf[strftime(timebuf, sizeof(timebuf), "%H:%M:%S", lt)] = '\0';
+
+ fprintf(stderr,
+ "%s.%04ld %s%-5s\x1b[0m \x1b[96m%s:%d:\x1b[0m ",
+ timebuf, tv.tv_usec / 100, level_colors[level], level_names[level], file, line);
+
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+ fflush(stderr);
} \ No newline at end of file
diff --git a/log.h b/log.h
index 50db985..b78695b 100644
--- a/log.h
+++ b/log.h
@@ -13,23 +13,14 @@
enum { LOG_TRACE, LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_FATAL };
-#ifndef FAST_AS_FUCK
#define log_trace(...) log_log(LOG_TRACE, __FILE__, __LINE__, __VA_ARGS__)
#define log_debug(...) log_log(LOG_DEBUG, __FILE__, __LINE__, __VA_ARGS__)
#define log_info(...) log_log(LOG_INFO, __FILE__, __LINE__, __VA_ARGS__)
#define log_warn(...) log_log(LOG_WARN, __FILE__, __LINE__, __VA_ARGS__)
#define log_error(...) log_log(LOG_ERROR, __FILE__, __LINE__, __VA_ARGS__)
#define log_fatal(...) log_log(LOG_FATAL, __FILE__, __LINE__, __VA_ARGS__)
-#else
-#define log_trace(...)
-#define log_debug(...)
-#define log_info(...)
-#define log_warn(...)
-#define log_error(...)
-#define log_fatal(...)
-#endif
-
-void log_set_udata(void *udata);
+
+
void log_set_fp(FILE *fp);
void log_set_level(int level);
void log_set_quiet(int enable);
diff --git a/stats.h b/stats.h
deleted file mode 100644
index cf129b6..0000000
--- a/stats.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#define STAT_APPLY(XX)\
- XX(nfds_cnt)\
- XX(nfds_sum)\
- XX(nfds_max)\
- XX(yield_cnt)
-
-
-#define STAT_STRUCT_FN(name) size_t name;
-struct {
- STAT_APPLY(STAT_STRUCT_FN)
-} stats;
-
-
-#define STAT_PRINT_FN(name) printf ( #name ": %zu\n", stats. name);
-void report_stat () {
- STAT_APPLY(STAT_PRINT_FN);
-}
diff --git a/very_const.c b/very_const.c
deleted file mode 100644
index 7342034..0000000
--- a/very_const.c
+++ /dev/null
@@ -1,106 +0,0 @@
-#define _GNU_SOURCE
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-#include <aio.h>
-
-#include <sys/socket.h>
-#include <sys/epoll.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <sys/epoll.h>
-#include <jemalloc/jemalloc.h>
-
-#include "log.h"
-
-#define PORT 8080
-#define LISTEN_N 50
-#define EVENTS_N 50
-
-void die (const char *msg) {
- (void)msg;
- log_error (" %s", msg);
- log_error (" %s", strerror (errno));
- exit (EXIT_FAILURE);
-}
-
-
-#define assertfd(FD) if (FD < 0) die (#FD " is not a valid file descriptor")
-#define assert(EX) if (!(EX)) die (#EX " is false")
-
-const char resp[] =
- "HTTP/1.1 200 OK\r\n"
- "Content-Length: 25\r\n"
- "Content-Type: text/html\r\n"
- "Connection: close\r\n"
- "\r\n"
- "Hello from const server\r\n";
-
-void dostuff (int sock);
-
-int main () {
-
- int sockfd, newsockfd;
- unsigned clilen;
- struct sockaddr_in serv_addr, cli_addr;
- log_set_level (LOG_INFO);
-
-
- sockfd = socket(AF_INET, SOCK_STREAM, 0);
- assertfd (sockfd);
- int enable = 1;
- assert (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) >= 0);
-
- bzero((char *) &serv_addr, sizeof(serv_addr));
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_addr.s_addr = INADDR_ANY;
- serv_addr.sin_port = htons(PORT);
-
- assert (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) >= 0);
-
- struct epoll_event ev, events[EVENTS_N];
- int epollfd = epoll_create1 (0);
- ev.data.ptr = NULL;
- ev.events = EPOLLIN | EPOLLERR;
- assert (epoll_ctl (epollfd, EPOLL_CTL_ADD, sockfd, &ev) == 0);
-
- listen(sockfd, LISTEN_N);
- clilen = sizeof(cli_addr);
- for (;;) {
- /*int nfds = epoll_wait (epollfd, events, EVENTS_N, 3000);
- if (nfds == 0) {
- exit (EXIT_SUCCESS);
- }
- assert (nfds != -1);
- log_trace ("nfds: %d", nfds);
- for (int i = 0; i < nfds; ++i) {*/
- for (;;) { //if (events[i].data.ptr == NULL) {
- newsockfd = accept4(sockfd, (struct sockaddr *) &cli_addr, &clilen, SOCK_NONBLOCK);
- assertfd (newsockfd);
- log_trace ("new: %d", newsockfd);
-
- dostuff (newsockfd);
- //}
- //else {
- // die ("pffff");
- //}
- }
- }
- return 0;
-}
-
-ssize_t write_sock (int sock);
-
-void dostuff (int sock) {
- write_sock (sock);
- close (sock);
-}
-
-inline ssize_t write_sock (int sock) {
-
- return write (sock, resp, sizeof (resp) - 1);
-}