2024-04-17 18:49:56 +02:00
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
/* smdemo0.c */
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
2005-06-27 01:16:38 +02:00
|
|
|
|
|
2024-04-20 10:11:27 +02:00
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
/* This file is part of LibShMem. */
|
|
|
|
|
/* */
|
|
|
|
|
/* LibShMem is free software: you can redistribute it and/or modify it */
|
|
|
|
|
/* under the terms of the GNU General Public License as published by */
|
|
|
|
|
/* the Free Software Foundation, either version 3 of the License, or */
|
|
|
|
|
/* (at your option) any later version. */
|
|
|
|
|
/* */
|
|
|
|
|
/* LibShMem is distributed in the hope that it will be useful, */
|
|
|
|
|
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
|
|
|
|
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
|
|
|
|
/* GNU General Public License for more details. */
|
|
|
|
|
/* */
|
|
|
|
|
/* You should have received a copy of the GNU General Public License */
|
|
|
|
|
/* along with LibShMem. If not, see <https://www.gnu.org/licenses/>. */
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
|
2005-06-27 01:16:38 +02:00
|
|
|
|
|
2024-04-17 18:49:56 +02:00
|
|
|
|
|
2024-04-20 10:11:27 +02:00
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
/* Includes */
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
2024-04-17 18:49:56 +02:00
|
|
|
|
|
2005-06-27 01:16:38 +02:00
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <errno.h>
|
2024-04-14 20:00:25 +02:00
|
|
|
|
#include <sys/wait.h>
|
2005-06-27 01:16:38 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <node.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef SM_MODE
|
|
|
|
|
# define SM_MODE 0 /* Utilisation des API s<>curis<69>s */
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include <shmem.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define LOG_ERROR 10
|
|
|
|
|
#define LOG_WARNING 20
|
|
|
|
|
#define LOG_INFO 30
|
|
|
|
|
#define LOG_TRACE 40
|
|
|
|
|
|
|
|
|
|
#define FATHER_ID 0
|
|
|
|
|
|
|
|
|
|
#define SON_SND_ID 1
|
|
|
|
|
#define SON_SND_NAME "snd"
|
|
|
|
|
|
|
|
|
|
#define SON_RCV_ID 2
|
|
|
|
|
#define SON_RCV_NAME "rcv"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define INST_MAX 256
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Log_Print( int, int, int, int, char *, ...);
|
|
|
|
|
|
|
|
|
|
int Do_Fork_Exec( char **, int, int, int, int *, int);
|
|
|
|
|
|
|
|
|
|
void Make_Son_Cmd_Name( char *, char *, char *);
|
|
|
|
|
|
|
|
|
|
int main( int , char **);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Log_Print( int Log_Level, int Verbose_Level, int Proc_Id, int Inst_Id, char *Format_Str, ...)
|
|
|
|
|
{
|
|
|
|
|
va_list args;
|
|
|
|
|
char *prompt[] = { "father", "snd", "rcv"};
|
|
|
|
|
int fmt_size = 255;
|
|
|
|
|
char fmt[ fmt_size + 1];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( Log_Level <= Verbose_Level)
|
|
|
|
|
{
|
|
|
|
|
va_start( args, Format_Str);
|
|
|
|
|
|
|
|
|
|
if( Proc_Id == FATHER_ID)
|
|
|
|
|
{
|
|
|
|
|
snprintf( fmt, fmt_size, "%s: %s", prompt[Proc_Id], Format_Str);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
snprintf( fmt, fmt_size, "%s%02d : %s", prompt[Proc_Id], Inst_Id, Format_Str);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vfprintf( stderr, fmt, args);
|
|
|
|
|
fflush( stderr);
|
|
|
|
|
|
|
|
|
|
va_end( args);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int Do_Fork_Exec( char **ArgV_Tab, int Proc_Id, int Inst_Id, int Dir, int Pipe_Desc[2], int Verbose_Level)
|
|
|
|
|
{
|
|
|
|
|
pid_t pid;
|
|
|
|
|
int rc;
|
|
|
|
|
char cmd[1024] = "";
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for( i = 0; ArgV_Tab[i] != NULL; i++)
|
|
|
|
|
{
|
|
|
|
|
if( i > 0)
|
|
|
|
|
{
|
|
|
|
|
strcat( cmd, " ");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
strcat( cmd, ArgV_Tab[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Log_Print( LOG_TRACE, Verbose_Level, FATHER_ID, 0, "Forking Inst_Id: (%d) Dir: (%d) Cmd: [%s]...\n", Inst_Id, Dir, cmd);
|
|
|
|
|
|
|
|
|
|
switch( pid = fork())
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
{
|
|
|
|
|
Log_Print( LOG_INFO, Verbose_Level, Proc_Id, Inst_Id, "PId: (%d) PPId: (%d) Exec_File: [%s]\n", getpid(), getppid(), ArgV_Tab[0]);
|
|
|
|
|
|
|
|
|
|
if( ( rc = close( Pipe_Desc[ 1 - Dir])) == -1)
|
|
|
|
|
{
|
|
|
|
|
Log_Print( LOG_ERROR, Verbose_Level, Proc_Id, Inst_Id, "close() failed: (%d) !\n", errno);
|
|
|
|
|
|
|
|
|
|
exit( -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( ( rc = dup2( Pipe_Desc[ Dir], Dir)) == -1)
|
|
|
|
|
{
|
|
|
|
|
Log_Print( LOG_ERROR, Verbose_Level, Proc_Id, Inst_Id, "dup2() failed: (%d) !\n", errno);
|
|
|
|
|
|
|
|
|
|
exit( -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( ( rc = execv( ArgV_Tab[0], ArgV_Tab)) == -1)
|
|
|
|
|
{
|
|
|
|
|
Log_Print( LOG_ERROR, Verbose_Level, Proc_Id, Inst_Id, "execv() failed: (%d) !\n", errno);
|
|
|
|
|
|
|
|
|
|
exit( -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
exit(-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case -1:
|
|
|
|
|
{
|
|
|
|
|
Log_Print( LOG_ERROR, Verbose_Level, FATHER_ID, Inst_Id, "fork() failed: (%d) !\n", errno);
|
|
|
|
|
|
|
|
|
|
return( -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
Log_Print( LOG_INFO, Verbose_Level, FATHER_ID, Inst_Id, "PId: (%d) Son_PId: (%d)\n", getpid(), pid);
|
|
|
|
|
|
|
|
|
|
return( 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Make_Son_Cmd_Name( char *Son_Cmd_Name, char *Father_Cmd_Name, char *Son_Name)
|
|
|
|
|
{
|
|
|
|
|
char *ptr;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( ( ptr = strstr( Father_Cmd_Name, "-")) == NULL)
|
|
|
|
|
{
|
|
|
|
|
ptr = Father_Cmd_Name + strlen( Father_Cmd_Name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
strncpy( Son_Cmd_Name, Father_Cmd_Name, ( ptr - Father_Cmd_Name));
|
|
|
|
|
Son_Cmd_Name[ ( ptr - Father_Cmd_Name)] = '\0';
|
|
|
|
|
strcat( Son_Cmd_Name, "_");
|
|
|
|
|
strcat( Son_Cmd_Name, Son_Name);
|
|
|
|
|
strcat( Son_Cmd_Name, ptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main( int ArgC, char **ArgV)
|
|
|
|
|
{
|
|
|
|
|
char *Heap_Name;
|
|
|
|
|
int Inst_Nb;
|
|
|
|
|
int Chunk_Nb;
|
|
|
|
|
size_t Chunk_Size;
|
|
|
|
|
int Verbose_Level = 30;
|
|
|
|
|
|
|
|
|
|
SMT_Heap *heap_ptr;
|
|
|
|
|
size_t heap_size = 1024;
|
|
|
|
|
int locked;
|
|
|
|
|
SMT_Status status;
|
|
|
|
|
int rc;
|
|
|
|
|
int pipe_desc[2];
|
|
|
|
|
pid_t pid;
|
|
|
|
|
char *ptr;
|
|
|
|
|
char *argv_tab[10];
|
|
|
|
|
char son_cmd[256];
|
|
|
|
|
char inst_id_str[32];
|
|
|
|
|
char chunk_nb_str[32];
|
|
|
|
|
char chunk_size_str[32];
|
|
|
|
|
char verbose_level_str[32];
|
|
|
|
|
int inst_id;
|
|
|
|
|
short error = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( ArgC != 6)
|
|
|
|
|
{
|
|
|
|
|
Log_Print( LOG_ERROR, Verbose_Level, FATHER_ID, 0, "Usage: %s Inst_Nb Heap_Name Chunck_Nb Chunk_Size Verbose_Level\n", ArgV[0]);
|
|
|
|
|
exit( -1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Inst_Nb = atoi( ArgV[1]);
|
|
|
|
|
Heap_Name = ArgV[2];
|
|
|
|
|
Chunk_Nb = atoi( ArgV[3]);
|
|
|
|
|
Chunk_Size = atoi( ArgV[4]);
|
|
|
|
|
Verbose_Level = atoi( ArgV[5]);
|
|
|
|
|
|
|
|
|
|
if( Inst_Nb > INST_MAX)
|
|
|
|
|
{
|
|
|
|
|
Log_Print( LOG_ERROR, Verbose_Level, FATHER_ID, 0, "Inst_Nb: (%d) > (%d) !\n", Inst_Nb, INST_MAX);
|
|
|
|
|
exit( -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Log_Print( LOG_INFO, Verbose_Level, FATHER_ID, 0, "Inst_Nb: (%d) Heap_Name: [%s] Chunck_Nb: (%d) Chunck_Size: (%d) Verbose_Level: (%d)...\n",
|
|
|
|
|
Inst_Nb, Heap_Name, Chunk_Nb, Chunk_Size, Verbose_Level);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( ( status = SM_Library_Open( 0, NULL, ( SMD_OPEN | SMD_DEBUG_ALL))) != SMS_OK)
|
|
|
|
|
{
|
|
|
|
|
Log_Print( LOG_ERROR, Verbose_Level, FATHER_ID, 0, "Can't open LibShMem (%d) !\n", status);
|
|
|
|
|
|
|
|
|
|
exit( -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Log_Print( LOG_TRACE, Verbose_Level, FATHER_ID, 0, "LibShMem opened !\n");
|
|
|
|
|
|
|
|
|
|
if( ( status = SM_Heap_Open( Heap_Name, &heap_ptr, heap_size, ( SMD_OPEN | SMD_CREATE | SMD_NO_LOCK), &locked)) != SMS_OK)
|
|
|
|
|
{
|
|
|
|
|
Log_Print( LOG_ERROR, Verbose_Level, FATHER_ID, 0, "Can't create heap (%d) !\n", status);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Log_Print( LOG_TRACE, Verbose_Level, FATHER_ID, 0, "Heap opened !\n");
|
|
|
|
|
|
|
|
|
|
for( inst_id = 0, error = 0; ( inst_id < Inst_Nb) && ( error == 0); inst_id++)
|
|
|
|
|
{
|
|
|
|
|
if( pipe( pipe_desc) == -1)
|
|
|
|
|
{
|
|
|
|
|
Log_Print( LOG_ERROR, Verbose_Level, FATHER_ID, 0, "Con't open pipe (%d) !\n", errno);
|
|
|
|
|
error = 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
argv_tab[0] = son_cmd;
|
|
|
|
|
Make_Son_Cmd_Name( argv_tab[0], ArgV[0], SON_SND_NAME);
|
|
|
|
|
|
|
|
|
|
argv_tab[1] = inst_id_str;
|
|
|
|
|
sprintf( argv_tab[1], "%d", inst_id);
|
|
|
|
|
|
|
|
|
|
argv_tab[2] = Heap_Name;
|
|
|
|
|
|
|
|
|
|
argv_tab[3] = chunk_nb_str;
|
|
|
|
|
sprintf( argv_tab[3], "%d", Chunk_Nb);
|
|
|
|
|
|
|
|
|
|
argv_tab[4] = chunk_size_str;
|
|
|
|
|
sprintf( argv_tab[4], "%d", Chunk_Size);
|
|
|
|
|
|
|
|
|
|
argv_tab[5] = verbose_level_str;
|
|
|
|
|
sprintf( argv_tab[5], "%d", Verbose_Level);
|
|
|
|
|
|
|
|
|
|
argv_tab[6] = NULL;
|
|
|
|
|
|
|
|
|
|
if( Do_Fork_Exec( argv_tab, SON_SND_ID, inst_id, 1, pipe_desc, Verbose_Level) == -1)
|
|
|
|
|
{
|
|
|
|
|
error = 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
argv_tab[0] = son_cmd;
|
|
|
|
|
Make_Son_Cmd_Name( argv_tab[0], ArgV[0], SON_RCV_NAME);
|
|
|
|
|
|
|
|
|
|
argv_tab[1] = inst_id_str;
|
|
|
|
|
sprintf( argv_tab[1], "%d", inst_id);
|
|
|
|
|
|
|
|
|
|
argv_tab[2] = Heap_Name;
|
|
|
|
|
|
|
|
|
|
argv_tab[3] = verbose_level_str;
|
|
|
|
|
sprintf( argv_tab[3], "%d", Verbose_Level);
|
|
|
|
|
|
|
|
|
|
argv_tab[4] = NULL;
|
|
|
|
|
|
|
|
|
|
if( Do_Fork_Exec( argv_tab, SON_RCV_ID, inst_id, 0, pipe_desc, Verbose_Level) == -1)
|
|
|
|
|
{
|
|
|
|
|
error = 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if( ( rc = close( pipe_desc[ 0])) == -1)
|
|
|
|
|
{
|
|
|
|
|
Log_Print( LOG_ERROR, Verbose_Level, FATHER_ID, 0, "close() pipe[0] failed: (%d)\n", errno);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( ( rc = close( pipe_desc[ 1])) == -1)
|
|
|
|
|
{
|
|
|
|
|
Log_Print( LOG_ERROR, Verbose_Level, FATHER_ID, 0, "close() pipe[1] failed: (%d)\n", errno);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( error == 0)
|
|
|
|
|
{
|
|
|
|
|
Log_Print( LOG_TRACE, Verbose_Level, FATHER_ID, 0, "Waiting sons to complet...\n");
|
|
|
|
|
|
|
|
|
|
for( inst_id = 0; inst_id < ( Inst_Nb * 2); inst_id++)
|
|
|
|
|
{
|
|
|
|
|
pid = wait( NULL);
|
|
|
|
|
|
|
|
|
|
Log_Print( LOG_TRACE, Verbose_Level, FATHER_ID, 0, "Son PId: (%d) exited !\n", pid);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( ( ( status = SM_Heap_Lock( heap_ptr, SMD_WRITE, &locked)) != SMS_OK) && ( locked == TRUE))
|
|
|
|
|
{
|
|
|
|
|
Log_Print( LOG_ERROR, Verbose_Level, FATHER_ID, 0, "Can't lock heap (%d) !\n", status);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if( ( status = SM_Heap_Close( heap_ptr)) != SMS_OK)
|
|
|
|
|
{
|
|
|
|
|
Log_Print( LOG_ERROR, Verbose_Level, FATHER_ID, 0, "Can't close heap (%d) !\n", status);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Log_Print( LOG_TRACE, Verbose_Level, FATHER_ID, 0, "Heap closed !\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( ( status = SM_Library_Close( SMD_CLOSE)) != SMS_OK)
|
|
|
|
|
{
|
|
|
|
|
Log_Print( LOG_ERROR, Verbose_Level, FATHER_ID, 0, "Can't close LibShMem (%d) !\n", status);
|
|
|
|
|
|
|
|
|
|
exit( -1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Log_Print( LOG_TRACE, Verbose_Level, FATHER_ID, 0, "LibShMem closed !\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
exit( 0);
|
|
|
|
|
}
|