# sources
SRCS = client.c loader.c objects.c pooler.c proto.c sbuf.c server.c util.c \
- admin.c stats.c takeover.c md5.c janitor.c pktbuf.c system.c main.c \
- varcache.c slab.c
+ admin.c stats.c takeover.c janitor.c pktbuf.c system.c main.c \
+ varcache.c
HDRS = client.h loader.h objects.h pooler.h proto.h sbuf.h server.h util.h \
- admin.h stats.h takeover.h md5.h janitor.h pktbuf.h system.h bouncer.h \
- mbuf.h varcache.h slab.h iobuf.h
+ admin.h stats.h takeover.h janitor.h pktbuf.h system.h bouncer.h \
+ mbuf.h varcache.h iobuf.h
# data & dirs to include in tgz
DOCS = doc/overview.txt doc/usage.txt doc/config.txt doc/todo.txt
#include <usual/logging.h>
#include <usual/aatree.h>
#include <usual/lookup3.h>
+#include <usual/slab.h>
#include <event.h>
#include "sbuf.h"
#include "pktbuf.h"
#include "varcache.h"
-#include "slab.h"
#include "admin.h"
#include "loader.h"
+++ /dev/null
-/*
- * MD5 implementation based on RFC1321.
- *
- * Copyright (c) 2008 Marko Kreen, Skype Technologies OÜ
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef __MD5_H__
-#define __MD5_H__
-
-#define MD5_BLOCK_LENGTH 64
-#define MD5_DIGEST_LENGTH 16
-
-struct md5_ctx {
- uint64_t nbytes;
- uint32_t a, b, c, d;
- uint32_t buf[16];
-};
-
-void md5_reset(struct md5_ctx *ctx);
-void md5_update(struct md5_ctx *ctx, const void *data, unsigned int len);
-void md5_final(uint8_t *dst, struct md5_ctx *ctx);
-
-#ifndef AVOID_MD5_COMPAT
-typedef struct md5_ctx MD5_CTX;
-#define MD5_Init(c) md5_reset(c)
-#define MD5_Update(c, d, l) md5_update(c, d, l)
-#define MD5_Final(d, c) md5_final(d, c)
-#endif
-
-#endif
-
extern struct StatList database_list;
extern struct StatList autodatabase_idle_list;
extern struct StatList login_client_list;
-extern ObjectCache *client_cache;
-extern ObjectCache *server_cache;
-extern ObjectCache *db_cache;
-extern ObjectCache *pool_cache;
-extern ObjectCache *user_cache;
-extern ObjectCache *iobuf_cache;
+extern struct Slab *client_cache;
+extern struct Slab *server_cache;
+extern struct Slab *db_cache;
+extern struct Slab *pool_cache;
+extern struct Slab *user_cache;
+extern struct Slab *iobuf_cache;
PgDatabase *find_database(const char *name);
PgUser *find_user(const char *name);
+++ /dev/null
-
-typedef struct ObjectCache ObjectCache;
-
-typedef void (*obj_init_fn)(void *obj);
-
-ObjectCache *objcache_create(const char *name, unsigned obj_size, unsigned align,
- obj_init_fn init_func);
-void objcache_destroy(ObjectCache *cache);
-
-void * obj_alloc(ObjectCache *cache) _MALLOC _MUSTCHECK;
-void obj_free(ObjectCache *cache, void *obj);
-
-int objcache_total_count(const ObjectCache *cache);
-int objcache_free_count(const ObjectCache *cache);
-int objcache_active_count(const ObjectCache *cache);
-
-typedef void (*slab_stat_fn)(void *arg, const char *slab_name,
- unsigned size, unsigned free,
- unsigned total);
-void objcache_stats(slab_stat_fn fn, void *arg);
-
SENDLIST("databases", statlist_count(&database_list));
SENDLIST("users", statlist_count(&user_list));
SENDLIST("pools", statlist_count(&pool_list));
- SENDLIST("free_clients", objcache_free_count(client_cache));
- SENDLIST("used_clients", objcache_active_count(client_cache));
+ SENDLIST("free_clients", slab_free_count(client_cache));
+ SENDLIST("used_clients", slab_active_count(client_cache));
SENDLIST("login_clients", statlist_count(&login_client_list));
- SENDLIST("free_servers", objcache_free_count(server_cache));
- SENDLIST("used_servers", objcache_active_count(server_cache));
+ SENDLIST("free_servers", slab_free_count(server_cache));
+ SENDLIST("used_servers", slab_active_count(server_cache));
admin_flush(admin, buf, "SHOW");
return true;
}
}
pktbuf_write_RowDescription(buf, "siiii", "name",
"size", "used", "free", "memtotal");
- objcache_stats(slab_stat_cb, buf);
+ slab_stats(slab_stat_cb, buf);
admin_flush(admin, buf, "SHOW");
return true;
}
list_del(&pool->map_head);
statlist_remove(&pool_list, &pool->head);
- obj_free(pool_cache, pool);
+ slab_free(pool_cache, pool);
}
static void kill_database(PgDatabase *db)
kill_pool(pool);
}
if (db->forced_user)
- obj_free(user_cache, db->forced_user);
+ slab_free(user_cache, db->forced_user);
if (db->connect_query)
free((void *)db->connect_query);
if (db->inactive_time)
statlist_remove(&autodatabase_idle_list, &db->head);
else
statlist_remove(&database_list, &db->head);
- obj_free(db_cache, db);
+ slab_free(db_cache, db);
}
/* as [pgbouncer] section can be loaded after databases,
+++ /dev/null
-/*
- * MD5 implementation based on RFC1321.
- *
- * Copyright (c) 2008 Marko Kreen, Skype Technologies OÜ
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "system.h"
-#include "md5.h"
-
-/*
- * Support functions.
- */
-
-#define bufpos(ctx) ((ctx)->nbytes & (MD5_BLOCK_LENGTH - 1))
-
-static inline uint32_t rol(uint32_t v, int s)
-{
- return (v << s) | (v >> (32 - s));
-}
-
-static inline void swap_words(uint32_t *w, int n)
-{
-#ifdef WORDS_BIGENDIAN
- for (; n > 0; w++, n--) {
- uint32_t v = rol(*w, 16);
- *w = ((v >> 8) & 0x00FF00FF) | ((v << 8) & 0xFF00FF00);
- }
-#endif
-}
-
-static inline void put_word(uint8_t *dst, uint32_t val)
-{
-#ifdef WORDS_BIGENDIAN
- dst[0] = val;
- dst[1] = val >> 8;
- dst[2] = val >> 16;
- dst[3] = val >> 24;
-#else
- memcpy(dst, &val, 4);
-#endif
-}
-
-/*
- * MD5 core.
- */
-
-#define F(X,Y,Z) ((X & Y) | ((~X) & Z))
-#define G(X,Y,Z) ((X & Z) | (Y & (~Z)))
-#define H(X,Y,Z) (X ^ Y ^ Z)
-#define I(X,Y,Z) (Y ^ (X | (~Z)))
-
-#define OP(fn, a, b, c, d, k, s, T_i) \
- a = b + rol(a + fn(b, c, d) + X[k] + T_i, s)
-
-static void md5_mix(struct md5_ctx *ctx, const uint32_t *X)
-{
- uint32_t a, b, c, d;
-
- a = ctx->a;
- b = ctx->b;
- c = ctx->c;
- d = ctx->d;
-
- /* Round 1. */
- OP(F, a, b, c, d, 0, 7, 0xd76aa478);
- OP(F, d, a, b, c, 1, 12, 0xe8c7b756);
- OP(F, c, d, a, b, 2, 17, 0x242070db);
- OP(F, b, c, d, a, 3, 22, 0xc1bdceee);
- OP(F, a, b, c, d, 4, 7, 0xf57c0faf);
- OP(F, d, a, b, c, 5, 12, 0x4787c62a);
- OP(F, c, d, a, b, 6, 17, 0xa8304613);
- OP(F, b, c, d, a, 7, 22, 0xfd469501);
- OP(F, a, b, c, d, 8, 7, 0x698098d8);
- OP(F, d, a, b, c, 9, 12, 0x8b44f7af);
- OP(F, c, d, a, b, 10, 17, 0xffff5bb1);
- OP(F, b, c, d, a, 11, 22, 0x895cd7be);
- OP(F, a, b, c, d, 12, 7, 0x6b901122);
- OP(F, d, a, b, c, 13, 12, 0xfd987193);
- OP(F, c, d, a, b, 14, 17, 0xa679438e);
- OP(F, b, c, d, a, 15, 22, 0x49b40821);
-
- /* Round 2. */
- OP(G, a, b, c, d, 1, 5, 0xf61e2562);
- OP(G, d, a, b, c, 6, 9, 0xc040b340);
- OP(G, c, d, a, b, 11, 14, 0x265e5a51);
- OP(G, b, c, d, a, 0, 20, 0xe9b6c7aa);
- OP(G, a, b, c, d, 5, 5, 0xd62f105d);
- OP(G, d, a, b, c, 10, 9, 0x02441453);
- OP(G, c, d, a, b, 15, 14, 0xd8a1e681);
- OP(G, b, c, d, a, 4, 20, 0xe7d3fbc8);
- OP(G, a, b, c, d, 9, 5, 0x21e1cde6);
- OP(G, d, a, b, c, 14, 9, 0xc33707d6);
- OP(G, c, d, a, b, 3, 14, 0xf4d50d87);
- OP(G, b, c, d, a, 8, 20, 0x455a14ed);
- OP(G, a, b, c, d, 13, 5, 0xa9e3e905);
- OP(G, d, a, b, c, 2, 9, 0xfcefa3f8);
- OP(G, c, d, a, b, 7, 14, 0x676f02d9);
- OP(G, b, c, d, a, 12, 20, 0x8d2a4c8a);
-
- /* Round 3. */
- OP(H, a, b, c, d, 5, 4, 0xfffa3942);
- OP(H, d, a, b, c, 8, 11, 0x8771f681);
- OP(H, c, d, a, b, 11, 16, 0x6d9d6122);
- OP(H, b, c, d, a, 14, 23, 0xfde5380c);
- OP(H, a, b, c, d, 1, 4, 0xa4beea44);
- OP(H, d, a, b, c, 4, 11, 0x4bdecfa9);
- OP(H, c, d, a, b, 7, 16, 0xf6bb4b60);
- OP(H, b, c, d, a, 10, 23, 0xbebfbc70);
- OP(H, a, b, c, d, 13, 4, 0x289b7ec6);
- OP(H, d, a, b, c, 0, 11, 0xeaa127fa);
- OP(H, c, d, a, b, 3, 16, 0xd4ef3085);
- OP(H, b, c, d, a, 6, 23, 0x04881d05);
- OP(H, a, b, c, d, 9, 4, 0xd9d4d039);
- OP(H, d, a, b, c, 12, 11, 0xe6db99e5);
- OP(H, c, d, a, b, 15, 16, 0x1fa27cf8);
- OP(H, b, c, d, a, 2, 23, 0xc4ac5665);
-
- /* Round 4. */
- OP(I, a, b, c, d, 0, 6, 0xf4292244);
- OP(I, d, a, b, c, 7, 10, 0x432aff97);
- OP(I, c, d, a, b, 14, 15, 0xab9423a7);
- OP(I, b, c, d, a, 5, 21, 0xfc93a039);
- OP(I, a, b, c, d, 12, 6, 0x655b59c3);
- OP(I, d, a, b, c, 3, 10, 0x8f0ccc92);
- OP(I, c, d, a, b, 10, 15, 0xffeff47d);
- OP(I, b, c, d, a, 1, 21, 0x85845dd1);
- OP(I, a, b, c, d, 8, 6, 0x6fa87e4f);
- OP(I, d, a, b, c, 15, 10, 0xfe2ce6e0);
- OP(I, c, d, a, b, 6, 15, 0xa3014314);
- OP(I, b, c, d, a, 13, 21, 0x4e0811a1);
- OP(I, a, b, c, d, 4, 6, 0xf7537e82);
- OP(I, d, a, b, c, 11, 10, 0xbd3af235);
- OP(I, c, d, a, b, 2, 15, 0x2ad7d2bb);
- OP(I, b, c, d, a, 9, 21, 0xeb86d391);
-
- ctx->a += a;
- ctx->b += b;
- ctx->c += c;
- ctx->d += d;
-}
-
-/*
- * Public API.
- */
-
-void md5_reset(struct md5_ctx *ctx)
-{
- ctx->nbytes = 0;
- ctx->a = 0x67452301;
- ctx->b = 0xefcdab89;
- ctx->c = 0x98badcfe;
- ctx->d = 0x10325476;
-}
-
-void md5_update(struct md5_ctx *ctx, const void *data, unsigned int len)
-{
- unsigned int n;
- const uint8_t *ptr = data;
- uint8_t *buf = (uint8_t *)ctx->buf;
-
- while (len > 0) {
- n = MD5_BLOCK_LENGTH - bufpos(ctx);
- if (n > len)
- n = len;
- memcpy(buf + bufpos(ctx), ptr, n);
- ptr += n;
- len -= n;
- ctx->nbytes += n;
- if (bufpos(ctx) == 0) {
- swap_words(ctx->buf, 16);
- md5_mix(ctx, ctx->buf);
- }
- }
-}
-
-void md5_final(uint8_t *dst, struct md5_ctx *ctx)
-{
- static const uint8_t padding[MD5_BLOCK_LENGTH] = { 0x80 };
- uint64_t final_len = ctx->nbytes * 8;
- int pad_len, pos = bufpos(ctx);
-
- /* add padding */
- pad_len = MD5_BLOCK_LENGTH - 8 - pos;
- if (pad_len <= 0)
- pad_len += MD5_BLOCK_LENGTH;
- md5_update(ctx, padding, pad_len);
-
- /* add length directly */
- swap_words(ctx->buf, 14);
- ctx->buf[14] = final_len;
- ctx->buf[15] = final_len >> 32;
-
- /* final result */
- md5_mix(ctx, ctx->buf);
- put_word(dst, ctx->a);
- put_word(dst + 4, ctx->b);
- put_word(dst + 8, ctx->c);
- put_word(dst + 12, ctx->d);
-}
-
*/
STATLIST(login_client_list);
-ObjectCache *server_cache;
-ObjectCache *client_cache;
-ObjectCache *db_cache;
-ObjectCache *pool_cache;
-ObjectCache *user_cache;
-ObjectCache *iobuf_cache;
+struct Slab *server_cache;
+struct Slab *client_cache;
+struct Slab *db_cache;
+struct Slab *pool_cache;
+struct Slab *user_cache;
+struct Slab *iobuf_cache;
/*
* libevent may still report events when event_del()
/* fast way to get number of active clients */
int get_active_client_count(void)
{
- return objcache_active_count(client_cache);
+ return slab_active_count(client_cache);
}
/* fast way to get number of active servers */
int get_active_server_count(void)
{
- return objcache_active_count(server_cache);
+ return slab_active_count(server_cache);
}
static void construct_client(void *obj)
void init_objects(void)
{
aatree_init(&user_tree, user_node_cmp, NULL);
- user_cache = objcache_create("user_cache", sizeof(PgUser), 0, NULL);
- db_cache = objcache_create("db_cache", sizeof(PgDatabase), 0, NULL);
- pool_cache = objcache_create("pool_cache", sizeof(PgPool), 0, NULL);
+ user_cache = slab_create("user_cache", sizeof(PgUser), 0, NULL);
+ db_cache = slab_create("db_cache", sizeof(PgDatabase), 0, NULL);
+ pool_cache = slab_create("pool_cache", sizeof(PgPool), 0, NULL);
if (!user_cache || !db_cache || !pool_cache)
fatal("cannot create initial caches");
/* initialization after config loading */
void init_caches(void)
{
- server_cache = objcache_create("server_cache", sizeof(PgSocket), 0, construct_server);
- client_cache = objcache_create("client_cache", sizeof(PgSocket), 0, construct_client);
- iobuf_cache = objcache_create("iobuf_cache", IOBUF_SIZE, 0, do_iobuf_reset);
+ server_cache = slab_create("server_cache", sizeof(PgSocket), 0, construct_server);
+ client_cache = slab_create("client_cache", sizeof(PgSocket), 0, construct_client);
+ iobuf_cache = slab_create("iobuf_cache", IOBUF_SIZE, 0, do_iobuf_reset);
}
/* state change means moving between lists */
/* put to new location */
switch (client->state) {
case CL_FREE:
- obj_free(client_cache, client);
+ slab_free(client_cache, client);
break;
case CL_JUSTFREE:
statlist_append(&justfree_client_list, &client->head);
/* put to new location */
switch (server->state) {
case SV_FREE:
- obj_free(server_cache, server);
+ slab_free(server_cache, server);
break;
case SV_JUSTFREE:
statlist_append(&justfree_server_list, &server->head);
/* create new object if needed */
if (db == NULL) {
- db = obj_alloc(db_cache);
+ db = slab_alloc(db_cache);
if (!db)
return NULL;
PgUser *user = find_user(name);
if (user == NULL) {
- user = obj_alloc(user_cache);
+ user = slab_alloc(user_cache);
if (!user)
return NULL;
{
PgUser *user = db->forced_user;
if (!user) {
- user = obj_alloc(user_cache);
+ user = slab_alloc(user_cache);
if (!user)
return NULL;
list_init(&user->head);
{
PgPool *pool;
- pool = obj_alloc(pool_cache);
+ pool = slab_alloc(pool_cache);
if (!pool)
return NULL;
allow_new:
/* get free conn object */
- server = obj_alloc(server_cache);
+ server = slab_alloc(server_cache);
if (!server) {
log_debug("launch_new_connection: no memory");
return;
PgSocket *client;
/* get free PgSocket */
- client = obj_alloc(client_cache);
+ client = slab_alloc(client_cache);
if (!client) {
log_warning("cannot allocate client struct");
safe_close(sock);
if (!pool)
return false;
- server = obj_alloc(server_cache);
+ server = slab_alloc(server_cache);
if (!server)
return false;
sbuf->pkt_remain = 0;
sbuf->pkt_action = sbuf->wait_type = 0;
if (sbuf->io) {
- obj_free(iobuf_cache, sbuf->io);
+ slab_free(iobuf_cache, sbuf->io);
sbuf->io = NULL;
}
return true;
return;
if (release && iobuf_empty(io)) {
- obj_free(iobuf_cache, io);
+ slab_free(iobuf_cache, io);
sbuf->io = NULL;
} else
iobuf_try_resync(io, SBUF_SMALL_PKT);
static bool allocate_iobuf(SBuf *sbuf)
{
if (sbuf->io == NULL) {
- sbuf->io = obj_alloc(iobuf_cache);
+ sbuf->io = slab_alloc(iobuf_cache);
if (sbuf->io == NULL) {
sbuf_call_proto(sbuf, SBUF_EV_RECV_FAILED);
return false;
+++ /dev/null
-/*
- * PgBouncer - Lightweight connection pooler for PostgreSQL.
- *
- * Copyright (c) 2007-2009 Marko Kreen, Skype Technologies OÜ
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * Primitive slab allocator.
- *
- * - On each alloc initializer is called.
- * - if init func is not given, memset() is done
- */
-
-#include <sys/param.h>
-
-#include "bouncer.h"
-
-/*
- * Store for pre-initialized objects of one type.
- */
-struct ObjectCache {
- struct List head;
- struct StatList freelist;
- struct StatList slablist;
- char name[32];
- unsigned final_size;
- unsigned total_count;
- obj_init_fn init_func;
-};
-
-/*
- * Header for each slab.
- */
-struct Slab {
- struct List head;
-};
-
-/* keep track of all caches */
-static STATLIST(objcache_list);
-
-/* cache for cache headers */
-static ObjectCache *objcache_cache = NULL;
-
-/* fill struct contents */
-static void init_objcache(ObjectCache *cache,
- const char *name,
- unsigned obj_size,
- unsigned align,
- obj_init_fn init_func)
-{
- list_init(&cache->head);
- statlist_init(&cache->freelist, name);
- statlist_init(&cache->slablist, name);
- safe_strcpy(cache->name, name, sizeof(cache->name));
- cache->total_count = 0;
- cache->init_func = init_func;
- statlist_append(&objcache_list, &cache->head);
-
- if (align == 0)
- cache->final_size = ALIGN(obj_size);
- else
- cache->final_size = CUSTOM_ALIGN(obj_size, align);
-
- log_noise("new cache: %s, size=%u", name, cache->final_size);
-}
-
-/* make new cache */
-ObjectCache * objcache_create(const char *name,
- unsigned obj_size,
- unsigned align,
- obj_init_fn init_func)
-{
- ObjectCache *cache;
-
- /* main cache */
- if (!objcache_cache) {
- objcache_cache = malloc(sizeof(ObjectCache));
- if (!objcache_cache)
- return NULL;
- init_objcache(objcache_cache, "objcache_cache",
- sizeof(ObjectCache), 0, NULL);
- }
-
- /* new cache object */
- cache = obj_alloc(objcache_cache);
- if (cache)
- init_objcache(cache, name, obj_size, align, init_func);
- return cache;
-}
-
-/* free all storage associated by cache */
-void objcache_destroy(ObjectCache *cache)
-{
- struct List *item, *tmp;
- struct Slab *slab;
-
- statlist_for_each_safe(item, &cache->slablist, tmp) {
- slab = container_of(item, struct Slab, head);
- free(slab);
- }
- statlist_remove(&objcache_list, &cache->head);
- memset(cache, 0, sizeof(*cache));
- obj_free(objcache_cache, cache);
-}
-
-/* add new block of objects to cache */
-static void grow(ObjectCache *cache)
-{
- unsigned count, i, size;
- char *area;
- struct Slab *slab;
-
- /* calc new slab size */
- count = cache->total_count;
- if (count < 50)
- count = 16 * 1024 / cache->final_size;
- if (count < 50)
- count = 50;
- size = count * cache->final_size;
-
- /* allocate & init */
- slab = malloc(size + sizeof(struct Slab));
- if (!slab)
- return;
- list_init(&slab->head);
- area = (char *)slab + sizeof(struct Slab);
- memset(area, 0, size);
-
- /* init objects */
- for (i = 0; i < count; i++) {
- void *obj = area + i * cache->final_size;
- struct List *head = (struct List *)obj;
- list_init(head);
- statlist_append(&cache->freelist, head);
- }
-
- /* register to cache */
- cache->total_count += count;
- statlist_append(&cache->slablist, &slab->head);
-}
-
-/* get free object from cache */
-void *obj_alloc(ObjectCache *cache)
-{
- struct List *item = statlist_pop(&cache->freelist);
- if (!item) {
- grow(cache);
- item = statlist_pop(&cache->freelist);
- }
- if (item) {
- if (cache->init_func)
- cache->init_func(item);
- else
- memset(item, 0, cache->final_size);
- }
- return item;
-}
-
-/* put object back to cache */
-void obj_free(ObjectCache *cache, void *obj)
-{
- struct List *item = obj;
- list_init(item);
- statlist_prepend(&cache->freelist, item);
-}
-
-/* total number of objects allocated from cache */
-int objcache_total_count(const ObjectCache *cache)
-{
- return cache->total_count;
-}
-
-/* free objects in cache */
-int objcache_free_count(const ObjectCache *cache)
-{
- return statlist_count(&cache->freelist);
-}
-
-/* number of objects in use */
-int objcache_active_count(const ObjectCache *cache)
-{
- return objcache_total_count(cache) - objcache_free_count(cache);
-}
-
-static void run_slab_stats(ObjectCache *cache, slab_stat_fn fn, void *arg)
-{
- unsigned free = statlist_count(&cache->freelist);
- fn(arg, cache->name, cache->final_size, free, cache->total_count);
-}
-
-void objcache_stats(slab_stat_fn fn, void *arg)
-{
- ObjectCache *cache;
- struct List *item;
-
- statlist_for_each(item, &objcache_list) {
- cache = container_of(item, ObjectCache, head);
- run_slab_stats(cache, fn, arg);
- }
-}
-
#include "bouncer.h"
-#include "md5.h"
+#define MD5_COMPAT
+#include <usual/md5.h>
int log_socket_prefix(enum LogLevel lev, void *ctx, char *dst, unsigned int dstlen)
{