mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-25 12:43:09 +00:00
trace lua service
This commit is contained in:
4
Makefile
4
Makefile
@@ -60,8 +60,8 @@ service/snlua.so : service-src/service_lua.c
|
|||||||
service/gate.so : gate/mread.c gate/ringbuffer.c gate/main.c
|
service/gate.so : gate/mread.c gate/ringbuffer.c gate/main.c
|
||||||
gcc $(CFLAGS) $(SHARED) $^ -o $@ -Igate -Iskynet-src
|
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
|
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
|
gcc $(CFLAGS) $(SHARED) -Iluacompat $^ -o $@ -Iskynet-src -Ilualib-src
|
||||||
|
|
||||||
service/client.so : service-src/service_client.c
|
service/client.so : service-src/service_client.c
|
||||||
gcc $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src
|
gcc $(CFLAGS) $(SHARED) $^ -o $@ -Iskynet-src
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "skynet.h"
|
#include "skynet.h"
|
||||||
|
#include "trace_service.h"
|
||||||
#include "lua-seri.h"
|
#include "lua-seri.h"
|
||||||
|
|
||||||
#include "luacompat52.h"
|
#include "luacompat52.h"
|
||||||
@@ -10,13 +11,12 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#define NANOSEC 1000000000
|
|
||||||
|
|
||||||
struct stat {
|
struct stat {
|
||||||
lua_State *L;
|
lua_State *L;
|
||||||
int count;
|
int count;
|
||||||
uint32_t ti_sec;
|
uint32_t ti_sec;
|
||||||
uint32_t ti_nsec;
|
uint32_t ti_nsec;
|
||||||
|
struct trace_pool *trace;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -25,23 +25,9 @@ _stat_begin(struct stat *S, struct timespec *ti) {
|
|||||||
clock_gettime(CLOCK_THREAD_CPUTIME_ID, ti);
|
clock_gettime(CLOCK_THREAD_CPUTIME_ID, ti);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
inline static void
|
||||||
_stat_end(struct stat *S, struct timespec *ti) {
|
_stat_end(struct stat *S, struct timespec *ti) {
|
||||||
struct timespec end;
|
diff_time(ti, &S->ti_sec, &S->ti_nsec);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -61,6 +47,10 @@ _stat(lua_State *L) {
|
|||||||
lua_pushnumber(L, t);
|
lua_pushnumber(L, t);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (strcmp(what,"trace")==0) {
|
||||||
|
lua_pushlightuserdata(L, S->trace);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,6 +101,13 @@ _cb(struct skynet_context * context, void * ud, int type, int session, uint32_t
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_delete_stat(lua_State *L) {
|
||||||
|
struct stat * S = lua_touserdata(L,1);
|
||||||
|
trace_release(S->trace);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_callback(lua_State *L) {
|
_callback(lua_State *L) {
|
||||||
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
struct skynet_context * context = lua_touserdata(L, lua_upvalueindex(1));
|
||||||
@@ -128,6 +125,12 @@ _callback(lua_State *L) {
|
|||||||
struct stat * S = lua_newuserdata(L, sizeof(*S));
|
struct stat * S = lua_newuserdata(L, sizeof(*S));
|
||||||
memset(S, 0, sizeof(*S));
|
memset(S, 0, sizeof(*S));
|
||||||
S->L = gL;
|
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);
|
lua_rawsetp(L, LUA_REGISTRYINDEX, _stat);
|
||||||
|
|
||||||
@@ -337,6 +340,51 @@ _harbor(lua_State *L) {
|
|||||||
return 2;
|
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
|
// define in lua-remoteobj.c
|
||||||
int remoteobj_init(lua_State *L);
|
int remoteobj_init(lua_State *L);
|
||||||
|
|
||||||
@@ -379,10 +427,14 @@ luaopen_skynet_c(lua_State *L) {
|
|||||||
luaL_Reg l2[] = {
|
luaL_Reg l2[] = {
|
||||||
{ "stat", _stat },
|
{ "stat", _stat },
|
||||||
{ "remote_init", remoteobj_init },
|
{ "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 },
|
{ NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
luaL_setfuncs(L,l2,0);
|
luaL_setfuncs(L,l2,0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
146
lualib-src/trace_service.c
Normal file
146
lualib-src/trace_service.c
Normal file
@@ -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
lualib-src/trace_service.h
Normal file
22
lualib-src/trace_service.h
Normal file
@@ -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
|
||||||
Reference in New Issue
Block a user