Changed log manager API so that pointer reference to logmanager is not used anymore. Every call initializes logmanager now except skygw_logmanager_done and skygw_log_flush.

skygw_logmanager_init is still useful because it allows for providing memory address for log manager where it can store a list of preallocated write buffers. TBD.

Logmanager access is now protected with spinlock familiar from epoll/core/spinlock.c . It is modified to avoid trashing; misses are counted and every tenth subsequent lock acquiring attempt triggers short random sleep.
This commit is contained in:
vraatikka
2013-06-26 23:13:40 +03:00
parent 2ea8e2a05a
commit ef1d198654
7 changed files with 397 additions and 210 deletions

View File

@ -26,9 +26,11 @@ testcomp:
-o testlog -DSS_DEBUG \
-I$(SOLIDDB_SRC_PATH)/include \
-I$(MARIADB_SRC_PATH)/include \
-I$(ROOT_PATH)/epoll_v1.0/include \
-I$(LOG_MANAGER_PATH) -I$(ROOT_PATH)/utils testlog.c \
-llog_manager $(LDLIBS) \
$(LOG_MANAGER_PATH)/skygw_utils.o
$(LOG_MANAGER_PATH)/skygw_utils.o \
$(LOG_MANAGER_PATH)/atomic.o
testall:
- $(LAUNCH_DEBUGGER) $(TESTAPP) $(BACKGR)

View File

@ -22,44 +22,166 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <skygw_utils.h>
#include <log_manager.h>
typedef struct thread_st {
skygw_message_t* mes;
simple_mutex_t* mtx;
size_t* nactive;
} thread_t;
static void* thr_run(void* data);
#define NTHR 10
int main(int argc, char* argv[])
{
int err;
logmanager_t* lmgr;
char* logstr;
lmgr = skygw_logmanager_init(NULL, argc, argv);
int i;
skygw_message_t* mes;
simple_mutex_t* mtx;
size_t nactive;
thread_t* thr[NTHR];
skygw_logmanager_init(NULL, argc, argv);
logstr = strdup("My name is Tracey");
err = skygw_log_write(NULL, lmgr, LOGFILE_TRACE, logstr);
err = skygw_log_write(NULL, LOGFILE_TRACE, logstr);
logstr = strdup("My name is Stacey");
err = skygw_log_write_flush(NULL, lmgr, LOGFILE_TRACE, logstr);
err = skygw_log_write_flush(NULL, LOGFILE_TRACE, logstr);
skygw_logmanager_done(NULL, &lmgr);
skygw_logmanager_done(NULL);
logstr = strdup("My name is Philip");
err = skygw_log_write(NULL, lmgr, LOGFILE_TRACE, logstr);
err = skygw_log_write(NULL, LOGFILE_TRACE, logstr);
lmgr = skygw_logmanager_init(NULL, argc, argv);
skygw_logmanager_init(NULL, argc, argv);
logstr = strdup("A terrible error has occurred!");
err = skygw_log_write_flush(NULL, lmgr, LOGFILE_ERROR, logstr);
err = skygw_log_write_flush(NULL, LOGFILE_ERROR, logstr);
logstr = strdup("Hi, how are you?");
err = skygw_log_write(NULL, lmgr, LOGFILE_MESSAGE, logstr);
err = skygw_log_write(NULL, LOGFILE_MESSAGE, logstr);
logstr = strdup("I'm doing fine!");
err = skygw_log_write(NULL, lmgr, LOGFILE_MESSAGE, logstr);
err = skygw_log_write(NULL, LOGFILE_MESSAGE, logstr);
logstr = strdup("I was wondering, you know, it has been such a lovely weather whole morning and I thought that would you like to come to my place and have a little piece of cheese with us. Just me and my mom - and you, of course. Then, if you wish, we could listen to the radio and keep company for our little Steven, my mom's cat, you see.");
err = skygw_log_write(NULL, lmgr, LOGFILE_MESSAGE, logstr);
logstr = strdup("Rather more surprising, at least at first sight, is the fact that a reference to a[i] can also be written as *(a+i). In evaluating a[i], C converts it to *(a+i) immediately; the two forms are equivalent. Applying the operatos & to both parts of this equivalence, it follows that &a[i] and a+i are also identical: a+i is the address of the i-th element beyond a.");
err = skygw_log_write(NULL, LOGFILE_ERROR, logstr);
logstr = strdup("I was wondering, you know, it has been such a lovely weather whole morning and I thought that would you like to come to my place and have a little piece of cheese with us. Just me and my mom - and you, of course. Then, if you wish, we could listen to the radio and keep company for our little Steven, my mom's cat, you know.");
err = skygw_log_write(NULL, LOGFILE_MESSAGE, logstr);
skygw_logmanager_done(NULL);
mes = skygw_message_init();
mtx = simple_mutex_init(NULL, strdup("testmtx"));
return_err:
skygw_logmanager_done(NULL, &lmgr);
for (i=0; i<NTHR; i++) {
thr[i] = (thread_t*)calloc(1, sizeof(thread_t));
thr[i]->mes = mes;
thr[i]->mtx = mtx;
thr[i]->nactive = &nactive;
}
nactive = NTHR;
for (i=0; i<NTHR; i++) {
pthread_t p;
pthread_create(&p, NULL, thr_run, thr[i]);
}
do {
skygw_message_wait(mes);
simple_mutex_lock(mtx, TRUE);
if (nactive > 0) {
simple_mutex_unlock(mtx);
continue;
}
break;
} while(TRUE);
/** This is to release memory */
skygw_logmanager_done(NULL);
simple_mutex_unlock(mtx);
for (i=0; i<NTHR; i++) {
free(thr[i]);
}
skygw_message_done(mes);
simple_mutex_done(mtx);
return err;
}
void* thr_run(
void* data)
{
thread_t* td = (thread_t *)data;
char* logstr;
int err;
skygw_logmanager_init(NULL, 0, NULL);
skygw_logmanager_done(NULL);
skygw_log_flush(LOGFILE_MESSAGE);
logstr = strdup("Hi, how are you?");
err = skygw_log_write(NULL, LOGFILE_MESSAGE, logstr);
ss_dassert(err == 0);
skygw_logmanager_done(NULL);
skygw_log_flush(LOGFILE_TRACE);
skygw_log_flush(LOGFILE_MESSAGE);
skygw_logmanager_init(NULL, 0, NULL);
logstr = strdup("Testing. One, two, three\n");
err = skygw_log_write(NULL, LOGFILE_ERROR, logstr);
ss_dassert(err == 0);
skygw_logmanager_init(NULL, 0, NULL);
skygw_logmanager_init(NULL, 0, NULL);
skygw_log_flush(LOGFILE_ERROR);
logstr = strdup("For automatic and register variables, it is done each time the function or block is entered.");
err = skygw_log_write(NULL, LOGFILE_TRACE, logstr);
ss_dassert(err == 0);
skygw_logmanager_done(NULL);
skygw_logmanager_init(NULL, 0, NULL);
skygw_logmanager_init(NULL, 0, NULL);
skygw_logmanager_done(NULL);
skygw_log_flush(LOGFILE_ERROR);
skygw_logmanager_done(NULL);
logstr = strdup("..and you?");
err = skygw_log_write(NULL, LOGFILE_MESSAGE, logstr);
ss_dassert(err == 0);
skygw_logmanager_init(NULL, 0, NULL);
skygw_logmanager_init(NULL, 0, NULL);
logstr = strdup("For automatic and register variables, it is done each time the function or block is entered.");
err = skygw_log_write(NULL, LOGFILE_TRACE, logstr);
ss_dassert(err == 0);
skygw_logmanager_init(NULL, 0, NULL);
skygw_logmanager_init(NULL, 0, NULL);
logstr = strdup("..... and you too?");
err = skygw_log_write(NULL, LOGFILE_MESSAGE, logstr);
ss_dassert(err == 0);
skygw_logmanager_done(NULL);
skygw_log_flush(LOGFILE_TRACE);
logstr = strdup("For automatic and register variables, it is done each time the function or block is entered.");
err = skygw_log_write(NULL, LOGFILE_TRACE, logstr);
ss_dassert(err == 0);
logstr = strdup("Testing. One, two, three, four\n");
err = skygw_log_write(NULL, LOGFILE_ERROR, logstr);
ss_dassert(err == 0);
skygw_logmanager_init(NULL, 0, NULL);
logstr = strdup("Testing. One, two, three, .. where was I?\n");
err = skygw_log_write(NULL, LOGFILE_ERROR, logstr);
ss_dassert(err == 0);
skygw_logmanager_init(NULL, 0, NULL);
skygw_logmanager_init(NULL, 0, NULL);
skygw_logmanager_done(NULL);
simple_mutex_lock(td->mtx, TRUE);
*td->nactive -= 1;
simple_mutex_unlock(td->mtx);
skygw_message_send(td->mes);
return NULL;
}