Skip to content

Commit

Permalink
Support memcached
Browse files Browse the repository at this point in the history
  • Loading branch information
eecheng87 committed Jun 9, 2022
1 parent e72f8e0 commit ae3058b
Show file tree
Hide file tree
Showing 11 changed files with 180 additions and 5 deletions.
37 changes: 37 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@ REDIS_ZIP_NAME := 7.0-rc2
REDIS_PATH := downloads/$(REDIS_NAME)
REDIS := redis

MEMCACHED_SOURCE := http://www.memcached.org/files/memcached-1.6.15.tar.gz
MEMCACHED_NAME := memcached-1.6.15
MEMCACHED_ZIP_NAME := memcached-1.6.15
MEMCACHED_PATH := downloads/$(MEMCACHED_NAME)
MEMCACHED := memcached

LIBEVENT_SOURCE := https://github.com/libevent/libevent/archive/refs/tags/release-2.1.12-stable.tar.gz
LIBEVENT_NAME := libevent-release-2.1.12-stable
LIBEVENT_ZIP_NAME := release-2.1.12-stable
LIBEVENT_PATH := downloads/$(LIBEVENT_NAME)
LIBEVENT := libevent

LIBDUMMY_PATH := $(shell find $(shell pwd) -type f -name "libdummy.so") | sed 's_/_\\/_g'
PWD := $(shell pwd)
OUT := downloads
Expand Down Expand Up @@ -89,6 +101,29 @@ $(REDIS):
cd $(OUT) && patch -p1 < ../patches/redis_network.patch && patch -p1 < ../patches/redis_server.patch
cd $(REDIS_PATH) && make -j$(nproc)

$(LIBEVENT):
@echo "download libevent..."
wget $(LIBEVENT_SOURCE) --no-check-certificate
mkdir -p $(LIBEVENT_PATH)
tar -zxvf $(LIBEVENT_ZIP_NAME).tar.gz -C $(OUT)
rm $(LIBEVENT_ZIP_NAME).tar.gz
cd $(LIBEVENT_PATH) && mkdir -p local && ./autogen.sh && ./configure --prefix=$(PWD)/$(LIBEVENT_PATH)/local
cd $(OUT) && patch -p1 < ../patches/libevent.patch


$(MEMCACHED): $(LIBEVENT)
@echo "download memcached..."
wget $(MEMCACHED_SOURCE)
mkdir -p $(MEMCACHED_PATH)
tar -zxvf $(MEMCACHED_ZIP_NAME).tar.gz -C $(OUT)
rm $(MEMCACHED_ZIP_NAME).tar.gz
cd $(MEMCACHED_PATH) && mkdir -p local && ./configure --prefix=$(PWD)/$(MEMCACHED_PATH)/local
cd $(OUT) && patch -p1 < ../patches/memcached.patch
scripts/libevent.sh $(LIBEVENT_PATH)
cd $(LIBEVENT_PATH) && make -j$(nproc) && sudo make install
scripts/memcached.sh $(MEMCACHED_PATH)
cd $(MEMCACHED_PATH) && make -j$(nproc)

test-nginx-perf:
./$(NGX_PATH)/objs/nginx

Expand Down Expand Up @@ -119,6 +154,8 @@ else ifeq ($(strip $(TARGET)),redis)
TARGET = redis
else ifeq ($(strip $(TARGET)),echo)
TARGET = echo
else ifeq ($(strip $(TARGET)),mcached)
TARGET = mcached
endif

# set configuration flag of Nginx
Expand Down
3 changes: 2 additions & 1 deletion module/include/aarch64_syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
#define __ESCA_shutdown 210
#define __ESCA_close 57
#define __ESCA_write 64
#define __ESCA_sendto 206
#define __ESCA_sendto 206
#define __ESCA_sendmsg 211
2 changes: 1 addition & 1 deletion module/include/esca.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#include <stdatomic.h>

#define DEFAULT_CONFIG_PATH ""
#define DEFAULT_CONFIG_PATH "/home/eecheng/SAIO/esca.conf"
#define CONFIG_ARG_MAX_BYTES 128

/* Limit */
Expand Down
3 changes: 2 additions & 1 deletion module/include/x86_syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
#define __ESCA_shutdown 48
#define __ESCA_close 3
#define __ESCA_write 1
#define __ESCA_sendto 44
#define __ESCA_sendto 44
#define __ESCA_sendmsg 46
19 changes: 19 additions & 0 deletions patches/libevent.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
--- old/libevent-release-2.1.12-stable/event.c 2022-06-09 01:52:06.746406656 +0000
+++ new/libevent-release-2.1.12-stable/event.c 2022-06-09 01:51:04.594620903 +0000
@@ -1639,7 +1639,7 @@
int count = 0;

EVUTIL_ASSERT(activeq != NULL);
-
+batch_start();
for (evcb = TAILQ_FIRST(activeq); evcb; evcb = TAILQ_FIRST(activeq)) {
struct event *ev=NULL;
if (evcb->evcb_flags & EVLIST_INIT) {
@@ -1747,6 +1747,7 @@
if (base->event_continue)
break;
}
+batch_flush();
return count;
}

20 changes: 20 additions & 0 deletions patches/memcached.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--- old/memcached-1.6.15/thread.c 2022-06-09 01:59:43.605398261 +0000
+++ new/memcached-1.6.15/thread.c 2022-06-09 02:01:16.581275340 +0000
@@ -497,6 +497,8 @@
/*
* Worker thread: main event loop
*/
+extern void init_worker(int);
+int worker_index = 0;
static void *worker_libevent(void *arg) {
LIBEVENT_THREAD *me = arg;

@@ -514,7 +516,7 @@
}

register_thread_initialized();
-
+ init_worker(worker_index++);
event_base_loop(me->base, 0);

// same mechanism used to watch for all threads exiting.
8 changes: 8 additions & 0 deletions scripts/libevent.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash

lib_saio_dir=$(find $(pwd) -type d -name "wrapper" | sed 's_/_\\/_g')
libpath=$1

# modify libevent
sed -i "s/LDFLAGS =.*/& -Wl,-rpath -Wl,${lib_saio_dir}/" ${libpath}/Makefile
sed -i "s/LIBS =.*/& -L${lib_saio_dir} -ldummy/" ${libpath}/Makefile
10 changes: 10 additions & 0 deletions scripts/memcached.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash

lib_saio_dir=$(find $(pwd) -type d -name "wrapper" | sed 's_/_\\/_g')
libevent_dir=$(find $(pwd) -type d -path "*/local/lib" | sed 's_/_\\/_g')
mempath=$1

# modify memcached
sed -i "s/LDFLAGS =.*/& -Wl,-rpath -Wl,${lib_saio_dir}/" ${mempath}/Makefile
sed -i "s/LDFLAGS =.*/& -Wl,-rpath -Wl,${libevent_dir}/" ${mempath}/Makefile
sed -i "s/LIBS =.*/& -L${lib_saio_dir} -ldummy/" ${mempath}/Makefile
65 changes: 65 additions & 0 deletions wrapper/mcached.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
ssize_t sendmsg(int sockfd, const struct msghdr* msg, int flags)
{
if (!in_segment) {
return real_sendmsg(sockfd, msg, flags);
}

int idx = this_worker_id * RATIO + (sockfd % RATIO);
batch_num++;

int i = table[idx]->tail_table;
int j = table[idx]->tail_entry;

/* check out of bound */
msg_offset = msg_offset & MSG_MASK;
iov_offset = iov_offset & IOV_MASK;

int res = 0;
struct iovec* iov = msg->msg_iov;
int iovlen = msg->msg_iovlen, start_iov_offset = iov_offset;

for (int k = 0; k < iovlen; k++) {
int ll = iov[k].iov_len; // number of bytes

/* handle string */
if (pool_offset + (ull)(ll) > MAX_POOL_SIZE)
pool_offset = 0;

memcpy((void*)((unsigned char*)mpool + pool_offset), iov[k].iov_base, ll);

iov_offset = iov_offset & IOV_MASK;
iovpool[iov_offset].iov_base = (void*)((unsigned char*)mpool + pool_offset);
iovpool[iov_offset].iov_len = ll;

/* update index of iovec array */
iov_offset++;

/* update offset of character pool */
pool_offset += (size_t)(ll);

res += ll;
}

/* copy msghdr */
msgpool[msg_offset].msg_name = NULL; // FIXME: should be more general
msgpool[msg_offset].msg_namelen = 0;
msgpool[msg_offset].msg_iov = (struct iovec*)(&iovpool[start_iov_offset]);
msgpool[msg_offset].msg_iovlen = iovlen;
msgpool[msg_offset].msg_control = NULL;
msgpool[msg_offset].msg_controllen = 0;
msgpool[msg_offset].msg_flags = msg->msg_flags;

table[idx]->user_tables[i][j].sysnum = __ESCA_sendmsg;
table[idx]->user_tables[i][j].nargs = 3;
table[idx]->user_tables[i][j].args[0] = sockfd;
table[idx]->user_tables[i][j].args[1] = (long)(&msgpool[msg_offset]);
table[idx]->user_tables[i][j].args[2] = flags;

msg_offset++;
update_index(idx);

esca_smp_store_release(&table[idx]->user_tables[i][j].rstatus, BENTRY_BUSY);

/* assume success */
return res;
}
7 changes: 6 additions & 1 deletion wrapper/preload.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ int syscall_num; /* number of syscall triggered currently */
size_t pgsize;

void* mpool; /* memory pool */
ull pool_offset;
struct iovec* iovpool; /* pool for iovector */
struct msghdr* msgpool; /* pool for msgpool */
ull pool_offset;
ull iov_offset;
ull msg_offset;

/* Global configurable variable */
int ESCA_LOCALIZE;
Expand Down Expand Up @@ -78,6 +80,8 @@ void init_worker(int idx)
pool_offset = 0;
iovpool = (struct iovec*)malloc(sizeof(struct iovec) * MAX_POOL_IOV_SIZE);
iov_offset = 0;
msgpool = (struct msghdr*)malloc(sizeof(struct msghdr) * MAX_POOL_MSG_SIZE);
msg_offset = 0;

init_worker_exit:
return;
Expand Down Expand Up @@ -170,6 +174,7 @@ __attribute__((constructor)) static void setup(void)
real_writev = real_writev ? real_writev : dlsym(RTLD_NEXT, "writev");
real_shutdown = real_shutdown ? real_shutdown : dlsym(RTLD_NEXT, "shutdown");
real_sendfile = real_sendfile ? real_sendfile : dlsym(RTLD_NEXT, "sendfile");
real_sendmsg = real_sendmsg ? real_sendmsg : dlsym(RTLD_NEXT, "sendmsg");

/* configuration */
config = malloc(sizeof(esca_config_t));
Expand Down
11 changes: 10 additions & 1 deletion wrapper/preload.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
#define DEPLOY_TAGET 1
#define MAX_TABLE_SIZE 64
#define MAX_POOL_SIZE 900000000
#define MAX_POOL_IOV_SIZE 1000

/* optimize: order two */
#define MAX_POOL_IOV_SIZE 1024
#define MAX_POOL_MSG_SIZE 1024
#define IOV_MASK (MAX_POOL_IOV_SIZE - 1)
#define MSG_MASK (MAX_POOL_MSG_SIZE - 1)
#define POOL_UNIT 8

#include "../module/include/esca.h"
Expand All @@ -15,7 +20,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <time.h>

Expand All @@ -35,3 +42,5 @@ typedef long (*shutdown_t)(int fd, int how);
shutdown_t real_shutdown;
typedef long (*sendfile_t)(int out_fd, int in_fd, off_t* offset, size_t count);
sendfile_t real_sendfile;
typedef long (*sendmsg_t)(int sockfd, const struct msghdr* msg, int flags);
sendmsg_t real_sendmsg;

0 comments on commit ae3058b

Please sign in to comment.