/*----------------------------------------------------------------------------*/ /* smdemo0.c */ /*----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/ /* This file is part of LibShMem */ /* */ /* LibShMem is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU Lesser General Public Licence as published by */ /* the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. */ /* */ /* You should have received a copy of the GNU Lesser General Public License */ /* along with LibShMem; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /*---------------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #ifndef SM_MODE # define SM_MODE 0 /* Utilisation des API sécurisés */ #endif #include #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); }