From 6ca781b8a38474ab428d5fcb3b489dfe3e974334 Mon Sep 17 00:00:00 2001 From: bustico Date: Fri, 21 Mar 2008 09:03:34 +0000 Subject: - numerous fixes - socket in non blocking mode (resolve some deadlock, and agent are immune to another agent beeing blocked) --- tools/Makefile | 86 +++++++ tools/ivyperf.c | 116 +++++++++ tools/ivyprobe.c | 442 ++++++++++++++++++++++++++++++++++ tools/ivyprobe_omp | Bin 0 -> 86152 bytes tools/ivythroughput.cpp | 628 ++++++++++++++++++++++++++++++++++++++++++++++++ tools/ivythroughput_omp | Bin 0 -> 117728 bytes 6 files changed, 1272 insertions(+) create mode 100644 tools/Makefile create mode 100644 tools/ivyperf.c create mode 100644 tools/ivyprobe.c create mode 100755 tools/ivyprobe_omp create mode 100644 tools/ivythroughput.cpp create mode 100755 tools/ivythroughput_omp (limited to 'tools') diff --git a/tools/Makefile b/tools/Makefile new file mode 100644 index 0000000..8e2394f --- /dev/null +++ b/tools/Makefile @@ -0,0 +1,86 @@ +CC = gcc -g -Wall +CPP='g++' +BUGGY_DEBIAN_OPTION = -DPCRECPP_EXP_DEFN="" -DPCRECPP_EXP_DECL="" +OMPCFLAGS = $(CFLAGS) -fopenmp -DOPENMP=1 +OMPLIB = -lgomp -lpthread +GLIBINC = `pkg-config --cflags glib-2.0` +GLIBLIB = `pkg-config --libs glib-2.0` +GLUTINC = -I/usr/include -I. +GLUTLIB = -L. -lglut -lGLU -lGL -lX11 -lXmu + + + + +TARGETS = ivyprobe ivythroughput ivyperf ivyglibprobe ivyxtprobe #ivyprobe_efence +OMP_TARGET= ivyprobe_omp ivythroughput_omp + +PCRELIB = `pcre-config --libs` +EXTRALIB= -L../src +EXTRAINC=-I../src + +.SUFFIXES: .c .o + +.c.o: + $(CC) $(CFLAGS) $(EXTRAINC) -c $*.c +.cpp.o: + $(CPP) $(CFLAGS) $(EXTRAINC) $(BUGGY_DEBIAN_OPTION) -c $*.cpp + + +all: $(TARGETS) +omp: $(OMP_TARGET) + +ivyprobe: ivyprobe.o ../src/libivy.a + $(CC) $(CFLAGS) $(EXTRAINC) -o $@ ivyprobe.o -L. -livy $(PCRELIB) $(EXTRALIB) + +ivythroughput: ivythroughput.o ../src/libivy.a + $(CPP) $(CFLAGS) $(EXTRAINC) -o $@ ivythroughput.o -L. -livy -lpcrecpp $(PCRELIB) $(EXTRALIB) + +ivyprobe_efence: ivyprobe.o ../src/libivy.a + $(CPP) $(CFLAGS) $(EXTRAINC) -o $@ ivyprobe.o -L. -livy -lpcrecpp $(PCRELIB) $(EXTRALIB) -lefence + + + +ivyprobe_omp: ivyprobe.o ../src/libivy_omp.a + $(CC) $(CFLAGS) $(EXTRAINC) -o $@ ivyprobe.o -L. -livy_omp $(PCRELIB) $(EXTRALIB) $(OMPLIB) + +ivythroughput_omp: ivythroughput.o ../src/libivy_omp.a + $(CPP) $(CFLAGS) $(EXTRAINC) -o $@ ivythroughput.o -L. -livy_omp -lpcrecpp $(PCRELIB) $(EXTRALIB) $(OMPLIB) + +ivyprobe.o : ivyprobe.c + $(CC) $(CFLAGS) $(EXTRAINC) $(REGEXP) -c ivyprobe.c -o $@ + +ivyperf: ivyperf.o ../src/libivy.a + $(CC) $(CFLAGS) $(EXTRAINC) -o $@ ivyperf.o -L. -livy $(PCRELIB) $(EXTRALIB) + +ivyxtprobe.o : ivyprobe.c + $(CC) $(CFLAGS) $(EXTRAINC) $(REGEXP) -DXTMAINLOOP -c ivyprobe.c -o $@ $(XTINC) + +ivyxtprobe: ivyxtprobe.o ../src/libxtivy.a + $(CC) -o $@ ivyxtprobe.o -L. $(XTLIB) -lxtivy $(PCRELIB) $(EXTRALIB) + +ivyglibprobe.o : ivyprobe.c + $(CC) $(CFLAGS) $(EXTRAINC) $(REGEXP) -DGLIBMAINLOOP -c ivyprobe.c -o ivyglibprobe.o $(GLIBINC) + +ivyglibprobe: ivyglibprobe.o ../src/libglibivy.a + $(CC) -o ivyglibprobe ivyglibprobe.o -L. $(GLIBLIB) -lglibivy $(PCRELIB) $(EXTRALIB) + +ivyglutprobe.o : ivyprobe.c + $(CC) $(CFLAGS) $(EXTRAINC) $(REGEXP) -DGLUTMAINLOOP -c ivyprobe.c -o ivyglutprobe.o $(GLUTINC) + +ivyglutprobe: ivyglutprobe.o ../src/libglutivy.a + $(CC) -o ivyglutprobe ivyglutprobe.o -L. $(GLUTLIB) -lglutivy $(PCRELIB) $(EXTRALIB + +installbins: $(TARGETS) + test -d $(DESTDIR)$(PREFIX)/bin || mkdirhier $(DESTDIR)$(PREFIX)/bin + install -m755 ivyprobe $(DESTDIR)$(PREFIX)/bin + +installbins_omp: $(OMP_TARGET) + test -d $(DESTDIR)$(PREFIX)/bin || mkdirhier $(DESTDIR)$(PREFIX)/bin + install -m755 ivyprobe_omp $(DESTDIR)$(PREFIX)/bin + +install: installbins +install_omp: installbins_omp + + +clean: + rm -fR $(TARGETS) *~ diff --git a/tools/ivyperf.c b/tools/ivyperf.c new file mode 100644 index 0000000..07453e3 --- /dev/null +++ b/tools/ivyperf.c @@ -0,0 +1,116 @@ +/* + * Ivy perf mesure le temp de round trip + * + * Copyright (C) 1997-2004 + * Centre d'Études de la Navigation Aérienne + * + * Main and only file + * + * Authors: François-Régis Colin + * Yannick Jestin + * + * Please refer to file version.h for the + * copyright notice regarding this software + */ + +#include "version.h" +#include +#include +#include +#ifdef WIN32 +#include +#ifdef __MINGW32__ +#include +#include +#endif +#else +#include +#include +#ifdef __INTERIX +extern char *optarg; +extern int optind; +#endif +#endif + + +#include "ivysocket.h" +#include "ivy.h" +#include "timer.h" +#include "ivyloop.h" +#define MILLISEC 1000.0 + +const char *mymessages[] = { "IvyPerf", "ping", "pong" }; +static double origin = 0; + +static double currentTime() +{ + double current; +#ifdef WIN32 + current = GetTickCount(); +#else + struct timeval stamp; + gettimeofday( &stamp, NULL ); + current = (double)stamp.tv_sec * MILLISEC + (double)(stamp.tv_usec/MILLISEC); +#endif + return current; +} + +void Reply (IvyClientPtr app, void *user_data, int argc, char *argv[]) +{ + IvySendMsg ("pong ts=%s tr=%f", *argv, currentTime()- origin); +} +void Pong (IvyClientPtr app, void *user_data, int argc, char *argv[]) +{ + double current = currentTime() - origin ; + double ts = atof( *argv++ ); + double tr = atof( *argv++ ); + double roundtrip1 = tr-ts; + double roundtrip2 = current - tr; + double roundtrip3 = current - ts; + fprintf(stderr,"roundtrip %f %f %f \n", roundtrip1, roundtrip2, roundtrip3 ); +} + +void TimerCall(TimerId id, void *user_data, unsigned long delta) +{ + int count = IvySendMsg ("ping ts=%f", currentTime() - origin ); + if ( count == 0 ) fprintf(stderr, "." ); +} + +void binCB( IvyClientPtr app, void *user_data, int id, char* regexp, IvyBindEvent event ) +{ + char *app_name = IvyGetApplicationName( app ); + switch ( event ) + { + case IvyAddBind: + printf("Application:%s bind '%s' ADDED\n", app_name, regexp ); + break; + case IvyRemoveBind: + printf("Application:%s bind '%s' REMOVED\n", app_name, regexp ); + break; + case IvyFilterBind: + printf("Application:%s bind '%s' FILTRED\n", app_name, regexp ); + break; + + } +} +int main(int argc, char *argv[]) +{ + long time=200; + + /* Mainloop management */ + if ( argc > 1 ) time = atol( argv[1] ); + + IvyInit ("IvyPerf", "IvyPerf ready", NULL,NULL,NULL,NULL); + IvySetFilter( sizeof( mymessages )/ sizeof( char *),mymessages ); + IvySetBindCallback( binCB, 0 ), + IvyBindMsg (Reply, NULL, "^ping ts=(.*)"); + IvyBindMsg (Pong, NULL, "^pong ts=(.*) tr=(.*)"); + origin = currentTime(); + IvyStart (0); + + TimerRepeatAfter (TIMER_LOOP, time, TimerCall, (void*)1); + + + IvyMainLoop (); + return 0; +} diff --git a/tools/ivyprobe.c b/tools/ivyprobe.c new file mode 100644 index 0000000..ead6e76 --- /dev/null +++ b/tools/ivyprobe.c @@ -0,0 +1,442 @@ +/* + * Ivy probe + * + * Copyright (C) 1997-2004 + * Centre d'Études de la Navigation Aérienne + * + * Main and only file + * + * Authors: François-Régis Colin + * Yannick Jestin + * + * Please refer to file version.h for the + * copyright notice regarding this software + */ +#define DEFAULT_IVYPROBE_NAME "IVYPROBE" +#define DEFAULT_READY " Ready" +#include "version.h" + +#define IVYMAINLOOP + +#ifdef XTMAINLOOP +#undef IVYMAINLOOP +#endif +#ifdef GLIBMAINLOOP +#undef IVYMAINLOOP +#endif + +#ifdef GLUTMAINLOOP +#undef IVYMAINLOOP +#endif + +#include +#include +#include +#ifdef WIN32 +#include +#include "getopt.h" +#ifdef __MINGW32__ +#include +#include +#endif +#else +#include +#include +#ifdef __INTERIX +extern char *optarg; +extern int optind; +#endif + +#endif +#ifdef XTMAINLOOP +#include "ivyxtloop.h" +#endif +#ifdef GLIBMAINLOOP +#include +#include "ivyglibloop.h" +#endif +#ifdef GLUTMAINLOOP +#include "ivyglutloop.h" +#endif +#ifdef IVYMAINLOOP +#include "ivyloop.h" +#endif +#include "ivysocket.h" +#include "ivychannel.h" +#include "ivybind.h" /* to test regexp before passing to BinMsg */ +#include "ivy.h" +#include "timer.h" +#ifdef XTMAINLOOP +#include +XtAppContext cntx; +#endif + +int app_count = 0; +int wait_count = 0; +int fbindcallback = 0; +int filter_count = 0; +const char *filter[4096]; +char *classes; + +void DirectCallback(IvyClientPtr app, void *user_data, int id, char *msg ) +{ + printf("%s sent a direct message, id=%d, message=%s\n", + IvyGetApplicationName(app),id,msg); +} + + +void Callback (IvyClientPtr app, void *user_data, int argc, char *argv[]) +{ + int i; + printf ("%s sent ",IvyGetApplicationName(app)); + for (i = 0; i < argc; i++) + printf(" '%s'",argv[i]); + printf("\n"); +} + +char * Chop(char *arg) +{ + size_t len; + if (arg==NULL) return arg; + len=strlen(arg)-1; + if ((*(arg+len))=='\n') *(arg+len)=0; + return arg; +} + +void HandleStdin (Channel channel, HANDLE fd, void *data) +{ + char buf[4096]; + char *line; + char *cmd; + char *arg; + int id; + IvyClientPtr app; + int err; + line = fgets(buf, 4096, stdin); + if (!line) { + + IvyChannelRemove (channel); + IvyStop(); + return; + } + if (*line == '.') { + cmd = strtok (line, ".: \n"); + + if (strcmp (cmd, "die") == 0) { + arg = strtok (NULL, " \n"); + if (arg) { + app = IvyGetApplication (arg); + if (app) + IvySendDieMsg (app); + else printf ("No Application %s!!!\n",arg); + } + + } else if (strcmp(cmd, "dieall-yes-i-am-sure") == 0) { + arg = IvyGetApplicationList("#"); + arg = strtok (arg, "#"); + while (arg) { + app = IvyGetApplication (arg); + if (app) + IvySendDieMsg (app); + else + printf ("No Application %s!!!\n",arg); + arg = strtok (NULL, " "); + } + + } else if (strcmp(cmd, "bind") == 0) { + arg = strtok (NULL, "'"); + Chop(arg); + if (arg) { + IvyBinding bind; + const char *errbuf; + int erroffset; + bind = IvyBindingCompile(arg, & erroffset, & errbuf); + if (bind==NULL) { + printf("Error compiling '%s', %s, not bound\n", arg, errbuf); + } else { + IvyBindingFree( bind ); + IvyBindMsg (Callback, NULL, arg); + } + } + + } else if (strcmp(cmd, "where") == 0) { + arg = strtok (NULL, " \n"); + if (arg) { + app = IvyGetApplication (arg); + if (app) + printf ("Application %s on %s\n",arg, IvyGetApplicationHost (app)); + else printf ("No Application %s!!!\n",arg); + } + } else if (strcmp(cmd, "direct") == 0) { + arg = strtok (NULL, " \n"); + if (arg) { + app = IvyGetApplication (arg); + if (app) { + arg = strtok (NULL, " "); + id = atoi (arg) ; + arg = strtok (NULL, "'"); + IvySendDirectMsg (app, id, Chop(arg)); + } else + printf ("No Application %s!!!\n",arg); + } + + } else if (strcmp(cmd, "who") == 0) { + printf("Apps: %s\n", IvyGetApplicationList(",")); + + } else if (strcmp(cmd, "help") == 0) { + fprintf(stderr,"Commands list:\n"); + printf(" .help - this help\n"); + printf(" .quit - terminate this application\n"); + printf(" .die appname - send die msg to appname\n"); + printf(" .dieall-yes-i-am-sure - send die msg to all applis\n"); + printf(" .direct appname id 'arg' - send direct msg to appname\n"); + printf(" .where appname - on which host is appname\n"); + printf(" .bind 'regexp' - add a msg to receive\n"); + printf(" .showbind - show bindings \n"); + + printf(" .who - who is on the bus\n"); + } else if (strcmp(cmd, "showbind") == 0) { + if (!fbindcallback) { + IvySetBindCallback(IvyDefaultBindCallback, NULL); + fbindcallback=1; + } else { + IvySetBindCallback(NULL, NULL); + fbindcallback=0; + } + } else if (strcmp(cmd, "quit") == 0) { + exit(0); + } + } else { + cmd = strtok (buf, "\n"); + err = IvySendMsg (cmd); + printf("-> Sent to %d peer%s\n", err, err == 1 ? "" : "s"); + } +} + +void ApplicationCallback (IvyClientPtr app, void *user_data, IvyApplicationEvent event) +{ + char *appname; + char *host; +/* char **msgList;*/ + appname = IvyGetApplicationName (app); + host = IvyGetApplicationHost (app); + switch (event) { + + case IvyApplicationConnected: + app_count++; + printf("%s connected from %s\n", appname, host); +/* printf("Application(%s): Begin Messages\n", appname);*/ +/* double usage with -s flag remove it + msgList = IvyGetApplicationMessages (app); + while (*msgList ) + printf("%s subscribes to '%s'\n",appname,*msgList++); +*/ +/* printf("Application(%s): End Messages\n",appname);*/ +#ifndef WIN32 +/* Stdin not compatible with select , select only accept socket */ + if (app_count == wait_count) + IvyChannelAdd (0, NULL, NULL, HandleStdin, NULL); +#endif + break; + + case IvyApplicationDisconnected: + app_count--; + printf("%s disconnected from %s\n", appname, host); + break; + + default: + printf("%s: unkown event %d\n", appname, event); + break; + } +} +void IvyPrintBindCallback( IvyClientPtr app, void *user_data, int id, char* regexp, IvyBindEvent event) +{ + switch ( event ) { + case IvyAddBind: + if ( fbindcallback ) + printf("Application: %s on %s add regexp %d : %s\n", + IvyGetApplicationName( app ), IvyGetApplicationHost(app), id, regexp); + break; + case IvyRemoveBind: + if ( fbindcallback ) + printf("Application: %s on %s remove regexp %d :%s\n", + IvyGetApplicationName( app ), IvyGetApplicationHost(app), id, regexp); + break; + case IvyFilterBind: + printf("Application: %s on %s as been filtred regexp %d :%s\n", + IvyGetApplicationName( app ), IvyGetApplicationHost(app), id, regexp); + break; + case IvyChangeBind: + if ( fbindcallback ) + printf("Application: %s on %s change regexp %d : %s\n", + IvyGetApplicationName( app ), IvyGetApplicationHost(app), id, regexp); + break; + default: + printf("Application: %s unkown event %d\n",IvyGetApplicationName( app ), event); + break; + } +} + + +#ifdef IVYMAINLOOP +void TimerCall(TimerId id, void *user_data, unsigned long delta) +{ + printf("Timer callback: %ld delta %lu ms\n", (long)user_data, delta); + IvySendMsg ("TEST TIMER %d", (long)user_data); + /*if ((int)user_data == 5) TimerModify (id, 2000);*/ +} +#endif +#ifdef GLUTMAINLLOP +void +display(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + glFlush(); +} +#endif + +void BindMsgOfFile( const char * regex_file ) +{ + char line[4096]; + size_t size; + FILE* file; + file = fopen( regex_file, "r" ); + if ( !file ) { + perror( "Regexp file open "); + return; + } + while( !feof( file ) ) + { + if ( fgets( line, sizeof(line), file ) ) + { + size = strlen(line); + if ( size > 1 ) + { + line[size-1] = '\0'; /* supress \n */ + IvyBindMsg (Callback, NULL, line); + } + } + } +} +void BuildFilterRegexp() +{ + char *word=strtok( classes, "," ); + while ( word != NULL && (filter_count < 4096 )) + { + filter[filter_count++] = word; + word = strtok( NULL, ","); + } + if ( filter_count ) + IvySetFilter( filter_count, filter ); +} +int main(int argc, char *argv[]) +{ + int c; + int timer_test = 0; + char busbuf [1024] = ""; + const char* bus = 0; + const char* regex_file = 0; + char agentnamebuf [1024] = ""; + const char* agentname = DEFAULT_IVYPROBE_NAME; + char agentready [1024] = ""; + const char* helpmsg = + "[options] [regexps]\n\t-b bus\tdefines the Ivy bus to which to connect to, defaults to 127:2010\n" + "\t-t\ttriggers the timer test\n" + "\t-n name\tchanges the name of the agent, defaults to IVYPROBE\n" + "\t-v\tprints the ivy relase number\n\n" + "regexp is a Perl5 compatible regular expression (see ivyprobe(1) and pcrepattern(3) for more info\n" + "use .help within ivyprobe\n" + "\t-s bindcall\tactive the interception of regexp's subscribing or unscribing\n" + "\t-f regexfile\tread list of regexp's from file one by line\n" + "\t-c msg1,msg2,msg3,...\tfilter the regexp's not beginning with words\n" + ; + while ((c = getopt(argc, argv, "vn:d:b:w:t:sf:c:")) != EOF) + switch (c) { + case 'b': + strcpy (busbuf, optarg); + bus = busbuf; + break; + case 'w': + wait_count = atoi(optarg) ; + break; + case 'f': + regex_file = optarg ; + break; + case 'n': + strcpy(agentnamebuf, optarg); + agentname=agentnamebuf; + case 'v': + printf("ivy c library version %d.%d\n",IVYMAJOR_VERSION,IVYMINOR_VERSION); + break; + case 't': + timer_test = 1; + break; + case 's': + fbindcallback=1; + break; + case 'c': + classes= strdup(optarg); + break; + default: + printf("usage: %s %s",argv[0],helpmsg); + exit(1); + } + sprintf(agentready,"%s Ready",agentname); + + /* Mainloop management */ +#ifdef XTMAINLOOP + /*XtToolkitInitialize();*/ + cntx = XtCreateApplicationContext(); + IvyXtChannelAppContext (cntx); +#endif +#ifdef GLUTMAINLLOOP + glutInit(&argc, argv); + glutCreateWindow("IvyProbe Test"); + glClearColor(0.49, 0.62, 0.75, 0.0); + glutDisplayFunc(display); +#endif + IvyInit (agentname, agentready, ApplicationCallback,NULL,NULL,NULL); + IvySetBindCallback(IvyPrintBindCallback, NULL); + + IvyBindDirectMsg( DirectCallback,NULL); + if ( classes ) + BuildFilterRegexp(); + if ( regex_file ) + BindMsgOfFile( regex_file ); + for (; optind < argc; optind++) + IvyBindMsg (Callback, NULL, argv[optind]); + + if (wait_count == 0) +#ifndef WIN32 +/* Stdin not compatible with select , select only accept socket */ + IvyChannelAdd (0, NULL, NULL, HandleStdin, NULL); +#endif + + IvyStart (bus); + + if (timer_test) { +#ifdef IVYMAINLOOP + TimerRepeatAfter (TIMER_LOOP, 1000, TimerCall, (void*)1); + TimerRepeatAfter (5, 5000, TimerCall, (void*)5); +#endif + } + +#ifdef XTMAINLOOP + XtAppMainLoop (cntx); +#endif +#ifdef GLIBMAINLOOP + { + GMainLoop *ml = g_main_loop_new(NULL, FALSE); + g_main_loop_run(ml); + } +#endif +#ifdef GLUTMAINLOOP + glutMainLoop(); +#endif + +#ifdef IVYMAINLOOP + IvyMainLoop (); +#endif + return 0; +} + diff --git a/tools/ivyprobe_omp b/tools/ivyprobe_omp new file mode 100755 index 0000000..37afc69 Binary files /dev/null and b/tools/ivyprobe_omp differ diff --git a/tools/ivythroughput.cpp b/tools/ivythroughput.cpp new file mode 100644 index 0000000..17e5e54 --- /dev/null +++ b/tools/ivythroughput.cpp @@ -0,0 +1,628 @@ +/* + * IvyThroughput + * + * Copyright (C) 2008 + * Centre d'Études de la Navigation Aérienne + */ + + +// g++ ivythroughput.cpp -o ivythroughput -L/usr/local/lib64/ -Wl,-rpath,/usr/local/lib64/ -livy -lpcrecpp + +/* SCENARIO + + ° traitement des options : + -v (affi version) -b bus, -r regexp file, -m message file, -n : nombre de recepteurs + -t [type de test => ml (memory leak), tp (throughput) + + test memory leak + ° fork d'un emetteur et d'un (ou plusieurs) recepteur : le recepteur s'abonne à toutes les regexps, + se desabonne, se reabonne etc etc en boucle : on teste que l'empreinte mémoire + de l'emetteur ne grossisse pas + + test throughput : + ° fork d'un emetteur et d'un ou plusieurs recepteurs : les recepteurs s'abonnent à toutes les regexps + ° l'emetteur envoie en boucle tous les messages du fichier de message + ° l'emetteur note le temps d'envoi des messages + ° l'emetteur envoie un die all et quitte +*/ + +#include +#include +#include +#include "version.h" +#include +#include +#include +#include +#include +#include +#include + +#include "ivysocket.h" +#include "ivy.h" +#include "timer.h" +#include "ivyloop.h" +#include + +#include +#include +#include + +typedef std::list ListOfString; +typedef std::list ListOfPid; +typedef std::map MapUintToBool; +typedef std::list ListOfMsgRcvPtr; + +typedef struct { + unsigned int currentBind; + unsigned int totalBind; +} InfoBind; +typedef std::map MapBindByClnt; + +#define MILLISEC 1000.0 + +typedef enum {memoryLeak1, memoryLeak2, throughput} KindOfTest ; + + +typedef struct { + ListOfMsgRcvPtr *bindIdList; + const ListOfString *regexps; + unsigned int inst; +} MlDataStruct; + + + +extern char *optarg; +extern int optind, opterr, optopt; + +void recepteur_tp (const char* bus, KindOfTest kod, unsigned int inst, + const ListOfString& regexps, unsigned int exitAfter); +void recepteur_ml (const char* bus, KindOfTest kod, unsigned int inst, + const ListOfString& regexps); +void emetteur (const char* bus, KindOfTest kod, int testDuration, + const ListOfString& messages, int regexpSize); + +bool getMessages (const char*fileName, ListOfString &messages); +bool getRegexps (const char*fileName, ListOfString ®exps); + +double currentTime(); +void binCB( IvyClientPtr app, void *user_data, int id, char* regexp, IvyBindEvent event ) ; +void binCBR( IvyClientPtr app, void *user_data, int id, char* regexp, IvyBindEvent event ) ; +void congestCB ( IvyClientPtr app, void *user_data, IvyApplicationEvent event ) ; +void stopCB (TimerId id, void *user_data, unsigned long delta); +void sendAllMessageCB (TimerId id, void *user_data, unsigned long delta); +void recepteurReadyCB (IvyClientPtr app, void *user_data, int argc, char *argv[]); +void recepteurCB (IvyClientPtr app, void *user_data, int argc, char *argv[]); +void startOfSeqCB (IvyClientPtr app, void *user_data, int argc, char *argv[]); +void endOfSeqCB (IvyClientPtr app, void *user_data, int argc, char *argv[]); +void desabonneEtReabonneCB (TimerId id, void *user_data, unsigned long delta); +void changeRegexpCB (TimerId id, void *user_data, unsigned long delta); +void exitCB (TimerId id, void *user_data, unsigned long delta); + +unsigned int nbMess=0, nbReg=0, numClients =1, globalInst; +MapUintToBool recReady; +KindOfTest kindOfTest = throughput; +bool regexpAreUniq = false; + +int main(int argc, char *argv[]) +{ + int c; + int testDuration = 10; + char *bus ; + char regexpFile[1024] = "testivy/regexp.txt"; + char messageFile[1024] = "testivy/plantageradargl.ivy"; + ListOfString messages, regexps; + pid_t pid; + ListOfPid recPid; + + const char* helpmsg = + "[options] \n" + "\t -b bus\tdefines the Ivy bus to which to connect to, defaults to 127:2010\n" + "\t -v \t prints the ivy relase number\n\n" + "\t -t \t type of test : ml or ml2 (memory leak) or tp (throughput)\n" + "\t -r \t regexfile\tread list of regexp's from file\n" + "\t -p \t each client will prepend regexp with uniq string to " + "simulate N clients with differents regexps\n" + "\t -m \t messageFile\tread list of messages from file\n" + "\t -n \t number of clients\n" + "\t -d \t duration of the test in seconds\n" ; + + + if (getenv("IVYBUS") != NULL) { + bus = strdup (getenv("IVYBUS")); + } else { + bus = strdup ("127.0.0.1:2000") ; + } + + while ((c = getopt(argc, argv, "vpb:r:m:n:t:d:")) != EOF) + switch (c) { + case 'b': + strcpy (bus, optarg); + break; + case 'v': + printf("ivy c library version %d.%d\n",IVYMAJOR_VERSION, IVYMINOR_VERSION); + break; + case 'p': + regexpAreUniq = true; + break; + case 't': + if (strcasecmp (optarg, "ml") == 0) { + kindOfTest = memoryLeak1; + } else if (strcasecmp (optarg, "ml1") == 0) { + kindOfTest = memoryLeak1; + } else if (strcasecmp (optarg, "ml2") == 0) { + kindOfTest = memoryLeak2; + } else if (strcasecmp (optarg, "tp") == 0) { + kindOfTest = throughput; + } else { + printf("usage: %s %s",argv[0],helpmsg); + exit(1); + } + break; + case 'r': + strcpy (regexpFile, optarg); + break; + case 'm': + strcpy (messageFile, optarg); + break; + case 'n': + numClients = atoi (optarg); + break; + case 'd': + testDuration = atoi (optarg); + break; + default: + printf("usage: %s %s",argv[0],helpmsg); + exit(1); + } + + if (!getRegexps (regexpFile, regexps)) + {return (1);}; + + if (kindOfTest != memoryLeak1) { + if (!getMessages (messageFile, messages)) + {return (1);}; + } + + + + for (unsigned int i=0; i< numClients; i++) { + if ((pid = fork ()) == 0) { + // fils + switch (kindOfTest) { + case throughput : + recepteur_tp (bus, kindOfTest, i, regexps, 0); + break; + case memoryLeak1 : + recepteur_ml (bus, kindOfTest, i, regexps); + break; + case memoryLeak2 : + recepteur_tp (bus, kindOfTest, i, regexps, testDuration-5); + break; + } + exit (0); + } else { + recPid.push_back (pid); + recReady[i]=false; + } + } + + emetteur (bus, kindOfTest, testDuration, messages, regexps.size()); + + ListOfPid::iterator iter; + for (iter=recPid.begin(); iter != recPid.end(); iter++) { + kill (*iter, SIGTERM); + } + + for (iter=recPid.begin(); iter != recPid.end(); iter++) { + waitpid (*iter, NULL, 0); + } + + return (0); +} + + + + +/* +# _ _ +# | | | | +# ___ _ __ ___ ___ | |_ | |_ ___ _ _ _ __ +# / _ \ | '_ ` _ \ / _ \ | __| | __| / _ \ | | | | | '__| +# | __/ | | | | | | | __/ \ |_ \ |_ | __/ | |_| | | | +# \___| |_| |_| |_| \___| \__| \__| \___| \__,_| |_| +*/ +void emetteur (const char* bus, KindOfTest kod, int testDuration, + const ListOfString& messages, int regexpSize) +{ + printf ("DBG> emetteur start, pid=%d\n", getpid()); + IvyInit ("IvyThroughputEmit", "IvyThroughputEmit Ready", congestCB, NULL,NULL,NULL); + // double origin = currentTime(); + + + IvySetBindCallback (binCB, (void *) (regexpSize+2)); + IvyBindMsg (recepteurReadyCB, (void *) &messages, + "^IvyThroughputReceive_(\\d+)\\s+Ready"); + + TimerRepeatAfter (1, testDuration *1000, stopCB, NULL); + + IvyStart (bus); + IvyMainLoop (); +} + + + +/* +# _ __ _ +# | '_ \ | | +# _ __ ___ ___ ___ | |_) | | |_ ___ _ _ _ __ +# | '__| / _ \ / __| / _ \ | .__/ | __| / _ \ | | | | | '__| +# | | | __/ | (__ | __/ | | \ |_ | __/ | |_| | | | +# |_| \___| \___| \___| |_| \__| \___| \__,_| |_| +*/ +void recepteur_tp (const char* bus, KindOfTest kod, unsigned int inst, + const ListOfString& regexps, unsigned int exitAfter) +{ + std::string agentName = "IvyThroughputReceive_"; + std::stringstream stream ; + stream << inst; + agentName += stream.str(); + std::string agentNameReady (agentName + " Ready"); + //double origin = currentTime(); + globalInst = inst; + + printf ("DBG> recepteur_%d start, pid=%d\n", inst, getpid()); + IvyInit (agentName.c_str(), agentNameReady.c_str(), congestCB, NULL,NULL,NULL); + + unsigned int debugInt = 0; + ListOfString::const_iterator iter; + for (iter=regexps.begin(); iter != regexps.end(); iter++) { + debugInt++; + string reg = *iter; + if (regexpAreUniq) { (reg += " ") += stream.str();} + IvyBindMsg (recepteurCB, (void *) inst, reg.c_str()); + } + IvyBindMsg (startOfSeqCB, NULL, "^start(OfSequence)"); + IvyBindMsg (endOfSeqCB, NULL, "^end(OfSequence)"); + + if (kod == memoryLeak2) { + TimerRepeatAfter (1, exitAfter*1000, exitCB, NULL); + } + + //usleep (inst * 50 * 1000); + IvyStart (bus); + IvyMainLoop (); +} + +void recepteur_ml (const char* bus, KindOfTest kod, unsigned int inst, + const ListOfString& regexps) +{ + std::string agentName = "IvyThroughputReceive_"; + std::stringstream stream ; + stream << inst; + agentName += stream.str(); + std::string agentNameReady (agentName + " Ready"); + //double origin = currentTime(); + globalInst = inst; + static ListOfMsgRcvPtr bindIdList; + static MlDataStruct mds; + + printf ("DBG> recepteur_%d start, pid=%d\n", inst, getpid()); + IvyInit (agentName.c_str(), agentNameReady.c_str(), congestCB, NULL,NULL,NULL); + + unsigned int debugInt = 0; + ListOfString::const_iterator iter; + for (iter=regexps.begin(); iter != regexps.end(); iter++) { + debugInt++; + string reg = *iter; + if (regexpAreUniq) { (reg += " ") += stream.str();} + bindIdList.push_back (IvyBindMsg (recepteurCB, (void *) inst, reg.c_str())); + } + IvyBindMsg (startOfSeqCB, NULL, "^start(OfSequence)"); + IvyBindMsg (endOfSeqCB, NULL, "^end(OfSequence)"); + + mds.bindIdList = &bindIdList; + mds.regexps = ®exps; + mds.inst = inst; + + TimerRepeatAfter (1, 1000, desabonneEtReabonneCB, &mds); + //TimerRepeatAfter (1, 1000, abonneEtDesabonneCB, &mds); + + IvyStart (bus); + IvyMainLoop (); +} + +// =========================================================================== + + + +/* +# __ _ _ __ __ __ _ +# / _` | | | | \/ | / _` | +# | (_| | ___ | |_ | \ / | ___ ___ ___ __ _ | (_| | ___ +# \__, | / _ \ | __| | |\/| | / _ \ / __| / __| / _` | \__, | / _ \ +# __/ | | __/ \ |_ | | | | | __/ \__ \ \__ \ | (_| | __/ | | __/ +# |___/ \___| \__| |_| |_| \___| |___/ |___/ \__,_| |___/ \___| +*/ + +bool getMessages (const char*fileName, ListOfString &messages) +{ + FILE *infile; + char buffer [1024*64]; + pcrecpp::RE pcreg ("\"(.*)\"$"); + string aMsg; + + infile = fopen(fileName, "r"); + if (!infile) { + fprintf (stderr, "impossible d'ouvrir %s en lecture\n", fileName); + return false; + } + + while (fgets (buffer, sizeof (buffer), infile) != NULL) { + if (pcreg.PartialMatch (buffer, &aMsg)) { + messages.push_back (aMsg); + nbMess++; + } + } + fclose (infile); + return (true); +} + + +/* +# __ _ _ _____ __ _ _ __ +# / _` | | | | __ \ / _` | | '_ \ +# | (_| | ___ | |_ | |__) | ___ | (_| | ___ __ __ | |_) | ___ +# \__, | / _ \ | __| | _ / / _ \ \__, | / _ \ \ \/ / | .__/ / __| +# __/ | | __/ \ |_ | | \ \ | __/ __/ | | __/ > < | | \__ \ +# |___/ \___| \__| |_| \_\ \___| |___/ \___| /_/\_\ |_| |___/ +*/ +bool getRegexps (const char*fileName, ListOfString ®exps) +{ + FILE *infile; + char buffer [1024*64]; + pcrecpp::RE pcreg ("add regexp \\d+ : (.*)$"); + string aMsg; + + infile = fopen(fileName, "r"); + if (!infile) { + fprintf (stderr, "impossible d'ouvrir %s en lecture\n", fileName); + return false; + } + + while (fgets (buffer, sizeof (buffer), infile) != NULL) { + if (pcreg.PartialMatch (buffer, &aMsg)) { + regexps.push_back (aMsg); + nbReg++; + } + } + fclose (infile); + + return (true); +} + + + +/* +# _______ _ +# |__ __| (_) +# ___ _ _ _ __ _ __ | | _ _ __ ___ ___ +# / __| | | | | | '__| | '__| | | | | | '_ ` _ \ / _ \ +# | (__ | |_| | | | | | | | | | | | | | | | | __/ +# \___| \__,_| |_| |_| |_| |_| |_| |_| |_| \___| +*/ +double currentTime() +{ + double current; + + struct timeval stamp; + gettimeofday( &stamp, NULL ); + current = (double)stamp.tv_sec * MILLISEC + (double)(stamp.tv_usec/MILLISEC); + return current; +} + + +/* +# _ _ _____ ____ +# | | (_) / ____| | _ \ +# | |__ _ _ __ | | | |_) | +# | '_ \ | | | '_ \ | | | _ < +# | |_) | | | | | | | | |____ | |_) | +# |_.__/ |_| |_| |_| \_____| |____/ +*/ +void binCB( IvyClientPtr app, void *user_data, int id, char* regexp, IvyBindEvent event ) +{ + string appName = IvyGetApplicationName( app ); + static MapBindByClnt bindByClnt; + + if (bindByClnt.find (appName) == bindByClnt.end()) { + (bindByClnt[appName]).currentBind = 0; + (bindByClnt[appName]).totalBind = (unsigned long) user_data; + } + + switch ( event ) + { + case IvyAddBind: + (bindByClnt[appName]).currentBind ++; + if ((bindByClnt[appName]).currentBind == (bindByClnt[appName]).totalBind) { + printf("Application:%s ALL REGEXPS BINDED\n", appName.c_str()); + } else { + // printf("Application:%s bind [%d/%d]\n", appName.c_str(), + // (bindByClnt[appName]).currentBind, (bindByClnt[appName]).totalBind); + } + break; + case IvyRemoveBind: + if ((id % 10000) == 0) { + printf("Application:%s bind '%d' REMOVED\n", appName.c_str(), id ); + } + break; + case IvyFilterBind: + printf("Application:%s bind '%s' FILTRED\n", appName.c_str(), regexp ); + break; + case IvyChangeBind: + printf("Application:%s bind '%s' CHANGED\n", appName.c_str(), regexp ); + break; + } +} + + + +void congestCB ( IvyClientPtr app, void *user_data, IvyApplicationEvent event ) +{ + string appName = IvyGetApplicationName( app ); + + switch ( event ) { + case IvyApplicationCongestion: + printf("Application:%s : Congestion\n", appName.c_str()); + break; + case IvyApplicationDecongestion: + printf("Application:%s : DEcongestion\n", appName.c_str()); + break; + case IvyApplicationFifoFull: + printf("Application:%s : FIFO PLEINE, MESSAGES PERDUS !!!\n", appName.c_str()); + break; + case IvyApplicationConnected: + // printf("Application:%s : Connected\n", appName.c_str()); + case IvyApplicationDisconnected: + // printf("Application:%s : Disconnected\n", appName.c_str()); + break; + } +} + + + + +void stopCB (TimerId id, void *user_data, unsigned long delta) +{ + IvyStop (); +} + + +void sendAllMessageCB (TimerId id, void *user_data, unsigned long delta) +{ + ListOfString *messages = (ListOfString *) user_data; + double startTime = currentTime(); + unsigned int envoyes=0; + + IvySendMsg ("startOfSequence"); + ListOfString::iterator iter; + for (iter=messages->begin(); iter != messages->end(); iter++) { + envoyes += IvySendMsg ((*iter).c_str()); + } + IvySendMsg ("endOfSequence"); + + printf ("[ivy %d.%d] envoyer [%d/%d] messages filtrés par %d regexps a %d clients " + "prends %.1f secondes\n", + IVYMAJOR_VERSION, IVYMINOR_VERSION, + envoyes, nbMess, nbReg, numClients, + (currentTime()-startTime) / 1000.0) ; + TimerRepeatAfter (1, 1000, sendAllMessageCB ,user_data); +} + +void recepteurCB (IvyClientPtr app, void *user_data, int argc, char *argv[]) +{ + // unsigned long recN = (long) user_data; + // printf ("."); + // if (!((argc == 1) && (strcmp (argv[0], "OfSequence")) == 0)) + nbMess++; +} + + +void recepteurReadyCB (IvyClientPtr app, void *user_data, int argc, char *argv[]) +{ + ListOfString *messages = (ListOfString *) user_data; + unsigned int instance = atoi( *argv++ ); + + recReady[instance] = true; + bool readyToStart = true; + + for (unsigned int i=0; i< numClients; i++) { + if (recReady[i]==false) { + // printf ("Emetteur : manque recepteur [%d/%d]\n", i, numClients-1); + readyToStart = false; + } + } + + if (readyToStart == true) { + if (kindOfTest != memoryLeak1) { + TimerRepeatAfter (1, 100, sendAllMessageCB , messages); + printf ("Emetteur : tous recepteurs prets : on envoie la puree !!\n"); + } + } else { + printf ("\n"); + } +} + + + +void startOfSeqCB (IvyClientPtr app, void *user_data, int argc, char *argv[]) +{ + nbMess = 0; +} + + +void endOfSeqCB (IvyClientPtr app, void *user_data, int argc, char *argv[]) +{ + //nbMess--; + printf ("recepteur %d a recu %d messages\n", globalInst, nbMess); +} + + +void desabonneEtReabonneCB (TimerId id, void *user_data, unsigned long delta) +{ + MlDataStruct *mds = (MlDataStruct *) user_data; + + // printf ("on entre dans desabonneEtReabonneCB\n"); + + ListOfMsgRcvPtr::iterator iter; + + // DESABONNE + for (iter=mds->bindIdList->begin(); iter != mds->bindIdList->end(); iter++) { + IvyUnbindMsg (*iter); + } + mds->bindIdList->clear (); + + // REABONNE + ListOfString::const_iterator iter2; + for (iter2=mds->regexps->begin(); iter2 != mds->regexps->end(); iter2++) { + string reg = *iter2; + mds->bindIdList->push_back (IvyBindMsg (recepteurCB, (void *) mds->inst, reg.c_str())); + } + + // CHANGE REGEXP + for (iter=mds->bindIdList->begin(); iter != mds->bindIdList->end(); iter++) { + IvyChangeMsg (*iter, "^Une regexp (BIDON)"); + } + + + // DESABONNE + for (iter=mds->bindIdList->begin(); iter != mds->bindIdList->end(); iter++) { + IvyUnbindMsg (*iter); + } + mds->bindIdList->clear (); + + //TimerRepeatAfter (1, 1000, changeRegexpCB, mds); +} + + +void changeRegexpCB (TimerId id, void *user_data, unsigned long delta) +{ + MlDataStruct *mds = (MlDataStruct *) user_data; + + // printf ("on entre dans abonneEtDesabonneCB\n"); + + ListOfMsgRcvPtr::iterator iter; + + + for (iter=mds->bindIdList->begin(); iter != mds->bindIdList->end(); iter++) { + IvyChangeMsg (*iter, "^Une regexp (BIDON)"); + } + + TimerRepeatAfter (1, 1000, changeRegexpCB, mds); +} + +void exitCB (TimerId id, void *user_data, unsigned long delta) +{ + printf ("DBG> client exit\n"); + exit (0); +} diff --git a/tools/ivythroughput_omp b/tools/ivythroughput_omp new file mode 100755 index 0000000..146666d Binary files /dev/null and b/tools/ivythroughput_omp differ -- cgit v1.1