Première version

This commit is contained in:
smas
2000-07-28 15:34:22 +00:00
commit 961ddc46da
14 changed files with 6065 additions and 0 deletions

235
util/msgadmin.c Normal file
View File

@@ -0,0 +1,235 @@
#define DATASTR_MODE 1 /* Pas de vérif des arguments + verrou sytématique */
#define MSG_MODE 1 /* Pas de vérif des arguments */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <sys/time.h>
#include <ver.h>
#include <datastr.h>
#include <msg.h>
VER_INFO_EXPORT (msgadmin, "$Revision: 1.1 $", "$Name: $", __FILE__, "$Author: smas $")
#define USAGE "Usage : %s [ --help | --version [-v] | --create | --destroy ]\n"
#define QUIT 0
#define BASE_INIT 1
#define BASE_OPEN 2
#define BASE_INFO 3
#define BASE_CLOSE 4
#define BASE_END 5
#define SHOW_PORT_LIST 6
#define PORT_CREATE 7
#define PORT_DUMP 8
#define PORT_FLUSH 9
#define PORT_DELETE 10
char menu [1000];
char tmp [100];
void init_menu (void);
int print_menu (void);
int main (int argc, char ** argv)
{
int choice;
MSGT_Port * Port;
MSGT_Message * Msg;
char Answer[10];
/* Lancement de commande d'administration */
if (argc >= 2)
{
if (!strcmp (argv[1], "--help"))
{
fprintf (stderr, USAGE, argv[0]);
return -1;
}
else if (!strcmp (argv[1], "--version"))
{
if (argc >= 3 && !strcmp (argv[2], "-v")) return VER_Object_Print (stdout, VERD_VERBOSE);
else return VER_Object_Print (stdout, VERD_MINIMAL);
}
else if (!strcmp (argv[1], "--create"))
{
if (MSG_Library_Open (0, NULL, MSGD_CREATE | MSGD_DEBUG_ALL) != MSGS_OK)
{
fprintf (stderr, "=> Impossible de créer l'instance de la librairie LIBMSG\n");
return -1;
}
return 1;
}
else if (!strcmp (argv[1], "--destroy"))
{
if (MSG_Library_Open (0, NULL, MSGD_OPEN | MSGD_DEBUG_ALL) != MSGS_OK || MSG_Library_Close (MSGD_DESTROY) != MSGS_OK)
{
fprintf (stderr, "=> Impossible de détruire l'instance de la librairie LIBMSG\n");
return -1;
}
return 0;
}
else
{
fprintf (stderr, USAGE, argv[0]);
return -1;
}
}
/* Lancement du menu intercatif */
init_menu ();
choice = print_menu ();
while (choice != QUIT)
{
strcpy (Answer, "yes");
switch (choice)
{
case BASE_INIT:
fprintf (stdout, "\nReturn code = %s\n", \
MSG_Library_Open (0, NULL, MSGD_CREATE | MSGD_DEBUG_ALL) == MSGS_OK ? "OK" : "NOK" );
break;
case BASE_OPEN:
fprintf (stdout, "\nReturn code = %s\n", \
MSG_Library_Open (0, NULL, MSGD_OPEN | MSGD_DEBUG_ALL) == MSGS_OK ? "OK" : "NOK" );
break;
case BASE_END:
fprintf (stdout, "\nReturn code = %s\n", \
MSG_Library_Close (MSGD_DESTROY) == MSGS_OK ? "OK" : "NOK" );
break;
case BASE_CLOSE:
fprintf (stdout, "\nReturn code = %s\n", \
MSG_Library_Close (MSGD_CLOSE) == MSGS_OK ? "OK" : "NOK" );
break;
case BASE_INFO:
if (!MSG_Base)
fprintf (stdout, "\nLIBMSG base must be opened first\n");
else
DS_DataStruct_Info_Print (MSG_Base->Port_List, stdout);
break;
case SHOW_PORT_LIST:
if (!MSG_Base) fprintf (stdout, "\nLIBMSG base must be opened first\n");
else DS_DataStruct_Print (MSG_Base->Port_List, stdout);
break;
case PORT_CREATE:
if (!MSG_Base) fprintf (stdout, "\nLIBMSG base must be opened first\n");
else
{
fprintf (stdout, "\nPort name ? ");
gets (tmp);
if (MSG_Port_Open (tmp, &Port, MSGD_CREATE) != MSGS_OK)
fprintf (stdout, "Unable to create port \"%s\"\n", tmp);
}
break;
case PORT_DUMP:
if (!MSG_Base) fprintf (stdout, "\nLIBMSG base must be opened first\n");
else
{
fprintf (stdout, "\nPort name ? ");
gets (tmp);
if (MSG_Port_Open (tmp, &Port, MSGD_OPEN) != MSGS_OK)
fprintf (stdout, "Unable to open port \"%s\"\n", tmp);
else
{
ND_Manager_Exec (MSG_Base->Port_List->Manager, NDD_CMD_PRINT_VALUE, Port, stdout);
if (fprintf (stdout, "\n\nShow message queue ? (y/n) ") && gets (tmp) && *tmp == 'y')
DS_DataStruct_Print (Port->MsgQueue, stdout);
if (fprintf (stdout, "\nShow semaphore list ? (y/n) ") && gets (tmp) && *tmp == 'y')
DS_DataStruct_Print (Port->SemList, stdout);
}
}
break;
case PORT_FLUSH:
if (!MSG_Base) fprintf (stdout, "\nLIBMSG base must be opened first\n");
else
{
fprintf (stdout, "\nPort name ? ");
gets (tmp);
if (MSG_Port_Open (tmp, &Port, MSGD_OPEN) != MSGS_OK)
fprintf (stdout, "Unable to open port \"%s\"\n", tmp);
/* Retrait de tous les messages du port */
while (MSG_Message_Receive (Port, MSGD_NO_TYPE, &Msg, MSGD_NO_WAIT) == MSGS_OK)
MSG_Message_Free (Msg);
}
break;
case PORT_DELETE:
if (!MSG_Base) fprintf (stdout, "\nLIBMSG base must be opened first\n");
else
{
fprintf (stdout, "\nPort name ? ");
gets (tmp);
if (MSG_Port_Exist (tmp, &Port) != MSGS_OK)
{
fprintf (stdout, "Port \"%s\" does not exist\n", tmp);
break;
}
if (MSG_Port_Close (Port, MSGD_DESTROY) != MSGS_OK)
fprintf (stdout, "Unable to delete port \"%s\"\n", tmp);
}
break;
case QUIT:
fprintf (stdout, "\nExiting program ...\n");
break;
default:
fprintf (stdout, "\nUndefined choice %d\n", choice);
}
choice = print_menu ();
}
return 0;
}
void init_menu (void)
{
sprintf (menu, "Menu :\n");
sprintf (tmp, " - %2d) %-25s", QUIT, "Quit"); strcat (menu, tmp);
sprintf (tmp, " - %2d) %-25s\n", BASE_INIT, "Init library"); strcat (menu, tmp);
sprintf (tmp, " - %2d) %-25s", BASE_OPEN, "Open library"); strcat (menu, tmp);
sprintf (tmp, " - %2d) %-25s\n", BASE_INFO, "Info library"); strcat (menu, tmp);
sprintf (tmp, " - %2d) %-25s", BASE_CLOSE, "Close library"); strcat (menu, tmp);
sprintf (tmp, " - %2d) %-25s\n", BASE_END, "End library"); strcat (menu, tmp);
sprintf (tmp, " - %2d) %-25s", SHOW_PORT_LIST, "Show message ports"); strcat (menu, tmp);
sprintf (tmp, " - %2d) %-25s\n", PORT_CREATE, "Create a message port"); strcat (menu, tmp);
sprintf (tmp, " - %2d) %-25s", PORT_DUMP, "Dump a message port"); strcat (menu, tmp);
sprintf (tmp, " - %2d) %-25s\n", PORT_FLUSH, "Flush all message from a port"); strcat (menu, tmp);
sprintf (tmp, " - %2d) %-25s\n", PORT_DELETE, "Delete a message port"); strcat (menu, tmp);
}
int print_menu (void)
{
fprintf (stdout, "---------------------------------------------------------------------------\n%s", menu);
tmp[0] = '\0';
while (tmp[0] == '\0')
{
printf ("\nChoice ? ");
gets (tmp);
}
return atoi (tmp);
}

BIN
util/msgbench.xls Normal file

Binary file not shown.

40
util/pingpong.result.cc Normal file
View File

@@ -0,0 +1,40 @@
-------------- TEST LIBMSG -----------------
Testing LIBMSG for 10 second(s) with 1 message(s) of 10 byte(s)...
20450 message(s) exchanged (2045 msg/sec)
Testing LIBMSG for 10 second(s) with 1 message(s) of 1000 byte(s)...
20244 message(s) exchanged (2024 msg/sec)
Testing LIBMSG for 10 second(s) with 1 message(s) of 2048 byte(s)...
19520 message(s) exchanged (1952 msg/sec)
---------
Testing LIBMSG for 10 second(s) with 10 message(s) of 10 byte(s)...
30752 message(s) exchanged (3075 msg/sec)
Testing LIBMSG for 10 second(s) with 10 message(s) of 1000 byte(s)...
30220 message(s) exchanged (3022 msg/sec)
Testing LIBMSG for 10 second(s) with 10 message(s) of 2048 byte(s)...
28590 message(s) exchanged (2859 msg/sec)
---------
Testing LIBMSG for 10 second(s) with 100 message(s) of 10 byte(s)...
27008 message(s) exchanged (2700 msg/sec)
Testing LIBMSG for 10 second(s) with 100 message(s) of 1000 byte(s)...
24970 message(s) exchanged (2497 msg/sec)
Testing LIBMSG for 10 second(s) with 100 message(s) of 2048 byte(s)...
21838 message(s) exchanged (2183 msg/sec)
-------------- TEST IPC -----------------
Testing IPC message queue for 10 second (s) with 1 message (s) of 10 byte (s)...
169485 message (s) exchanged (16948 Msg/sec)
Testing IPC message queue for 10 second (s) with 1 message (s) of 1000 byte (s)...
102630 message (s) exchanged (10263 Msg/sec)
Testing IPC message queue for 10 second (s) with 1 message (s) of 2048 byte (s)...
102040 message (s) exchanged (10204 Msg/sec)
---------
Testing IPC message queue for 10 second (s) with 10 message (s) of 10 byte (s)...
300810 message (s) exchanged (30081 Msg/sec)
Testing IPC message queue for 10 second (s) with 10 message (s) of 1000 byte (s)...
159352 message (s) exchanged (15935 Msg/sec)
Testing IPC message queue for 10 second (s) with 10 message (s) of 2048 byte (s)...
127773 message (s) exchanged (12777 Msg/sec)
---------
Testing IPC message queue for 10 second (s) with 100 message (s) of 1000 byte (s)...
175376 message (s) exchanged (17537 Msg/sec)
Testing IPC message queue for 10 second (s) with 100 message (s) of 2048 byte (s)...
121655 message (s) exchanged (12165 Msg/sec)

40
util/pingpong.result.gcc Normal file
View File

@@ -0,0 +1,40 @@
-------------- TEST LIBMSG -----------------
Testing LIBMSG for 10 second(s) with 1 message(s) of 10 byte(s)...
30364 message(s) exchanged (3036 msg/sec)
Testing LIBMSG for 10 second(s) with 1 message(s) of 1000 byte(s)...
29490 message(s) exchanged (2949 msg/sec)
Testing LIBMSG for 10 second(s) with 1 message(s) of 2048 byte(s)...
32788 message(s) exchanged (3278 msg/sec)
---------
Testing LIBMSG for 10 second(s) with 10 message(s) of 10 byte(s)...
32203 message(s) exchanged (3220 msg/sec)
Testing LIBMSG for 10 second(s) with 10 message(s) of 1000 byte(s)...
36712 message(s) exchanged (3671 msg/sec)
Testing LIBMSG for 10 second(s) with 10 message(s) of 2048 byte(s)...
34887 message(s) exchanged (3488 msg/sec)
---------
Testing LIBMSG for 10 second(s) with 100 message(s) of 10 byte(s)...
24382 message(s) exchanged (2438 msg/sec)
Testing LIBMSG for 10 second(s) with 100 message(s) of 1000 byte(s)...
24552 message(s) exchanged (2455 msg/sec)
Testing LIBMSG for 10 second(s) with 100 message(s) of 2048 byte(s)...
25862 message(s) exchanged (2586 msg/sec)
-------------- TEST IPC -----------------
Testing IPC message queue for 10 second (s) with 1 message (s) of 10 byte (s)...
162587 message (s) exchanged (16258 Msg/sec)
Testing IPC message queue for 10 second (s) with 1 message (s) of 1000 byte (s)...
106886 message (s) exchanged (10688 Msg/sec)
Testing IPC message queue for 10 second (s) with 1 message (s) of 2048 byte (s)...
88864 message (s) exchanged (8886 Msg/sec)
---------
Testing IPC message queue for 10 second (s) with 10 message (s) of 10 byte (s)...
267204 message (s) exchanged (26720 Msg/sec)
Testing IPC message queue for 10 second (s) with 10 message (s) of 1000 byte (s)...
167169 message (s) exchanged (16716 Msg/sec)
Testing IPC message queue for 10 second (s) with 10 message (s) of 2048 byte (s)...
121365 message (s) exchanged (12136 Msg/sec)
---------
Testing IPC message queue for 10 second (s) with 100 message (s) of 1000 byte (s)...
165790 message (s) exchanged (16579 Msg/sec)
Testing IPC message queue for 10 second (s) with 100 message (s) of 2048 byte (s)...
122897 message (s) exchanged (12289 Msg/sec)

579
util/pingpong_ipc.c Normal file
View File

@@ -0,0 +1,579 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#include <time.h>
#include <signal.h>
#define DEFAULT_TIMER 60 /* Durée par défaut du test (en secondes) */
#define DEFAULT_WINSIZE 100 /* Taille par défaut de la fenêtre de messages */
#define DEFAULT_MSGSIZE 100 /* Taille par défaut de chaque message */
#define FATHER_KEY 64 /* Clé du port de messages du père */
#define CHILD_KEY 65 /* Clé du port de messages du fils */
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
/*----------------------------------------------------------------*/
typedef struct {
long mtype;
char * mtext;
} T_Msg;
int My_Port, Its_Port;
int Child_Pid, Father_Pid, Its_Pid, My_Pid;
int Verbose;
unsigned int Timer;
unsigned int Win_Size;
unsigned int Msg_Size;
int Cpt_Msg;
T_Msg ** Msg_Window;
int End_Test, End_Sigum;
char * error_code (void);
void stop_test (int);
void stop_father (void);
void stop_child (void);
void clean (int);
void trace (char *);
void print_result (void);
void parse_arg (int, char **);
extern char * strdup (const char *);
/*----------------------------------------------------------------*/
int main (int argc, char ** argv)
{
unsigned int i, size;
char str [256];
T_Msg * Msg;
/* Récupération des arguments de la ligne de commande */
parse_arg (argc, argv);
/* Récupération du no de process courant */
Father_Pid = getpid ();
/* Création d'un process fils avec qui dialoguer */
if ((Child_Pid = fork ()) != 0)
{
/*--------- Code pour le process père -----------*/
Its_Pid = Child_Pid;
My_Pid = Father_Pid;
My_Port = 0;
signal (SIGINT, stop_test);
signal (SIGUSR1, stop_test);
/* Création d'un port de messages */
if ((My_Port = msgget (FATHER_KEY, 0777|IPC_CREAT|IPC_EXCL)) == -1)
{
fprintf (stderr, "Unable to create message queue for the father process : error %d (%s)\n", errno, error_code ());
clean (TRUE);
return 0;
}
else
{
sprintf (str, "Message port %d created", My_Port);
trace (str);
}
/* On attend que le fils ait créé son port de messages */
sleep (2);
/* Initialisation de la fenêtre de messages */
Msg_Window = (T_Msg **)malloc (Win_Size);
for (i = 0; i < Win_Size; i++)
{
Msg_Window[i] = (T_Msg *)malloc (sizeof (T_Msg));
Msg_Window[i]->mtype = 1;
Msg_Window[i]->mtext = (char *)malloc (Msg_Size);
Msg_Window[i]->mtext[0] = (char)i;
}
/* Récupération de la port de messages du fils */
if ((Its_Port = msgget (CHILD_KEY, 0)) == -1)
{
fprintf (stderr, "Unable to retrieve the message queue of the child process : error %d (%s)\n", errno, error_code ());
clean (TRUE);
return 0;
}
Msg = malloc (sizeof (T_Msg));
Msg->mtext = (char *)malloc (Msg_Size);
/* Initialisation du Timer */
signal (SIGALRM, stop_test);
alarm (Timer);
/* Début du test : traitement des messages */
fprintf (stdout, "Testing IPC message queue for %d second (s) with %d message (s) of %d byte (s)...\n", Timer, Win_Size, Msg_Size);
/* Envoi de tous les messages de la fenêtre au fils */
for (i = 0; i < Win_Size; i++)
{
errno = 0;
if (msgsnd (Its_Port, Msg_Window[i], Msg_Size, IPC_NOWAIT) == 0)
{
if (Verbose)
{
sprintf (str, "Message %d sent to port %d", i, Its_Port);
trace (str);
}
}
if (errno != 0 && errno != EAGAIN)
fprintf (stderr, "Unable to send message %d to port %d : error %d (%s)\n", i, Its_Port, errno, error_code ());
}
Cpt_Msg = 0;
while (End_Test == FALSE)
{
/* Réception de messages */
errno = 0;
if ((size = msgrcv (My_Port, Msg, Msg_Size, 0, MSG_NOERROR)) > 0)
{
i = (int)(Msg->mtext[0]);
if (Verbose)
{
sprintf (str, "Message %d received from port %d", i, My_Port);
trace (str);
}
Cpt_Msg++;
/* Réenvoi du message au fils */
errno = 0;
if (msgsnd (Its_Port, Msg_Window[i], Msg_Size, IPC_NOWAIT) == 0)
{
if (Verbose)
{
sprintf (str, "Message %d replied", i);
trace (str);
}
}
if (errno != 0 && errno != EAGAIN)
fprintf (stderr, "Unable to reply message %d to port %d (%s)\n", i, Its_Port, error_code ());
}
if (errno != 0)
fprintf (stderr, "Unable to receive a message from port %d (%s)\n", My_Port, error_code ());
}
stop_father ();
}
else
{
/*---------- Code pour le process fils ----------*/
My_Pid = getpid ();
Its_Pid = Father_Pid;
My_Port = 0;
/* Trap du signal SIGUSR1 envoyé par le process père à la fin du test */
signal (SIGUSR1, stop_test);
signal (SIGINT, stop_test);
/* Création d'un port de messages */
if ((My_Port = msgget (CHILD_KEY, 0777|IPC_CREAT|IPC_EXCL)) == -1)
{
fprintf (stderr, "Unable to create message queue for the child process (%s)\n", error_code ());
clean (TRUE);
return 0;
}
else
{
sprintf (str, "Message port %d created", My_Port);
trace (str);
}
/* On attend que le père ait créé son port de messages */
sleep (2);
Msg_Window = (T_Msg **)malloc (Win_Size);
for (i = 0; i < Win_Size; i++)
{
Msg_Window[i] = (T_Msg *)malloc (sizeof (T_Msg));
Msg_Window[i]->mtype = 1;
Msg_Window[i]->mtext = (char *)malloc (Msg_Size * sizeof (char));
Msg_Window[i]->mtext[0] = (char)i;
}
/* Récupération du port de messages du père */
if ((Its_Port = msgget (FATHER_KEY, 0)) == -1)
{
fprintf (stderr, "Unable to retrieve the message queue of the father process (%s)\n", error_code ());
clean (TRUE);
return 0;
}
/* Traitement des messages */
Msg = malloc (sizeof (T_Msg));
Msg->mtext = (char *)malloc (Msg_Size * sizeof (char));
while (End_Test == FALSE)
{
/* Réception de messages */
errno = 0;
if ((size = msgrcv (My_Port, Msg, Msg_Size, 0, MSG_NOERROR)) > 0)
{
i = (int)(Msg->mtext[0]);
if (Verbose)
{
sprintf (str, "Message %d received from port %d", i, My_Port);
trace (str);
}
Cpt_Msg++;
/* Réenvoi du message au fils */
errno = 0;
if (msgsnd (Its_Port, Msg_Window[i], Msg_Size, IPC_NOWAIT) == 0)
{
if (Verbose)
{
sprintf (str, "Message %d replied", i);
trace (str);
}
}
if (errno != 0 && errno != EAGAIN)
fprintf (stderr, "Unable to reply message %d to port %d (%s)\n", i, Its_Port, error_code ());
}
if (errno != 0)
fprintf (stderr, "Unable to receive a message from port %d (%s)\n", My_Port, error_code ());
}
stop_child ();
}
return 0;
}
/*----------------------------------------------------------------*/
void stop_test (int signum)
{
End_Sigum = signum;
End_Test = TRUE;
}
/*----------------------------------------------------------------*/
void stop_father (void)
{
switch (End_Sigum)
{
case SIGINT:
/* Fin initiée par l'utilisateur : ménage simple */
case SIGUSR1:
/* Fin anormale en provenance du fils : ménage simple */
clean (FALSE);
break;
case SIGALRM:
/* Fin normale : ménage + stop du fils + affichage du réultat */
clean (TRUE);
print_result ();
break;
default:
/* Fin anormale sur le process père : ménage + avertit le process fils */
clean (TRUE);
break;
}
exit (1);
}
/*----------------------------------------------------------------*/
void print_result (void)
{
/* Affichage du résultat du test */
fprintf (stdout, "%d message (s) exchanged (%d Msg/sec)\n", Cpt_Msg, (int)(Cpt_Msg / Timer));
}
/*----------------------------------------------------------------*/
void stop_child (void)
{
switch (End_Sigum)
{
case SIGINT:
/* Fin initiée par l'utilisateur : ménage simple */
case SIGUSR1:
/* Fin initiée par le process père : ménage simple */
clean (FALSE);
break;
default:
/* Fin anormale sur le process fils : ménage + avertit le process père */
clean (TRUE);
break;
}
exit (0);
}
/*----------------------------------------------------------------*/
void clean (int warn)
{
unsigned int i;
char str [256];
/* On avertit l'autre process */
if (warn == TRUE) kill (Its_Pid, SIGUSR1);
if (Msg_Window != NULL)
{
for (i = 0; i < Win_Size; i++)
{
if (Msg_Window[i] != NULL)
{
if (Msg_Window[i]->mtext != NULL) free (Msg_Window[i]->mtext);
free (Msg_Window[i]);
}
}
free (Msg_Window);
}
/* Destruction de la port de messages */
if (My_Port > 0)
{
if (Verbose)
{
sprintf (str, "Removing message queue %d...\n", My_Port);
trace (str);
}
msgctl (My_Port, IPC_RMID, NULL);
}
}
/*----------------------------------------------------------------*/
char * error_code (void)
{
static char * str;
if (str) free (str);
switch (errno)
{
case EACCES:
str = strdup ("EACCES");
break;
case EEXIST:
str = strdup ("EEXIST");
break;
case EIDRM:
str = strdup ("EIDRM");
break;
case ENOENT:
str = strdup ("ENOENT");
break;
case ENOMEM:
str = strdup ("ENOMEM");
break;
case ENOSPC:
str = strdup ("ENOSPC");
break;
case EFAULT:
str = strdup ("EFAULT");
break;
case EINTR:
str = strdup ("EINTR");
break;
case EINVAL:
str = strdup ("EINVAL");
break;
case E2BIG:
str = strdup ("E2BIG");
break;
case ENOMSG:
str = strdup ("ENOMSG");
break;
case EAGAIN:
str = strdup ("EAGAIN");
break;
default:
str = strdup ("unknown");
break;
}
return str;
}
/*----------------------------------------------------------------*/
void trace (char *str)
{
time_t dts;
struct tm *dt;
char current_date [30];
char str_trace [256];
/* Get current date */
time (&dts);
dt = localtime (&dts);
sprintf (current_date, "%04d/%02d/%02d %02d:%02d:%02d", dt->tm_year + 1900, dt->tm_mon + 1, dt->tm_mday, dt->tm_hour, dt->tm_min, dt->tm_sec);
sprintf (str_trace, "Process %d - %s : %s\n", My_Pid, current_date, str);
fprintf (stderr, str_trace);
fflush (stderr);
}
/*----------------------------------------------------------------*/
void parse_arg (int argc, char ** argv)
{
int i;
Verbose = FALSE;
for (i = 1; i < argc; i++)
{
if (!strcmp (argv[i], "--help") || !strcmp (argv[i], "-h"))
{
fprintf (stdout, "Usage : %s [options]\n", argv[0]);
fprintf (stdout,"options :\n");
fprintf (stdout, "\t --help -h\n");
fprintf (stdout, "\t --clean\n");
fprintf (stdout, "\t --verbose\n");
fprintf (stdout, "\t --duration <time in seconds> (default is %d)\n", DEFAULT_TIMER);
fprintf (stdout, "\t --window <message number> (default is %d)\n", DEFAULT_WINSIZE);
fprintf (stdout, "\t --message <message size> (default is %d bytes)\n", DEFAULT_MSGSIZE);
exit (1);
}
if (!strcmp (argv[i], "--clean"))
{
if ((My_Port = msgget (FATHER_KEY, 0)) != -1) msgctl (My_Port, IPC_RMID, NULL);
if ((Its_Port = msgget (CHILD_KEY, 0)) != -1) msgctl (Its_Port, IPC_RMID, NULL);
exit (1);
}
if (!strcmp (argv[i], "--verbose"))
{
Verbose = TRUE;
continue;
}
if (!strcmp (argv[i], "--duration"))
{
i++;
if (i == argc)
{
fprintf (stderr, "Missing argument after %s\n", argv[i - 1]);
exit (0);
}
Timer = atoi (argv[i]);
continue;
}
if (!strcmp (argv[i], "--window"))
{
i++;
if (i == argc)
{
fprintf (stderr, "Missing argument after %s\n", argv[i - 1]);
exit (0);
}
Win_Size = atoi (argv[i]);
continue;
}
if (!strcmp (argv[i], "--message"))
{
i++;
if (i == argc)
{
fprintf (stderr, "Missing argument after %s\n", argv[i - 1]);
exit (0);
}
Msg_Size = atoi (argv[i]);
continue;
}
fprintf (stdout, "Unknown option '%s'\n", argv[i]);
exit (0);
}
if (Timer <= 0) Timer = DEFAULT_TIMER;
if (Win_Size <= 0) Win_Size = DEFAULT_WINSIZE;
if (Msg_Size <= 0) Msg_Size = DEFAULT_MSGSIZE;
}

543
util/pingpong_msg.c Normal file
View File

@@ -0,0 +1,543 @@
#define MSG_MODE 1
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <time.h>
#include <signal.h>
#include <shmem.h>
#include <msg.h>
VER_INFO_EXPORT (pingpong, "1.0", "", __FILE__, "severin")
#define DEFAULT_TIMER 60 /* Durée par défaut du test (en secondes) */
#define DEFAULT_WINSIZE 100 /* Taille par défaut de la fenêtre de messages */
#define DEFAULT_MSGSIZE 100 /* Taille par défaut de chaque message */
#define FATHER_KEY "father_port" /* Clé du port de messages d'écoute du père */
#define CHILD_KEY "child_port" /* Clé du port de messages d'écoute du fils */
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
/*----------------------------------------------------------------*/
MSGT_Port * My_Port, * Its_Port;
unsigned int Child_Pid, Father_Pid, Its_Pid, My_Pid;
int Verbose, Tree;
unsigned int Win_Size, Msg_Size, Cpt_Msg, Timer;
SMT_DSH * DSH;
SMT_Heap * Heap;
int End_Test, End_Sigum;
char str [100];
void stop_test (int);
void stop_father (void);
void stop_child (void);
void clean (int);
void trace (char *);
void print_result (void);
void parse_arg (int, char **);
extern char * strdup (const char *);
extern kill (int, int);
/*----------------------------------------------------------------*/
int main (int argc, char ** argv)
{
unsigned int i;
MSGT_Message * Msg;
/* Récupération des arguments de la ligne de commande */
parse_arg (argc, argv);
/* Récupération du numéro de processus courant */
Father_Pid = getpid ();
/* Création d'un process fils avec qui dialoguer */
if ((Child_Pid = fork ()) != 0)
{
Heap = NULL;
/*--------- Code pour le process père -----------*/
/* Ouverture de la librairie libmsg */
if (MSG_Library_Open (0, NULL, MSGD_OPEN | MSGD_DEBUG_ALL) != MSGS_OK) return 0;
Its_Pid = Child_Pid;
My_Pid = Father_Pid;
signal (SIGINT, stop_test);
signal (SIGUSR1, stop_test);
/* Création d'un port de messages privé pour le père */
if (MSG_Port_Open (FATHER_KEY, &My_Port, MSGD_CREATE) != MSGS_OK)
{
fprintf (stderr, "Unable to create a message port for the father process\n");
clean (TRUE);
return 0;
}
else if (Verbose)
{
sprintf (str, "Message port \"%s\" created", My_Port->Name);
trace (str);
}
if (Tree == TRUE)
{
if (MSG_Port_Config (My_Port, MSGD_CONFIG_MSGQUEUE, NDD_DS_TREE) != MSGS_OK)
{
fprintf (stderr, "Unable to create a message port for the father process\n");
clean (TRUE);
return 0;
}
}
/* On attend que le fils ait créé son port de messages */
sleep (1);
/* Récupération du port de messages privé du fils */
if (MSG_Port_Open (CHILD_KEY, &Its_Port, MSGD_OPEN) != MSGS_OK)
{
fprintf (stderr, "Unable to retrieve the message port of the child process\n");
clean (TRUE);
return 0;
}
else if (Verbose)
{
sprintf (str, "Message port \"%s\" retrieved", Its_Port->Name);
trace (str);
}
/* Initialisation du Timer */
signal (SIGALRM, stop_test);
alarm (Timer);
/* Début du test : traitement des messages */
fprintf (stdout, "Testing LIBMSG for %d second(s) with %d message(s) of %d byte(s)...\n", Timer, Win_Size, Msg_Size);
/* Création et envoi de tous les messages au fils */
for (i = 0; i < Win_Size; i++)
{
if (MSG_Message_Alloc (&Msg, Msg_Size) == MSGS_OK)
{
if (Verbose)
{
sprintf (str, "Message %d created", i);
trace (str);
}
if (MSG_Message_Send (My_Port->Name, Its_Port, Msg) == MSGS_OK)
{
if (Verbose)
{
sprintf (str, "Message %d sent to port \"%s\"", i, Its_Port->Name);
trace (str);
}
}
}
}
Cpt_Msg = 0;
while (End_Test == FALSE)
{
/* Réception de messages */
if (MSG_Message_Receive (My_Port, MSGD_NO_TYPE, &Msg, MSGD_WAIT) == MSGS_OK)
{
if (Verbose)
{
sprintf (str, "Message %d received from port \"%s\"", Msg->Type, My_Port->Name);
trace (str);
}
Cpt_Msg++;
/* Réenvoi du message au fils */
if (MSG_Message_Reply (Msg) == MSGS_OK)
{
if (Verbose)
{
sprintf (str, "Message %d replied", Msg->Type);
trace (str);
}
}
}
}
stop_father ();
}
else
{
/*---------- Code pour le process fils ----------*/
Heap = NULL;
My_Pid = getpid ();
Its_Pid = Father_Pid;
/* Ouverture de la librairie libmsg */
if (MSG_Library_Open (0, NULL, SMD_OPEN | MSGD_DEBUG_ALL) != MSGS_OK) return 0;
/* Trap du signal SIGUSR1 envoyé par le process père à la fin du test */
signal (SIGUSR1, stop_test);
signal (SIGINT, stop_test);
/* Création d'un port de messages privé pour le fils */
if (MSG_Port_Open (CHILD_KEY, &My_Port, MSGD_CREATE) != MSGS_OK)
{
fprintf (stderr, "Unable to create message port for the child process\n");
clean (TRUE);
return 0;
}
else if (Verbose)
{
sprintf (str, "Message port \"%s\" created", My_Port->Name);
trace (str);
}
/* On attend que le père ait créé son port de messages privé */
sleep (1);
/* Récupération du port de messages privé du père */
if (MSG_Port_Open (FATHER_KEY, &Its_Port, MSGD_OPEN) != MSGS_OK)
{
fprintf (stderr, "Unable to retrieve the message port of the father process\n");
clean (TRUE);
return 0;
}
else if (Verbose)
{
sprintf (str, "Message port \"%s\" retrieved", Its_Port->Name);
trace (str);
}
/* Traitement des messages */
while (End_Test == FALSE)
{
/* Réception de messages */
if (MSG_Message_Receive (My_Port, MSGD_NO_TYPE, &Msg, MSGD_WAIT) == MSGS_OK)
{
if (Verbose)
{
sprintf (str, "Message %d received from port \"%s\"", Msg->Type, My_Port->Name);
trace (str);
}
/* Renvoi du message */
if (MSG_Message_Reply (Msg) == MSGS_OK)
{
if (Verbose)
{
sprintf (str, "Message %d replied", Msg->Type);
trace (str);
}
}
}
}
stop_child ();
}
return 0;
}
/*----------------------------------------------------------------*/
void stop_test (int signum)
{
End_Sigum = signum;
End_Test = TRUE;
}
/*----------------------------------------------------------------*/
void stop_father (void)
{
switch (End_Sigum)
{
case SIGINT:
/* Fin initiée par l'utilisateur : ménage simple */
case SIGUSR1:
/* Fin anormale en provenance du fils : ménage simple */
sprintf (str, "Signal USR1 received from child process");
trace (str);
clean (FALSE);
break;
case SIGALRM:
/* Fin normale : ménage + stop du fils + affichage du réultat */
clean (TRUE);
print_result ();
break;
default:
/* Fin anormale sur le process père : ménage + avertit le process fils */
clean (TRUE);
break;
}
exit (1);
}
/*----------------------------------------------------------------*/
void print_result (void)
{
/* Affichage du résultat du test */
fprintf (stdout, "%d message(s) exchanged (%d msg/sec)\n", Cpt_Msg, (int)(Cpt_Msg / Timer));
}
/*----------------------------------------------------------------*/
void stop_child (void)
{
switch (End_Sigum)
{
case SIGINT:
/* Fin initiée par l'utilisateur : ménage simple */
case SIGUSR1:
/* Fin initiée par le process père : ménage simple */
sprintf (str, "Signal USR1 received from father process");
trace (str);
clean (FALSE);
break;
default:
/* Fin anormale sur le process fils : ménage + avertit le process père */
clean (TRUE);
break;
}
exit (0);
}
/*----------------------------------------------------------------*/
void clean (int warn)
{
/* On avertit l'autre process */
if (warn == TRUE) kill (Its_Pid, SIGUSR1);
/* Fermeture du port de l'autre process */
if (Its_Port != NULL)
{
char Port_Name [256];
strcpy (Port_Name, Its_Port->Name);
MSG_Port_Close (Its_Port, MSGD_CLOSE);
if (Verbose)
{
sprintf (str, "Message port \"%s\" closed", Port_Name);
trace (str);
}
}
/* Destruction du port de messages privé */
if (My_Port != NULL)
{
char Port_Name [256];
strcpy (Port_Name, My_Port->Name);
/* On attend un peu afin que l'autre process puisse fermer mon port de messages */
sleep (1);
MSG_Port_Close (My_Port, MSGD_DESTROY);
if (Verbose)
{
sprintf (str, "Message port \"%s\" removed", Port_Name);
trace (str);
}
}
MSG_Library_Close (MSGD_CLOSE);
}
/*----------------------------------------------------------------*/
void trace (char * s)
{
time_t dts;
struct tm * dt;
char Current_Date [25];
char strace [100];
/* Get current date */
time (&dts);
dt = localtime (&dts);
sprintf (Current_Date, "%04d/%02d/%02d %02d:%02d:%02d", dt->tm_year + 1900, dt->tm_mon + 1, dt->tm_mday, dt->tm_hour, dt->tm_min, dt->tm_sec);
sprintf (strace, "Process %d - %s : %s\n", My_Pid, Current_Date, s);
fprintf (stderr, strace);
fflush (stderr);
}
/*----------------------------------------------------------------*/
void parse_arg (int argc, char **argv)
{
int i;
Verbose = Tree = FALSE;
for (i = 1; i < argc; i++)
{
if (!strcmp (argv[i], "--help") || !strcmp (argv[i], "-h"))
{
fprintf (stdout, "Usage : %s [options]\n", argv[0]);
fprintf (stdout,"options :\n");
fprintf (stdout, "\t --help | -h\n");
fprintf (stdout, "\t --clean\n");
fprintf (stdout, "\t --verbose\n");
fprintf (stdout, "\t --duration <time in seconds> (default is %d)\n", DEFAULT_TIMER);
fprintf (stdout, "\t --window <message number> (default is %d)\n", DEFAULT_WINSIZE);
fprintf (stdout, "\t --message <message size> (default is %d bytes)\n", DEFAULT_MSGSIZE);
fprintf (stdout, "\t --tree\n");
fprintf (stdout, "\t --version [-v]\n");
exit (1);
}
if (!strcmp (argv[i], "--clean"))
{
if (MSG_Library_Open (NULL, NULL, MSGD_OPEN) == MSGS_OK)
{
if (MSG_Port_Open (FATHER_KEY, &My_Port, MSGD_OPEN) == MSGS_OK)
MSG_Port_Close (My_Port, MSGD_DESTROY);
if (MSG_Port_Open (CHILD_KEY, &Its_Port, MSGD_OPEN) == MSGS_OK)
MSG_Port_Close (Its_Port, MSGD_DESTROY);
MSG_Library_Close (MSGD_CLOSE);
}
exit (1);
}
if (!strcmp (argv[i], "--verbose"))
{
Verbose = TRUE;
continue;
}
if (!strcmp (argv[i], "--tree"))
{
Tree = TRUE;
continue;
}
if (!strcmp (argv[i], "--duration"))
{
i++;
if (i == argc)
{
fprintf (stderr, "Missing argument after %s\n", argv[i - 1]);
exit (0);
}
Timer = atoi (argv[i]);
continue;
}
if (!strcmp (argv[i], "--window"))
{
i++;
if (i == argc)
{
fprintf (stderr, "Missing argument after %s\n", argv[i - 1]);
exit (0);
}
Win_Size = atoi (argv[i]);
continue;
}
if (!strcmp (argv[i], "--message"))
{
i++;
if (i == argc)
{
fprintf (stderr, "Missing argument after %s\n", argv[i - 1]);
exit (0);
}
Msg_Size = atoi (argv[i]);
continue;
}
if (!strcmp (argv[i], "--version"))
{
if (i+1 < argc && !strcmp (argv[i+1], "-v"))
{
VER_Object_Print (stdout, VERD_VERBOSE);
exit (0);
}
else
{
VER_Object_Print (stdout, VERD_MINIMAL);
exit (0);
}
}
fprintf (stdout, "Unknown option '%s'\n", argv[i]);
exit (0);
}
if (Timer <= 0) Timer = DEFAULT_TIMER;
if (Win_Size <= 0) Win_Size = DEFAULT_WINSIZE;
if (Msg_Size <= 0) Msg_Size = DEFAULT_MSGSIZE;
}

20
util/result.linux Normal file
View File

@@ -0,0 +1,20 @@
Testing LIBMSG for 10 second(s) with 1 message(s) of 10 byte(s)...
25791 message(s) exchanged (2579 msg/sec)
Testing LIBMSG for 10 second(s) with 1 message(s) of 1000 byte(s)...
24904 message(s) exchanged (2490 msg/sec)
Testing LIBMSG for 10 second(s) with 1 message(s) of 2048 byte(s)...
25248 message(s) exchanged (2524 msg/sec)
---------
Testing LIBMSG for 10 second(s) with 10 message(s) of 10 byte(s)...
27548 message(s) exchanged (2754 msg/sec)
Testing LIBMSG for 10 second(s) with 10 message(s) of 1000 byte(s)...
28720 message(s) exchanged (2872 msg/sec)
Testing LIBMSG for 10 second(s) with 10 message(s) of 2048 byte(s)...
26860 message(s) exchanged (2686 msg/sec)
---------
Testing LIBMSG for 10 second(s) with 100 message(s) of 10 byte(s)...
31243 message(s) exchanged (3124 msg/sec)
Testing LIBMSG for 10 second(s) with 100 message(s) of 1000 byte(s)...
29841 message(s) exchanged (2984 msg/sec)
Testing LIBMSG for 10 second(s) with 100 message(s) of 2048 byte(s)...
31047 message(s) exchanged (3104 msg/sec)

20
util/result.linux.old Normal file
View File

@@ -0,0 +1,20 @@
Testing LIBMSG for 10 second(s) with 1 message(s) of 10 byte(s)...
23639 message(s) exchanged (2363 msg/sec)
Testing LIBMSG for 10 second(s) with 1 message(s) of 1000 byte(s)...
22974 message(s) exchanged (2297 msg/sec)
Testing LIBMSG for 10 second(s) with 1 message(s) of 2048 byte(s)...
23340 message(s) exchanged (2334 msg/sec)
---------
Testing LIBMSG for 10 second(s) with 10 message(s) of 10 byte(s)...
26497 message(s) exchanged (2649 msg/sec)
Testing LIBMSG for 10 second(s) with 10 message(s) of 1000 byte(s)...
26441 message(s) exchanged (2644 msg/sec)
Testing LIBMSG for 10 second(s) with 10 message(s) of 2048 byte(s)...
26680 message(s) exchanged (2668 msg/sec)
---------
Testing LIBMSG for 10 second(s) with 100 message(s) of 10 byte(s)...
29914 message(s) exchanged (2991 msg/sec)
Testing LIBMSG for 10 second(s) with 100 message(s) of 1000 byte(s)...
29854 message(s) exchanged (2985 msg/sec)
Testing LIBMSG for 10 second(s) with 100 message(s) of 2048 byte(s)...
29891 message(s) exchanged (2989 msg/sec)

155
util/skeleton.c Normal file
View File

@@ -0,0 +1,155 @@
#include <stdlib.h>
#include <string.h>
#include <msg.h>
/*------------------------------------------------------------------------------------------*/
/* Fonction principale du programme */
/*------------------------------------------------------------------------------------------*/
void main ( void )
{
MSGT_Port * My_Port;
MSGT_Message * Msg;
int End_Process;
/* Ouverture de la librairie LIBMSG */
if (MSG_Library_Open (NULL, NULL, MSGD_OPEN) != MSGS_OK)
{
return;
}
/* Ouverture / création du port de messages privé */
if (MSG_Port_Open (<PORT_NAME>, &My_Port, <OPEN_MODE>) != MSGS_OK)
/*
<PORT_NAME> = nom du port privé (sans espace)
<OPEN_MODE> = MSGD_OPEN ou MSGD_CREATE
*/
{
MSG_Library_Close (MSGD_CLOSE);
return;
}
/* Boucle principale du programme */
End_Process = FALSE;
while (End_Proces == FALSE)
{
/* Ecoute du port de messages privé */
int rc = MSG_Message_Receive (My_Port, <RECEIVE_TYPE>, &Msg, <RECEIVE_MODE>);
/*
<RECEIVE_MODE> = MSGD_WAIT ou MSGD_NO_WAIT
<RECEIVE_TYPE> = MSGD_NO_TYPE ou type prédéfini ou type utilisateur
*/
switch (rc)
{
case MSGS_OK:
/* Message reçu */
Message_Process (Msg);
break;
case MSGS_NO_MSG:
/* Aucun message présent (en mode MSGD_NO_WAIT seulement) */
...
break;
case MSGS_BAD_TYPE:
/* Aucun message du type demandé (en mode MSGD_NO_WAIT seulement) */
...
break;
case MSGS_SIGNAL:
/* Ecoute interrompue par l'interception d'un signal */
...
break;
default:
break;
}
/* Traitement propre au programme */
...
} /* Fin de la boucle principale */
/* Fermeture du port de messages privé */
if (MSG_Port_Close (My_Port, <CLOSE_MODE>) != MSGS_OK) /* <CLOSE_MODE> = MSGD_CLOSE ou MSGD_DESTROY */
{
MSG_Library_Close (MSGD_CLOSE);
return;
}
/* Fermeture de la librairie LIBMSG */
MSG_Library_Close (MSGD_CLOSE);
}
/*------------------------------------------------------------------------------------------*/
/* Fonction de traitement d'un message reçu sur le port privé */
/*------------------------------------------------------------------------------------------*/
void Message_Process ( MSGT_Message * Msg )
{
/* Quel est le type du message ? */
switch ( (int)(Msg->Type) )
{
case <TYPE1>:
...
case <TYPE2>:
/* Traitement selon le message */
...
/* Réponse au message */
if (Msg->Size > strlen ("Message bien reçu"))
{
/* Réponse au message reçu */
strcpy ((char *)(Msg->Data), "Message bien reçu");
/* Retour à l'envoyeur */
if (MSG_Message_Reply (Msg) == MSGS_OK) return;
}
break;
default:
break;
}
/* Si on n'a pas répondu au message, on le supprime */
MSG_Message_Free (Msg);
}