Skip to content

Commit

Permalink
Add DTrace probes for Solaris/etc.
Browse files Browse the repository at this point in the history
  • Loading branch information
Trond Norbye authored and dormando committed Jan 2, 2009
1 parent 5da8dba commit 6895721
Show file tree
Hide file tree
Showing 10 changed files with 715 additions and 51 deletions.
18 changes: 16 additions & 2 deletions Makefile.am
Expand Up @@ -4,8 +4,22 @@ pkginclude_HEADERS = protocol_binary.h
memcached_SOURCES = memcached.c slabs.c slabs.h items.c items.h assoc.c assoc.h memcached.h thread.c stats.c stats.h memcached_SOURCES = memcached.c slabs.c slabs.h items.c items.h assoc.c assoc.h memcached.h thread.c stats.c stats.h
memcached_debug_SOURCES = $(memcached_SOURCES) memcached_debug_SOURCES = $(memcached_SOURCES)
memcached_CPPFLAGS = -DNDEBUG memcached_CPPFLAGS = -DNDEBUG
memcached_LDADD = @LIBOBJS@ memcached_LDADD = @DTRACE_OBJ@ @DAEMON_OBJ@
memcached_debug_LDADD = $(memcached_LDADD) memcached_debug_LDADD = @DTRACE_DEBUG_OBJ@ @DAEMON_OBJ@
memcached_DEPENDENCIES = @DTRACE_OBJ@ @DAEMON_OBJ@
memcached_debug_DEPENDENCIES = @DTRACE_DEBUG_OBJ@ @DAEMON_OBJ@

memcached_dtrace.h:
${DTRACE} -h -s memcached_dtrace.d
sed -e s,_DTRACE_VERSION,ENABLE_DTRACE,g memcached_dtrace.h | \
tr '\t' ' ' | grep -v unistd.h > memcached_dtrace.tmp
mv memcached_dtrace.tmp memcached_dtrace.h

memcached_dtrace.o: $(memcached_OBJECTS)
$(DTRACE) $(DTRACEFLAGS) -G -o memcached_dtrace.o -s ${srcdir}/memcached_dtrace.d $(memcached_OBJECTS)

memcached_debug_dtrace.o: $(memcached_debug_OBJECTS)
$(DTRACE) $(DTRACEFLAGS) -G -o memcached_debug_dtrace.o -s ${srcdir}/memcached_dtrace.d $(memcached_debug_OBJECTS)


SUBDIRS = doc SUBDIRS = doc
DIST_DIRS = scripts DIST_DIRS = scripts
Expand Down
22 changes: 16 additions & 6 deletions assoc.c
Expand Up @@ -496,14 +496,18 @@ item *assoc_find(const char *key, const size_t nkey) {
it = primary_hashtable[hv & hashmask(hashpower)]; it = primary_hashtable[hv & hashmask(hashpower)];
} }


item *ret = NULL;
int depth = 0;
while (it) { while (it) {
if ((nkey == it->nkey) && if ((nkey == it->nkey) && (memcmp(key, ITEM_key(it), nkey) == 0)) {
(memcmp(key, ITEM_key(it), nkey) == 0)) { ret = it;
return it; break;
} }
it = it->h_next; it = it->h_next;
++depth;
} }
return 0; MEMCACHED_ASSOC_FIND(key, depth);
return ret;
} }


/* returns the address of the item pointer before the key. if *item == 0, /* returns the address of the item pointer before the key. if *item == 0,
Expand Down Expand Up @@ -595,17 +599,23 @@ int assoc_insert(item *it) {
assoc_expand(); assoc_expand();
} }


MEMCACHED_ASSOC_INSERT(ITEM_key(it), hash_items);
return 1; return 1;
} }


void assoc_delete(const char *key, const size_t nkey) { void assoc_delete(const char *key, const size_t nkey) {
item **before = _hashitem_before(key, nkey); item **before = _hashitem_before(key, nkey);


if (*before) { if (*before) {
item *nxt = (*before)->h_next; item *nxt;
hash_items--;
/* The DTrace probe cannot be triggered as the last instruction
* due to possible tail-optimization by the compiler
*/
MEMCACHED_ASSOC_DELETE(key, hash_items);
nxt = (*before)->h_next;
(*before)->h_next = 0; /* probably pointless, but whatever. */ (*before)->h_next = 0; /* probably pointless, but whatever. */
*before = nxt; *before = nxt;
hash_items--;
return; return;
} }
/* Note: we never actually get here. the callers don't delete things /* Note: we never actually get here. the callers don't delete things
Expand Down
22 changes: 21 additions & 1 deletion configure.ac
Expand Up @@ -9,6 +9,25 @@ AC_PROG_CC
AM_PROG_CC_C_O AM_PROG_CC_C_O
AC_PROG_INSTALL AC_PROG_INSTALL


AC_ARG_ENABLE(dtrace,
[AS_HELP_STRING([--enable-dtrace],[Enable dtrace probes])])
if test "x$enable_dtrace" == "xyes"; then
AC_PATH_PROG([DTRACE], [dtrace], "no", [/usr/sbin:$PATH])
if test "x$DTRACE" != "xno"; then
AC_DEFINE([ENABLE_DTRACE],1,[Set to nonzero if you want to include DTRACE])
DTRACE_OBJ=memcached_dtrace.o
DTRACE_DEBUG_OBJ=memcached_debug_dtrace.o
else
AC_MSG_ERROR([Need dtrace binary and OS support.])
fi
else
AC_DEFINE([ENABLE_DTRACE],0,[Set to nonzero if you want to include DTRACE])
fi
AC_SUBST(DTRACE)
AC_SUBST(DTRACE_OBJ)
AC_SUBST(DTRACE_DEBUG_OBJ)
AC_SUBST(DTRACEFLAGS)

AC_ARG_ENABLE(64bit, AC_ARG_ENABLE(64bit,
[AS_HELP_STRING([--enable-64bit],[build 64bit verison])]) [AS_HELP_STRING([--enable-64bit],[build 64bit verison])])
if test "x$enable_64bit" == "xyes" if test "x$enable_64bit" == "xyes"
Expand Down Expand Up @@ -113,7 +132,8 @@ AC_SEARCH_LIBS(socket, socket)
AC_SEARCH_LIBS(gethostbyname, nsl) AC_SEARCH_LIBS(gethostbyname, nsl)
AC_SEARCH_LIBS(mallinfo, malloc) AC_SEARCH_LIBS(mallinfo, malloc)


AC_CHECK_FUNC(daemon,AC_DEFINE([HAVE_DAEMON],,[Define this if you have daemon()]),[AC_LIBOBJ(daemon)]) AC_CHECK_FUNC(daemon,AC_DEFINE([HAVE_DAEMON],,[Define this if you have daemon()]),[DAEMON_OBJ=daemon.o])
AC_SUBST(DAEMON_OBJ)


AC_HEADER_STDBOOL AC_HEADER_STDBOOL
AC_C_CONST AC_C_CONST
Expand Down
6 changes: 6 additions & 0 deletions items.c
Expand Up @@ -228,6 +228,7 @@ static void item_unlink_q(item *it) {
} }


int do_item_link(item *it) { int do_item_link(item *it) {
MEMCACHED_ITEM_LINK(ITEM_key(it), it->nbytes);
assert((it->it_flags & (ITEM_LINKED|ITEM_SLABBED)) == 0); assert((it->it_flags & (ITEM_LINKED|ITEM_SLABBED)) == 0);
assert(it->nbytes < (1024 * 1024)); /* 1MB max size */ assert(it->nbytes < (1024 * 1024)); /* 1MB max size */
it->it_flags |= ITEM_LINKED; it->it_flags |= ITEM_LINKED;
Expand All @@ -249,6 +250,7 @@ int do_item_link(item *it) {
} }


void do_item_unlink(item *it) { void do_item_unlink(item *it) {
MEMCACHED_ITEM_UNLINK(ITEM_key(it), it->nbytes);
if ((it->it_flags & ITEM_LINKED) != 0) { if ((it->it_flags & ITEM_LINKED) != 0) {
it->it_flags &= ~ITEM_LINKED; it->it_flags &= ~ITEM_LINKED;
STATS_LOCK(); STATS_LOCK();
Expand All @@ -262,6 +264,7 @@ void do_item_unlink(item *it) {
} }


void do_item_remove(item *it) { void do_item_remove(item *it) {
MEMCACHED_ITEM_REMOVE(ITEM_key(it), it->nbytes);
assert((it->it_flags & ITEM_SLABBED) == 0); assert((it->it_flags & ITEM_SLABBED) == 0);
if (it->refcount != 0) { if (it->refcount != 0) {
it->refcount--; it->refcount--;
Expand All @@ -274,6 +277,7 @@ void do_item_remove(item *it) {
} }


void do_item_update(item *it) { void do_item_update(item *it) {
MEMCACHED_ITEM_UPDATE(ITEM_key(it), it->nbytes);
if (it->time < current_time - ITEM_UPDATE_INTERVAL) { if (it->time < current_time - ITEM_UPDATE_INTERVAL) {
assert((it->it_flags & ITEM_SLABBED) == 0); assert((it->it_flags & ITEM_SLABBED) == 0);


Expand All @@ -286,6 +290,8 @@ void do_item_update(item *it) {
} }


int do_item_replace(item *it, item *new_it) { int do_item_replace(item *it, item *new_it) {
MEMCACHED_ITEM_REPLACE(ITEM_key(it), it->nbytes,
ITEM_key(new_it), new_it->nbytes);
assert((it->it_flags & ITEM_SLABBED) == 0); assert((it->it_flags & ITEM_SLABBED) == 0);


do_item_unlink(it); do_item_unlink(it);
Expand Down
76 changes: 59 additions & 17 deletions memcached.c
Expand Up @@ -317,6 +317,8 @@ conn *conn_new(const int sfd, enum conn_states init_state,
fprintf(stderr, "calloc()\n"); fprintf(stderr, "calloc()\n");
return NULL; return NULL;
} }
MEMCACHED_CONN_CREATE(c);

c->rbuf = c->wbuf = 0; c->rbuf = c->wbuf = 0;
c->ilist = 0; c->ilist = 0;
c->suffixlist = 0; c->suffixlist = 0;
Expand All @@ -341,13 +343,7 @@ conn *conn_new(const int sfd, enum conn_states init_state,


if (c->rbuf == 0 || c->wbuf == 0 || c->ilist == 0 || c->iov == 0 || if (c->rbuf == 0 || c->wbuf == 0 || c->ilist == 0 || c->iov == 0 ||
c->msglist == 0 || c->suffixlist == 0) { c->msglist == 0 || c->suffixlist == 0) {
if (c->rbuf != 0) free(c->rbuf); conn_free(c);
if (c->wbuf != 0) free(c->wbuf);
if (c->ilist != 0) free(c->ilist);
if (c->suffixlist != 0) free(c->suffixlist);
if (c->iov != 0) free(c->iov);
if (c->msglist != 0) free(c->msglist);
free(c);
fprintf(stderr, "malloc()\n"); fprintf(stderr, "malloc()\n");
return NULL; return NULL;
} }
Expand Down Expand Up @@ -424,6 +420,8 @@ conn *conn_new(const int sfd, enum conn_states init_state,
stats.total_conns++; stats.total_conns++;
STATS_UNLOCK(); STATS_UNLOCK();


MEMCACHED_CONN_ALLOCATE(c->sfd);

return c; return c;
} }


Expand Down Expand Up @@ -460,6 +458,7 @@ static void conn_cleanup(conn *c) {
*/ */
void conn_free(conn *c) { void conn_free(conn *c) {
if (c) { if (c) {
MEMCACHED_CONN_DESTROY(c);
if (c->hdrbuf) if (c->hdrbuf)
free(c->hdrbuf); free(c->hdrbuf);
if (c->msglist) if (c->msglist)
Expand Down Expand Up @@ -487,6 +486,7 @@ static void conn_close(conn *c) {
if (settings.verbose > 1) if (settings.verbose > 1)
fprintf(stderr, "<%d connection closed.\n", c->sfd); fprintf(stderr, "<%d connection closed.\n", c->sfd);


MEMCACHED_CONN_RELEASE(c->sfd);
close(c->sfd); close(c->sfd);
accept_new_conns(true); accept_new_conns(true);
conn_cleanup(c); conn_cleanup(c);
Expand Down Expand Up @@ -595,6 +595,10 @@ static void conn_set_state(conn *c, enum conn_states state) {
} }


c->state = state; c->state = state;

if (state == conn_write) {
MEMCACHED_PROCESS_COMMAND_END(c->sfd, c->wbuf, c->wbytes);
}
} }
} }


Expand Down Expand Up @@ -835,9 +839,32 @@ static void complete_nread_ascii(conn *c) {
out_string(c, "CLIENT_ERROR bad data chunk"); out_string(c, "CLIENT_ERROR bad data chunk");
} else { } else {
ret = store_item(it, comm, c); ret = store_item(it, comm, c);
if (ret == 1) if (ret == 1) {
out_string(c, "STORED"); out_string(c, "STORED");
else if(ret == 2) #ifdef HAVE_DTRACE
switch (comm) {
case NREAD_ADD:
MEMCACHED_COMMAND_ADD(c->sfd, ITEM_key(it), it->nbytes);
break;
case NREAD_REPLACE:
MEMCACHED_COMMAND_REPLACE(c->sfd, ITEM_key(it), it->nbytes);
break;
case NREAD_APPEND:
MEMCACHED_COMMAND_APPEND(c->sfd, ITEM_key(it), it->nbytes);
break;
case NREAD_PREPEND:
MEMCACHED_COMMAND_PREPEND(c->sfd, ITEM_key(it), it->nbytes);
break;
case NREAD_SET:
MEMCACHED_COMMAND_SET(c->sfd, ITEM_key(it), it->nbytes);
break;
case NREAD_CAS:
MEMCACHED_COMMAND_CAS(c->sfd, ITEM_key(it), it->nbytes,
it->cas_id);
break;
}
#endif
} else if(ret == 2)
out_string(c, "EXISTS"); out_string(c, "EXISTS");
else if(ret == 3) else if(ret == 3)
out_string(c, "NOT_FOUND"); out_string(c, "NOT_FOUND");
Expand Down Expand Up @@ -1024,7 +1051,7 @@ static void complete_incr_bin(conn *c) {
/* Weird magic in add_delta forces me to pad here */ /* Weird magic in add_delta forces me to pad here */
char tmpbuf[INCR_MAX_STORAGE_LEN]; char tmpbuf[INCR_MAX_STORAGE_LEN];
uint64_t l = 0; uint64_t l = 0;
add_delta(it, c->cmd == PROTOCOL_BINARY_CMD_INCREMENT, add_delta(c, it, c->cmd == PROTOCOL_BINARY_CMD_INCREMENT,
req->message.body.delta, tmpbuf); req->message.body.delta, tmpbuf);
rsp->message.body.value = swap64(strtoull(tmpbuf, NULL, 10)); rsp->message.body.value = swap64(strtoull(tmpbuf, NULL, 10));
c->cas = it->cas_id; c->cas = it->cas_id;
Expand Down Expand Up @@ -2153,6 +2180,8 @@ static inline void process_get_command(conn *c, token_t *tokens, size_t ntokens,


if (return_cas) if (return_cas)
{ {
MEMCACHED_COMMAND_GETS(c->sfd, ITEM_key(it), it->nbytes,
it->cas_id);
/* Goofy mid-flight realloc. */ /* Goofy mid-flight realloc. */
if (i >= c->suffixsize) { if (i >= c->suffixsize) {
char **new_suffix_list = realloc(c->suffixlist, char **new_suffix_list = realloc(c->suffixlist,
Expand Down Expand Up @@ -2186,6 +2215,8 @@ static inline void process_get_command(conn *c, token_t *tokens, size_t ntokens,
} }
else else
{ {
MEMCACHED_COMMAND_GET(c->sfd, ITEM_key(it), it->nbytes);

if (add_iov(c, "VALUE ", 6) != 0 || if (add_iov(c, "VALUE ", 6) != 0 ||
add_iov(c, ITEM_key(it), it->nkey) != 0 || add_iov(c, ITEM_key(it), it->nkey) != 0 ||
add_iov(c, ITEM_suffix(it), it->nsuffix + it->nbytes) != 0) add_iov(c, ITEM_suffix(it), it->nsuffix + it->nbytes) != 0)
Expand All @@ -2206,6 +2237,11 @@ static inline void process_get_command(conn *c, token_t *tokens, size_t ntokens,


} else { } else {
stats_get_misses++; stats_get_misses++;
if (return_cas) {
MEMCACHED_COMMAND_GETS(c->sfd, key, -1, 0);
} else {
MEMCACHED_COMMAND_GET(c->sfd, key, -1);
}
} }


key_token++; key_token++;
Expand Down Expand Up @@ -2373,21 +2409,22 @@ static void process_arithmetic_command(conn *c, token_t *tokens, const size_t nt
return; return;
} }


out_string(c, add_delta(it, incr, delta, temp)); out_string(c, add_delta(c, it, incr, delta, temp));
item_remove(it); /* release our reference */ item_remove(it); /* release our reference */
} }


/* /*
* adds a delta value to a numeric item. * adds a delta value to a numeric item.
* *
* c connection requesting the operation
* it item to adjust * it item to adjust
* incr true to increment value, false to decrement * incr true to increment value, false to decrement
* delta amount to adjust value by * delta amount to adjust value by
* buf buffer for response string * buf buffer for response string
* *
* returns a response string to send back to the client. * returns a response string to send back to the client.
*/ */
char *do_add_delta(item *it, const bool incr, const int64_t delta, char *buf) { char *do_add_delta(conn *c, item *it, const bool incr, const int64_t delta, char *buf) {
char *ptr; char *ptr;
int64_t value; int64_t value;
int res; int res;
Expand All @@ -2401,13 +2438,15 @@ char *do_add_delta(item *it, const bool incr, const int64_t delta, char *buf) {
return "CLIENT_ERROR cannot increment or decrement non-numeric value"; return "CLIENT_ERROR cannot increment or decrement non-numeric value";
} }


if (incr) if (incr) {
value += delta; value += delta;
else { MEMCACHED_COMMAND_INCR(c->sfd, ITEM_key(it), value);
} else {
value -= delta; value -= delta;
} if(value < 0) {
if(value < 0) { value = 0;
value = 0; }
MEMCACHED_COMMAND_DECR(c->sfd, ITEM_key(it), value);
} }
sprintf(buf, "%llu", value); sprintf(buf, "%llu", value);
res = strlen(buf); res = strlen(buf);
Expand Down Expand Up @@ -2465,6 +2504,7 @@ static void process_delete_command(conn *c, token_t *tokens, const size_t ntoken


it = item_get(key, nkey); it = item_get(key, nkey);
if (it) { if (it) {
MEMCACHED_PROCESS_COMMAND_START(c->sfd, c->rcurr, c->rbytes);
item_unlink(it); item_unlink(it);
item_remove(it); /* release our reference */ item_remove(it); /* release our reference */
out_string(c, "DELETED"); out_string(c, "DELETED");
Expand Down Expand Up @@ -2494,6 +2534,8 @@ static void process_command(conn *c, char *command) {


assert(c != NULL); assert(c != NULL);


MEMCACHED_PROCESS_COMMAND_START(c->sfd, c->rcurr, c->rbytes);

if (settings.verbose > 1) if (settings.verbose > 1)
fprintf(stderr, "<%d %s\n", c->sfd, command); fprintf(stderr, "<%d %s\n", c->sfd, command);


Expand Down
7 changes: 5 additions & 2 deletions memcached.h
Expand Up @@ -281,7 +281,8 @@ conn *do_conn_from_freelist();
bool do_conn_add_to_freelist(conn *c); bool do_conn_add_to_freelist(conn *c);
char *do_suffix_from_freelist(); char *do_suffix_from_freelist();
bool do_suffix_add_to_freelist(char *s); bool do_suffix_add_to_freelist(char *s);
char *do_add_delta(item *item, const bool incr, const int64_t delta, char *buf); char *do_add_delta(conn *c, item *item, const bool incr, const int64_t delta,
char *buf);
int do_store_item(item *item, int comm, conn* c); int do_store_item(item *item, int comm, conn* c);
conn *conn_new(const int sfd, const enum conn_states init_state, const int event_flags, const int read_buffer_size, enum protocol prot, struct event_base *base); conn *conn_new(const int sfd, const enum conn_states init_state, const int event_flags, const int read_buffer_size, enum protocol prot, struct event_base *base);


Expand All @@ -290,6 +291,7 @@ conn *conn_new(const int sfd, const enum conn_states init_state, const int event
#include "slabs.h" #include "slabs.h"
#include "assoc.h" #include "assoc.h"
#include "items.h" #include "items.h"
#include "memcached_dtrace.h"




/* /*
Expand All @@ -304,7 +306,8 @@ int dispatch_event_add(int thread, conn *c);
void dispatch_conn_new(int sfd, enum conn_states init_state, int event_flags, int read_buffer_size, enum protocol prot); void dispatch_conn_new(int sfd, enum conn_states init_state, int event_flags, int read_buffer_size, enum protocol prot);


/* Lock wrappers for cache functions that are called from main loop. */ /* Lock wrappers for cache functions that are called from main loop. */
char *add_delta(item *item, const int incr, const int64_t delta, char *buf); char *add_delta(conn *c, item *item, const int incr, const int64_t delta,
char *buf);
void assoc_move_next_bucket(void); void assoc_move_next_bucket(void);
conn *conn_from_freelist(void); conn *conn_from_freelist(void);
bool conn_add_to_freelist(conn *c); bool conn_add_to_freelist(conn *c);
Expand Down

0 comments on commit 6895721

Please sign in to comment.