Ver Fonte

H2O: Use spinlocks for the cache (#5342)

Also do a minor clean-up.
Anton Kirilov há 5 anos atrás
pai
commit
4d65fc794a

+ 21 - 11
frameworks/C/h2o/h2o.dockerfile

@@ -9,26 +9,36 @@ RUN apt update && \
 
 ### Install mustache-c
 
-ENV MUSTACHE_C_BUILD_DIR=mustache-c
+ENV MUSTACHE_C_REVISION=c1948c599edfe48c6099ed70ab1d5911d8c3ddc8
+
+ENV MUSTACHE_C_BUILD_DIR=mustache-c-build
 ENV MUSTACHE_C_PREFIX=/opt/mustache-c
 
-RUN git clone "https://github.com/x86-64/mustache-c.git" "$MUSTACHE_C_BUILD_DIR" && \
+RUN mkdir -p "$MUSTACHE_C_BUILD_DIR" && \
     cd "$MUSTACHE_C_BUILD_DIR" && \
-    git checkout c1948c599edfe48c6099ed70ab1d5911d8c3ddc8 && \
+    wget -qO - "https://github.com/x86-64/mustache-c/archive/${MUSTACHE_C_REVISION}.tar.gz" | \
+    tar xz --strip-components=1 && \
     CFLAGS="-O3 -flto -march=native" ./autogen.sh --prefix="$MUSTACHE_C_PREFIX" && \
-    make -j "$(nproc)" install
+    make -j "$(nproc)" install && \
+    cd .. && \
+    rm -rf "$MUSTACHE_C_BUILD_DIR"
 
 ### Install h2o
 
-ENV H2O_VERSION=2.2.6
-ENV H2O_ARCHIVE="v${H2O_VERSION}.tar.gz"
+ENV H2O_VERSION=v2.2.6
+
+ENV H2O_BUILD_DIR=h2o-build
 ENV H2O_PREFIX=/opt/h2o
 
-RUN wget -qO "$H2O_ARCHIVE" "https://github.com/h2o/h2o/archive/$H2O_ARCHIVE" && \
-    tar xf "$H2O_ARCHIVE" && \
-    cd "h2o-$H2O_VERSION" && \
+RUN mkdir -p "${H2O_BUILD_DIR}/build" && \
+    cd "$H2O_BUILD_DIR" && \
+    wget -qO - "https://github.com/h2o/h2o/archive/${H2O_VERSION}.tar.gz" | \
+    tar xz --strip-components=1 && \
+    cd build && \
     cmake -DCMAKE_INSTALL_PREFIX="$H2O_PREFIX" -DCMAKE_C_FLAGS="-flto -march=native" \
-          -DCMAKE_AR=/usr/bin/gcc-ar -DCMAKE_RANLIB=/usr/bin/gcc-ranlib . && \
-    make -j "$(nproc)" install
+          -DCMAKE_AR=/usr/bin/gcc-ar -DCMAKE_RANLIB=/usr/bin/gcc-ranlib .. && \
+    make -j "$(nproc)" install && \
+    cd ../.. && \
+    rm -rf "$H2O_BUILD_DIR"
 
 CMD ["./h2o.sh"]

+ 13 - 25
frameworks/C/h2o/src/cache.c

@@ -50,44 +50,32 @@ int cache_create(size_t concurrency,
 	cache->cache_num = CONCURRENCY_FACTOR * round_up_to_power_of_2(concurrency);
 	cache->cache_num = MAX(cache->cache_num, 1);
 	capacity = (capacity + cache->cache_num - 1) / cache->cache_num;
-
-	pthread_mutexattr_t attr;
-
-	if (pthread_mutexattr_init(&attr))
-		return 1;
-
-	if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP))
-		goto error;
-
 	cache->cache = malloc(cache->cache_num * sizeof(*cache->cache));
 
 	if (!cache->cache)
-		goto error;
+		return 1;
 
 	cache->cache_lock = malloc(cache->cache_num * sizeof(*cache->cache_lock));
 
 	if (!cache->cache_lock)
-		goto error_malloc;
+		goto error;
 
 	for (size_t i = 0; i < cache->cache_num; i++) {
 		cache->cache[i] = h2o_cache_create(0, capacity, duration, destroy_cb);
 
-		if (!cache->cache[i] || pthread_mutex_init(cache->cache_lock + i, &attr)) {
+		if (!cache->cache[i] || pthread_spin_init(cache->cache_lock + i, PTHREAD_PROCESS_PRIVATE)) {
 			if (cache->cache[i])
 				h2o_cache_destroy(cache->cache[i]);
 
 			cache->cache_num = i;
 			cache_destroy(cache);
-			goto error;
+			return 1;
 		}
 	}
 
-	pthread_mutexattr_destroy(&attr);
 	return 0;
-error_malloc:
-	free(cache->cache);
 error:
-	pthread_mutexattr_destroy(&attr);
+	free(cache->cache);
 	return 1;
 }
 
@@ -98,11 +86,11 @@ void cache_destroy(cache_t *cache)
 
 		for (size_t i = 0; i < cache->cache_num; i++) {
 			h2o_cache_destroy(cache->cache[i]);
-			pthread_mutex_destroy(cache->cache_lock + i);
+			pthread_spin_destroy(cache->cache_lock + i);
 		}
 
 		free(cache->cache);
-		free(cache->cache_lock);
+		free((void *) cache->cache_lock);
 		cache->cache = NULL;
 		cache->cache_lock = NULL;
 	}
@@ -119,13 +107,13 @@ h2o_cache_ref_t *cache_fetch(cache_t *cache,
 		keyhash = h2o_cache_calchash(key.base, key.len);
 
 	const size_t idx = get_index(cache->cache_num, keyhash);
-	pthread_mutex_t * const mutex = cache->cache_lock + idx;
+	pthread_spinlock_t * const lock = cache->cache_lock + idx;
 
-	CHECK_ERROR(pthread_mutex_lock, mutex);
+	CHECK_ERROR(pthread_spin_lock, lock);
 
 	h2o_cache_ref_t * const ret = h2o_cache_fetch(cache->cache[idx], now, key, keyhash);
 
-	CHECK_ERROR(pthread_mutex_unlock, mutex);
+	CHECK_ERROR(pthread_spin_unlock, lock);
 	return ret;
 }
 
@@ -149,12 +137,12 @@ int cache_set(uint64_t now,
 		keyhash = h2o_cache_calchash(key.base, key.len);
 
 	const size_t idx = get_index(cache->cache_num, keyhash);
-	pthread_mutex_t * const mutex = cache->cache_lock + idx;
+	pthread_spinlock_t * const lock = cache->cache_lock + idx;
 
-	CHECK_ERROR(pthread_mutex_lock, mutex);
+	CHECK_ERROR(pthread_spin_lock, lock);
 
 	const int ret = h2o_cache_set(cache->cache[idx], now, key, keyhash, value);
 
-	CHECK_ERROR(pthread_mutex_unlock, mutex);
+	CHECK_ERROR(pthread_spin_unlock, lock);
 	return ret;
 }

+ 1 - 1
frameworks/C/h2o/src/cache.h

@@ -27,7 +27,7 @@
 
 typedef struct {
 	h2o_cache_t **cache;
-	pthread_mutex_t *cache_lock;
+	pthread_spinlock_t *cache_lock;
 	size_t cache_num;
 } cache_t;
 

+ 0 - 3
frameworks/C/h2o/src/global_data.h

@@ -22,12 +22,9 @@
 #define GLOBAL_DATA_H_
 
 #include <h2o.h>
-#include <stdbool.h>
 #include <stdint.h>
-#include <h2o/cache.h>
 #include <openssl/ssl.h>
 
-#include "cache.h"
 #include "list.h"
 #include "handlers/request_handler_data.h"