Skip to content

Commit

Permalink
trace lua service
Browse files Browse the repository at this point in the history
  • Loading branch information
cloudwu committed Sep 15, 2012
1 parent b511c92 commit 9a7ed22
Show file tree
Hide file tree
Showing 4 changed files with 241 additions and 21 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ service/snlua.so : service-src/service_lua.c
service/gate.so : gate/mread.c gate/ringbuffer.c gate/main.c
gcc $(CFLAGS) $(SHARED) $^ -o $@ -Igate -Iskynet-src

luaclib/skynet.so : lualib-src/lua-skynet.c lualib-src/lua-seri.c lualib-src/lua-remoteobj.c | luaclib
gcc $(CFLAGS) $(SHARED) -Iluacompat $^ -o $@ -Iskynet-src
luaclib/skynet.so : lualib-src/lua-skynet.c lualib-src/lua-seri.c lualib-src/lua-remoteobj.c lualib-src/trace_service.c | luaclib
gcc $(CFLAGS) $(SHARED) -Iluacompat $^ -o $@ -Iskynet-src -Ilualib-src

service/client.so : service-src/service_client.c
gcc $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src
Expand Down
90 changes: 71 additions & 19 deletions lualib-src/lua-skynet.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "skynet.h"
#include "trace_service.h"
#include "lua-seri.h"

#include "luacompat52.h"
Expand All @@ -10,13 +11,12 @@
#include <assert.h>
#include <time.h>

#define NANOSEC 1000000000

struct stat {
lua_State *L;
int count;
uint32_t ti_sec;
uint32_t ti_nsec;
struct trace_pool *trace;
};

static void
Expand All @@ -25,23 +25,9 @@ _stat_begin(struct stat *S, struct timespec *ti) {
clock_gettime(CLOCK_THREAD_CPUTIME_ID, ti);
}

static void
inline static void
_stat_end(struct stat *S, struct timespec *ti) {
struct timespec end;
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end);
int diffsec = end.tv_sec - ti->tv_sec;
assert(diffsec>=0);
int diffnsec = end.tv_nsec - ti->tv_nsec;
if (diffnsec < 0) {
--diffsec;
diffnsec += NANOSEC;
}
S->ti_nsec += diffnsec;
if (S->ti_nsec > NANOSEC) {
++S->ti_sec;
S->ti_nsec -= NANOSEC;
}
S->ti_sec += diffsec;
diff_time(ti, &S->ti_sec, &S->ti_nsec);
}

static int
Expand All @@ -61,6 +47,10 @@ _stat(lua_State *L) {
lua_pushnumber(L, t);
return 1;
}
if (strcmp(what,"trace")==0) {
lua_pushlightuserdata(L, S->trace);
return 1;
}
return 0;
}

Expand Down Expand Up @@ -111,6 +101,13 @@ _cb(struct skynet_context * context, void * ud, int type, int session, uint32_t
return 0;
}

static int
_delete_stat(lua_State *L) {
struct stat * S = lua_touserdata(L,1);
trace_release(S->trace);
return 0;
}

static int
_callback(lua_State *L) {
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
Expand All @@ -128,6 +125,12 @@ _callback(lua_State *L) {
struct stat * S = lua_newuserdata(L, sizeof(*S));
memset(S, 0, sizeof(*S));
S->L = gL;
S->trace = trace_create();

lua_createtable(L,0,1);
lua_pushcfunction(L, _delete_stat);
lua_setfield(L,-1,"__gc");
lua_setmetatable(L, -2);

lua_rawsetp(L, LUA_REGISTRYINDEX, _stat);

Expand Down Expand Up @@ -337,6 +340,51 @@ _harbor(lua_State *L) {
return 2;
}

// trace api
static int
_trace_new(lua_State *L) {
struct trace_pool *p = lua_touserdata(L,1);
struct trace_info *t = trace_new(p);
lua_pushlightuserdata(L,t);
return 1;
}

static int
_trace_delete(lua_State *L) {
struct trace_pool *p = lua_touserdata(L,1);
struct trace_info *t = lua_touserdata(L,2);
double ti = trace_delete(p,t);
lua_pushnumber(L, ti);
return 1;
}

static int
_trace_switch(lua_State *L) {
struct trace_pool *p = lua_touserdata(L,1);
int session = luaL_checkinteger(L,2);
trace_switch(p, session);
return 0;
}

static int
_trace_yield(lua_State *L) {
struct trace_pool *p = lua_touserdata(L,1);
struct trace_info * t = trace_yield(p);
if (t) {
lua_pushlightuserdata(L,t);
return 1;
}
return 0;
}

static int
_trace_register(lua_State *L) {
struct trace_pool *p = lua_touserdata(L,1);
int session = luaL_checkinteger(L,2);
trace_register(p, session);
return 0;
}

// define in lua-remoteobj.c
int remoteobj_init(lua_State *L);

Expand Down Expand Up @@ -379,10 +427,14 @@ luaopen_skynet_c(lua_State *L) {
luaL_Reg l2[] = {
{ "stat", _stat },
{ "remote_init", remoteobj_init },
{ "trace_new", _trace_new },
{ "trace_delete", _trace_delete },
{ "trace_switch", _trace_switch },
{ "trace_yield", _trace_yield },
{ "trace_register", _trace_register },
{ NULL, NULL },
};


luaL_setfuncs(L,l2,0);

return 1;
Expand Down
146 changes: 146 additions & 0 deletions lualib-src/trace_service.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#include "trace_service.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <time.h>
#include <stdint.h>

#define HASH_SIZE 32

void
diff_time(struct timespec *ti, uint32_t *sec, uint32_t *nsec) {
struct timespec end;
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end);
int diffsec = end.tv_sec - ti->tv_sec;
assert(diffsec>=0);
int diffnsec = end.tv_nsec - ti->tv_nsec;
if (diffnsec < 0) {
--diffsec;
diffnsec += NANOSEC;
}
*nsec += diffnsec;
if (*nsec > NANOSEC) {
++*sec;
*nsec -= NANOSEC;
}
*sec += diffsec;
}

struct trace_info {
int session;
struct trace_info * prev;
struct trace_info * next;
struct timespec ti;
uint32_t ti_sec;
uint32_t ti_nsec;
};

struct trace_pool {
struct trace_info * current;
struct trace_info * slot[HASH_SIZE];
};

struct trace_pool *
trace_create() {
struct trace_pool * p = malloc(sizeof(*p));
memset(p, 0, sizeof(*p));
return p;
}

static void
_free_slot(struct trace_info *t) {
while (t) {
struct trace_info *next = t->next;
free(t);
t = next;
}
}

void
trace_release(struct trace_pool *p) {
int i;
for (i=0;i<HASH_SIZE;i++) {
_free_slot(p->slot[i]);
}
free(p->current);
}

struct trace_info *
trace_new(struct trace_pool *p) {
assert(p->current == NULL);
struct trace_info *t = malloc(sizeof(*t));
p->current = t;
t->session = 0;
t->prev = NULL;
t->next = NULL;
t->ti_sec = 0;
t->ti_nsec = 0;
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t->ti);
return t;
}

void
trace_register(struct trace_pool *p, int session) {
struct trace_info *t = p->current;
int hash = session % HASH_SIZE;
assert(t->session == 0);
t->session = session;
t->prev = NULL;
t->next = p->slot[hash];
if (p->slot[hash]) {
p->slot[hash]->prev = t;
}
}

struct trace_info *
trace_yield(struct trace_pool *p) {
struct trace_info *t = p->current;
if (t == NULL)
return NULL;
p->current = NULL;

diff_time(&t->ti,&t->ti_sec,&t->ti_nsec);

if (t->session == 0) {
return t;
} else {
return NULL;
}
}

void
trace_switch(struct trace_pool *p, int session) {
assert(p->current == NULL);
struct trace_info *t = p->slot[session % HASH_SIZE];
struct trace_info *prev = NULL;
while (t) {
if (t->session == session) {
p->current = t;
t->session = 0;
if (prev == NULL) {
p->slot[session % HASH_SIZE] = t->next;
} else {
prev->next = t->next;
}
if (t->next) {
t->next->prev = prev;
}
return;
}
prev = t;
t=t->next;
}
}

double
trace_delete(struct trace_pool *p, struct trace_info *t) {
assert(p->current == t);
p->current = NULL;
if (t) {
double ti = (double)t->ti_sec + (double)t->ti_nsec / NANOSEC;
free(t);
return ti;
} else {
return 0;
}
}
22 changes: 22 additions & 0 deletions lualib-src/trace_service.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef TRACE_SERVICE_H
#define TRACE_SERVICE_H

#include <time.h>
#include <stdint.h>

#define NANOSEC 1000000000

void diff_time(struct timespec *ti, uint32_t *sec, uint32_t *nsec);

struct trace_pool;
struct trace_info;

struct trace_pool * trace_create();
void trace_release(struct trace_pool *);
struct trace_info * trace_new(struct trace_pool *);
void trace_register(struct trace_pool *, int session);
void trace_switch(struct trace_pool *, int session);
struct trace_info * trace_yield(struct trace_pool *);
double trace_delete(struct trace_pool *, struct trace_info *);

#endif

0 comments on commit 9a7ed22

Please sign in to comment.