mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 12:20:41 +00:00
trace lua service
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#include "skynet.h"
|
||||
#include "trace_service.h"
|
||||
#include "lua-seri.h"
|
||||
|
||||
#include "luacompat52.h"
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
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