Arnaud G. GIBERT
493568b9fb
- Add NDT_Root pointer to SM_Base_Alloc(), SM_Base_Free(), SM_System_Alloc() & SM_System_Free() API.
5583 lines
159 KiB
C
5583 lines
159 KiB
C
/*----------------------------------------------------------------------------*/
|
||
/* libshmem.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 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 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, see */
|
||
/* <https://www.gnu.org/licenses/>. */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
|
||
|
||
/*----------------------------------------------------------------------------*/
|
||
/* Includes */
|
||
/*----------------------------------------------------------------------------*/
|
||
|
||
#define _LIBSHMEM_C_
|
||
|
||
|
||
|
||
#include <libshmem.h>
|
||
|
||
//#ifdef _LIBVER_SUPPORT
|
||
//VER_INFO_EXPORT(libshmem,"$Revision: 2.4 $", "$Name: $",__FILE__,"$Author: agibert $")
|
||
//#endif
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/*------------------------------------------------------------------------------*/
|
||
/* FONCTIONS PUBLIQUES */
|
||
/*------------------------------------------------------------------------------*/
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* FONCTIONS OPTIMISEES (SM_MODE = 1) */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Ouverture d'une instance de la librairie */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Instance : num<75>ro de l'instance de la librairie */
|
||
/* (I) Context : nom du nouveau contexte */
|
||
/* (I) Open_Mode : indicateur cr<63>ation/ouverture + mode d'affichage des erreurs */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Library_Open_I( int Instance, const char *Context, SMT_Flags Open_Mode)
|
||
{
|
||
SMT_Status rc;
|
||
LGT_Status lg_status;
|
||
int ND_Debug = FALSE;
|
||
int To_Open_Instance;
|
||
NDT_Index_Type index_type = ( NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_TREE | NDD_INDEX_SUBTYPE_BALANCED);
|
||
|
||
|
||
/* D<>finition du mode d'affichage des messages d'erreur */
|
||
|
||
if( SMD_DEBUG_MSK( Open_Mode)) SM_stderr = stderr;
|
||
if( Open_Mode & SMD_DEBUG_ALL) ND_Debug = TRUE;
|
||
|
||
if( ( lg_status = LG_Library_Open( LGD_LOG_WRITER_DEFAULT, false)) != LGS_OK)
|
||
{
|
||
fprintf( stderr, "Can't open LibLog library: (%d)\n", lg_status);
|
||
return( -1);
|
||
}
|
||
|
||
|
||
/* D<>finition de l'instance <20> ouvrir */
|
||
|
||
if( Instance) To_Open_Instance = Instance;
|
||
else
|
||
{
|
||
if( !getenv( INSTANCE_ENV_VAR) || ( To_Open_Instance = atoi( getenv( INSTANCE_ENV_VAR))) <= 0)
|
||
{
|
||
To_Open_Instance = DEFAULT_INSTANCE;
|
||
}
|
||
}
|
||
|
||
if( Open_Mode & SMD_CREATE) /* Cr<43>ation d'une nouvelle instance */
|
||
{
|
||
/* On v<>rifie que le processus courant n'acc<63>de pas d<>j<EFBFBD> <20> une instance */
|
||
|
||
if( SM_Open_Counter > 0)
|
||
{
|
||
LG_LOG_ERROR_1( "SM_Library_Open : the current process has already opened an instance: (%d) of the LIBSHMEM base", SM_Instance);
|
||
|
||
return( SMS_ERRAPI);
|
||
}
|
||
|
||
/* Ouverture de la librairie LIBNODE */
|
||
|
||
rc = ND_Library_Open( ND_Debug);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "SM_Library_Open : unable to open the LIBNODE library");
|
||
|
||
return( rc);
|
||
}
|
||
|
||
/* Ouverture de la liste des heaps ouverts (locale) */
|
||
|
||
rc = ND_DataStruct_Open( &Opened_Heap_List, 1, &index_type, "SM_Opened_Heap_List_Manager", NULL, NULL, NULL, NULL, NULL, TRUE, NULL);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "SM_Library_Open : unable to create the local opened heap cache");
|
||
|
||
goto Error1;
|
||
}
|
||
|
||
/* Cr<43>ation de la base de m<>moire partag<61>e */
|
||
|
||
SM_Instance = To_Open_Instance;
|
||
|
||
rc = SM_Base_Init();
|
||
if( rc != SMS_OK )
|
||
{
|
||
LG_LOG_ERROR_0( "SM_Library_Open : unable to initialize the shared memory base");
|
||
|
||
goto Error2;
|
||
}
|
||
}
|
||
else if( Open_Mode & SMD_OPEN) /* Ouverture d'une instance existante */
|
||
{
|
||
/* On v<>rifie que le processus courant n'a pas d<>j<EFBFBD> ouvert une autre instance */
|
||
|
||
if( SM_Open_Counter > 0 && To_Open_Instance != SM_Instance)
|
||
{
|
||
LG_LOG_ERROR_2( "SM_Library_Open : the current process cannot open instance: (%d) because it is already accessing instance: (%d)", To_Open_Instance, SM_Instance);
|
||
|
||
return( SMS_ERRAPI);
|
||
}
|
||
|
||
SM_Instance = To_Open_Instance;
|
||
|
||
/* Ouverture effective si c'est la premi<6D>re fois */
|
||
|
||
if( SM_Open_Counter == 0)
|
||
{
|
||
/* Ouverture de la librairie LIBNODE */
|
||
|
||
rc = ND_Library_Open( ND_Debug);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to open the LIBNODE library");
|
||
|
||
return( rc);
|
||
}
|
||
|
||
/* Ouverture de la liste des heaps ouverts (locale) */
|
||
|
||
rc = ND_DataStruct_Open( &Opened_Heap_List, 1, &index_type, "SM_Opened_Heap_List_Manager", NULL, NULL, NULL, NULL, NULL, TRUE, NULL);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to create the local opened heap cache");
|
||
|
||
goto Error1;
|
||
}
|
||
|
||
/* Ouverture de la base de m<>moire partag<61>e */
|
||
|
||
rc = SM_Base_Open();
|
||
if( rc != SMS_OK )
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to open the shared memory base");
|
||
|
||
goto Error2;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* D<>finition du contexte */
|
||
|
||
SM_Library_Context_Set_I( Context);
|
||
|
||
/* On incr<63>mente le compteur d'ouverture de la librairie */
|
||
|
||
SM_Open_Counter++;
|
||
|
||
return( SMS_OK);
|
||
|
||
/* Gestion d'erreur */
|
||
|
||
Error2:
|
||
ND_DataStruct_Close( Opened_Heap_List);
|
||
|
||
Error1:
|
||
ND_Library_Close();
|
||
|
||
return( rc);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* R<>cup<75>ration du num<75>ro de l'instance utilis<69>e */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (O) Instance : adresse du num<75>ro de l'instance utilis<69>e */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Library_Instance_Get_I( int *Instance)
|
||
{
|
||
*Instance = SM_Instance;
|
||
|
||
return( SMS_OK);
|
||
}
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* R<>cup<75>ration du nom du contexte utilis<69> */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (O) Context : adresse du nom du contexte utilis<69> */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Library_Context_Get_I( char **Context)
|
||
{
|
||
*Context = SM_Context;
|
||
|
||
return( SMS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Changement de contexte d'utilisation de la librairie */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Context : nom du nouveau contexte */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Library_Context_Set_I( const char *Context )
|
||
{
|
||
if( SM_Context) free( SM_Context);
|
||
|
||
if( Context && strlen( Context))
|
||
{
|
||
SM_Context = strdup( Context);
|
||
}
|
||
else
|
||
{
|
||
if( getenv( CONTEXT_ENV_VAR) && strlen( getenv( CONTEXT_ENV_VAR)))
|
||
{
|
||
SM_Context = strdup( getenv( CONTEXT_ENV_VAR));
|
||
}
|
||
else
|
||
{
|
||
SM_Context = strdup( DEFAULT_CONTEXT);
|
||
}
|
||
}
|
||
|
||
return( SMS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Fermeture de l'instance de la librairie */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Close_Mode : mode de fermeture (destruction ou fermeture simple) */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Library_Close_I( SMT_Flags Close_Mode)
|
||
{
|
||
SMT_Status rc;
|
||
LGT_Status lg_status;
|
||
|
||
|
||
if( Close_Mode & SMD_DESTROY) /* Destruction de l'instance */
|
||
{
|
||
/* Destruction de la base de m<>moire partag<61>e */
|
||
|
||
rc = SM_Base_End();
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to destroy the shared memory base");
|
||
|
||
return( rc);
|
||
}
|
||
|
||
if( SM_Context)
|
||
{
|
||
free( SM_Context);
|
||
SM_Context = NULL;
|
||
}
|
||
|
||
/* Fermeture de la liste des heaps ouverts */
|
||
|
||
ND_DataStruct_Close( Opened_Heap_List);
|
||
|
||
/* Fermeture de la librairie LIBNODE */
|
||
|
||
ND_Library_Close();
|
||
|
||
/* R<>initialisation du compteur d'ouverture */
|
||
|
||
SM_Open_Counter = 0;
|
||
}
|
||
else if( Close_Mode & SMD_CLOSE) /* Fermeture de l'instance */
|
||
{
|
||
/*
|
||
La fermeture n'est effective que si la librairie
|
||
n'a <20>t<EFBFBD> ouverte qu'une seule fois.
|
||
*/
|
||
|
||
if( SM_Open_Counter == 1)
|
||
{
|
||
/* Fermeture de la base de m<>moire partag<61>e */
|
||
|
||
rc = SM_Base_Close();
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to close the shared memory base");
|
||
|
||
return( rc);
|
||
}
|
||
|
||
if( SM_Context)
|
||
{
|
||
free( SM_Context);
|
||
SM_Context = NULL;
|
||
}
|
||
|
||
/* Fermeture de la liste des heaps ouverts */
|
||
|
||
ND_DataStruct_Close( Opened_Heap_List);
|
||
|
||
/* Fermeture de la librairie LIBNODE */
|
||
|
||
ND_Library_Close();
|
||
}
|
||
|
||
/* On met <20> jour le compteur d'ouverture de la librairie */
|
||
|
||
SM_Open_Counter--;
|
||
}
|
||
|
||
if( ( lg_status = LG_Library_Close( false)) != LGS_OK)
|
||
{
|
||
fprintf( stderr, "Can't close LibLog library: (%d)\n", lg_status);
|
||
return( SMS_KO);
|
||
}
|
||
|
||
return( SMS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Affichage des informations de la base de m<>moires partag<61>es */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Library_Dump_I( FILE *Out)
|
||
{
|
||
/* Affichage des informations sur la base */
|
||
/*
|
||
fprintf( Out, "Base: (%d):[%s]\tSize: (%d)\tCreator PId: (%ld)\tLast write access PId: (%ld)\nId Mem: (%d):(%d)\tId Sem: (%d)\tStatus: [%s]\n\n",
|
||
SM_Instance, SM_Context, SM_Base->Size, SM_Base->Creator, SM_Base->Writer, SM_Base->SysMemId, SM_Base->DataMemId, SM_Base->SemId, SM_Lock_Status_Get( "base", SM_Base));
|
||
*/
|
||
|
||
LG_LOG_INFO_5( "Base: (%d):[%s]\tSize: (%d)\tCreator PId: (%ld)\tLast write access PId: (%ld)",
|
||
SM_Instance, SM_Context, SM_Base->Size, SM_Base->Creator, SM_Base->Writer);
|
||
LG_LOG_INFO_4( "Id Mem: (%d):(%d)\tId Sem: (%d)\tStatus: [%s]",
|
||
SM_Base->SysMemId, SM_Base->DataMemId, SM_Base->SemId, SM_Lock_Status_Get( "base", SM_Base));
|
||
LG_LOG_INFO_0( "");
|
||
|
||
/* Affichage des informations du MHR */
|
||
|
||
ND_DataStruct_Info_Print( Out, SM_Base->MHR, NDD_RECURSIVE_MODE_PARENT_CHILD, 0, 0);
|
||
// fprintf( Out, "\n");
|
||
LG_LOG_INFO_0( "");
|
||
|
||
/* Affichage des informations de chaque heap */
|
||
|
||
return( ND_DataStruct_Value_Print( Out, SM_Base->MHR, NDD_RECURSIVE_MODE_PARENT_CHILD, 0, 0));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Lib<69>ration de tous les verrous (base, heap) */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Library_Unlock_I( void)
|
||
{
|
||
NDT_Node *Node;
|
||
union semun Sem_Ctl;
|
||
|
||
|
||
/* Lib<69>ration des verrous sur la base */
|
||
|
||
Sem_Ctl.val = 1;
|
||
|
||
if( semctl( SM_Base->SemId, 0, SETVAL, Sem_Ctl))
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to unlock the shared memory base");
|
||
|
||
return( SMS_ERRSEM);
|
||
}
|
||
|
||
/* Lib<69>ration des verrous sur les heaps */
|
||
|
||
ND_Index_Node_First_Get( &Node, SM_Base->MHR, NDD_INDEX_PRIMARY);
|
||
|
||
while( Node)
|
||
{
|
||
SMT_MHH *MHH;
|
||
|
||
MHH = (SMT_MHH *)( Node->Value);
|
||
|
||
if( semctl( MHH->SemId, 0, SETVAL, Sem_Ctl))
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to unlock heap: [%s]", MHH->Name);
|
||
|
||
return( SMS_ERRSEM);
|
||
}
|
||
|
||
ND_Index_Node_Next_Get( &Node, Node);
|
||
}
|
||
|
||
ND_Index_Node_First_Get( &Node, Opened_Heap_List, NDD_INDEX_PRIMARY);
|
||
|
||
while( Node)
|
||
{
|
||
( (SMT_Heap *)(Node->Value))->Lock_Mode = SMD_NO_LOCK;
|
||
ND_Index_Node_Next_Get( &Node, Node);
|
||
}
|
||
|
||
return( SMS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* D<>finition de la sortie standard des messages d'erreur de la librairie */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Library_Stderr_Set_I( FILE *Out)
|
||
{
|
||
SM_stderr = Out;
|
||
|
||
return( SMS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Test d'existence d'un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap_Name : Nom du heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_Exist_I( const char *Heap_Name)
|
||
{
|
||
NDT_Node *Node;
|
||
SMT_MHH *MHH;
|
||
char prefixed_name[ SMD_NAME_SIZE];
|
||
int Locked = FALSE;
|
||
|
||
|
||
SM_Name_Prefix( prefixed_name, Heap_Name);
|
||
|
||
if( strcmp( Heap_Name, HEAP_SYSTEM))
|
||
{
|
||
/* Verrouillage du heap syst<73>me en lecture */
|
||
|
||
SM_Heap_Lock_I( System_Heap, SMD_READ, &Locked);
|
||
}
|
||
|
||
/* Recherche dans le MHR */
|
||
|
||
ND_Index_Node_First_Get( &Node, SM_Base->MHR, NDD_INDEX_PRIMARY);
|
||
|
||
while( Node)
|
||
{
|
||
MHH = (SMT_MHH *)( Node->Value);
|
||
|
||
if( !strcmp( prefixed_name, MHH->Name))
|
||
{
|
||
return( SMS_YES);
|
||
}
|
||
|
||
ND_Index_Node_Next_Get( &Node, Node);
|
||
}
|
||
|
||
/* D<>verrouillage <20>ventuel du heap syst<73>me */
|
||
|
||
if( Locked == TRUE)
|
||
{
|
||
SM_Heap_Unlock_I( System_Heap);
|
||
}
|
||
|
||
return( SMS_NO);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Ouverture/cr<63>ation d'un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap_Name: nom du heap */
|
||
/* (O) Heap_Ptr_Ptr: pointeur sur le heap ouvert / cr<63><72> */
|
||
/* (I) Seg_Size: taille des segments du heap */
|
||
/* (I) Open_Mode: mode d'ouverture du heap */
|
||
/* (O) Locked: verrou effectif (TRUE ou FALSE) */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_Open_I( const char *Heap_Name, SMT_Heap **Heap_Ptr_Ptr, size_t Seg_Size, SMT_Flags Open_Mode, int *Locked)
|
||
{
|
||
SMT_MHH *MHH;
|
||
NDT_Node *Node_Ptr;
|
||
SMT_DSH *New_DSH;
|
||
char prefixed_name[ SMD_NAME_SIZE];
|
||
union semun Sem_Ctl;
|
||
int SemId;
|
||
SMT_Status rc;
|
||
NDT_Index_Type index_type = ( NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_FIFO);
|
||
|
||
|
||
*Locked = FALSE;
|
||
|
||
/* On regarde si le heap est d<>j<EFBFBD> ouvert par le processus courant */
|
||
|
||
if( SM_Heap_IsOpen_I( Heap_Name, Heap_Ptr_Ptr) == SMS_YES)
|
||
{
|
||
if( Open_Mode & SMD_OPEN)
|
||
{
|
||
/* Verrouillage du heap dans le mode demand<6E> */
|
||
|
||
rc = SM_Heap_Lock_I( *Heap_Ptr_Ptr, SMD_LOCK_MSK( Open_Mode), Locked);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_2( "Unable to lock heap: [%s] for: [%s]", Heap_Name, Open_Mode & SMD_READ ? "reading" : "writing");
|
||
|
||
return( rc);
|
||
}
|
||
|
||
return( SMS_OK);
|
||
}
|
||
else
|
||
{
|
||
LG_LOG_ERROR_0( "The heap already exists but (Flags & SMD_OPEN) is false");
|
||
|
||
return( SMS_ERRAPI);
|
||
}
|
||
}
|
||
|
||
|
||
SM_Name_Prefix( prefixed_name, Heap_Name);
|
||
|
||
|
||
/* On regarde si le heap existe d<>j<EFBFBD> dans la base */
|
||
|
||
if( SM_Heap_Exist_I( Heap_Name) == SMS_YES)
|
||
{
|
||
if( Open_Mode & SMD_OPEN)
|
||
{
|
||
SMT_MHH To_Find;
|
||
|
||
|
||
/* Ouverture d'un heap existant */
|
||
|
||
strcpy( To_Find.Name, prefixed_name);
|
||
ND_Index_Node_Find( &Node_Ptr, SM_Base->MHR, NDD_INDEX_PRIMARY, &To_Find, NULL);
|
||
|
||
MHH = (SMT_MHH *)( Node_Ptr->Value);
|
||
|
||
*Heap_Ptr_Ptr = (SMT_Heap *) malloc( sizeof( SMT_Heap));
|
||
if( !*Heap_Ptr_Ptr)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to allocate memory for the opened heap: [%s]", prefixed_name);
|
||
|
||
return( SMS_ERRMEM);
|
||
}
|
||
|
||
( *Heap_Ptr_Ptr)->Name = strdup( prefixed_name);
|
||
( *Heap_Ptr_Ptr)->MHH = MHH;
|
||
( *Heap_Ptr_Ptr)->Lock_Mode = SMD_NO_LOCK;
|
||
|
||
/* On ouvre tous les segments du heap */
|
||
|
||
ND_Index_Node_First_Get( &Node_Ptr, ( *Heap_Ptr_Ptr)->MHH->DSR, NDD_INDEX_PRIMARY);
|
||
|
||
while( Node_Ptr)
|
||
{
|
||
rc = SM_DataSegment_Open( Node_Ptr->Value);
|
||
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to open one of the data segments of heap: [%s]", prefixed_name);
|
||
|
||
goto Error1;
|
||
}
|
||
|
||
ND_Index_Node_Next_Get( &Node_Ptr, Node_Ptr);
|
||
}
|
||
|
||
( *Heap_Ptr_Ptr)->Nb_Seg = ( *Heap_Ptr_Ptr)->MHH->DSR->Index_Tab[NDD_INDEX_PRIMARY].Node_Number;
|
||
|
||
/* Verrouillage du heap dans le mode demand<6E> */
|
||
|
||
rc = SM_Heap_Lock_I( *Heap_Ptr_Ptr, SMD_LOCK_MSK( Open_Mode), Locked);
|
||
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_2( "Unable to lock heap: [%s] for: [%s]", prefixed_name, Open_Mode & SMD_READ ? "reading" : "writing");
|
||
|
||
goto Error1;
|
||
}
|
||
|
||
/* Ajout au cache des heaps ouverts */
|
||
|
||
rc = ND_DataStruct_Value_Add (Opened_Heap_List, *Heap_Ptr_Ptr);
|
||
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to add heap: [%s] to the opened heap cache", prefixed_name);
|
||
|
||
goto Error2;
|
||
}
|
||
|
||
return( SMS_OK);
|
||
}
|
||
else
|
||
{
|
||
LG_LOG_ERROR_0( "The heap already exists but (Open_Mode & SMD_OPEN) is false");
|
||
|
||
return( SMS_ERRAPI);
|
||
}
|
||
}
|
||
|
||
|
||
if( !( Open_Mode & SMD_CREATE))
|
||
{
|
||
LG_LOG_ERROR_1( "The heap: [%s] does no exist and (Open_Mode & SMD_CREATE) is false", prefixed_name);
|
||
|
||
return( SMS_ERRAPI);
|
||
}
|
||
|
||
|
||
/*Alloc du MHH qui fait l'alloccation du premier segment de donnees*/
|
||
rc = ND_Value_Alloc( (void **)&MHH, SM_Base->MHR, prefixed_name, Seg_Size);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to alloc a new MHH structure");
|
||
|
||
return(SMS_ERRAPI);
|
||
}
|
||
|
||
/* Ajout du nouveau heap <20> la structure MHR */
|
||
|
||
rc = ND_DataStruct_Value_Add( SM_Base->MHR, MHH);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to add the new heap to the MHR structure");
|
||
|
||
goto Error9;
|
||
}
|
||
|
||
/* Verrouillage du nouveau MHH dans le mode demand<6E> */
|
||
|
||
rc = SM_Heap_Lock_Set( MHH, SMD_LOCK_MSK( Open_Mode));
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_2( "Unable to lock heap: [%s] for: [%s]", prefixed_name, Open_Mode & SMD_READ ? "reading" : "writing");
|
||
|
||
goto Error10;
|
||
}
|
||
|
||
*Locked = TRUE;
|
||
|
||
/* Ajout du nouveau heap au cache des heaps ouverts */
|
||
|
||
*Heap_Ptr_Ptr = (SMT_Heap *)malloc( sizeof( SMT_Heap));
|
||
if( !*Heap_Ptr_Ptr)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to allocate memory for a new opened heap: [%s]", prefixed_name);
|
||
|
||
rc = SMS_ERRMEM;
|
||
|
||
goto Error10;
|
||
}
|
||
|
||
( *Heap_Ptr_Ptr)->Name = strdup( prefixed_name);
|
||
( *Heap_Ptr_Ptr)->MHH = MHH;
|
||
( *Heap_Ptr_Ptr)->Lock_Mode = SMD_LOCK_MSK( Open_Mode);
|
||
( *Heap_Ptr_Ptr)->Nb_Seg = 1;
|
||
|
||
rc = ND_DataStruct_Value_Add( Opened_Heap_List, *Heap_Ptr_Ptr);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to add heap: [%s] to the opened heap cache", prefixed_name);
|
||
|
||
goto Error11;
|
||
}
|
||
|
||
return( SMS_OK);
|
||
|
||
|
||
|
||
/* Gestion d'erreur sur cr<63>ation */
|
||
|
||
Error11:
|
||
free( ( *Heap_Ptr_Ptr)->Name);
|
||
free( *Heap_Ptr_Ptr);
|
||
|
||
*Heap_Ptr_Ptr = NULL;
|
||
|
||
Error10:
|
||
ND_DataStruct_Value_Remove( SM_Base->MHR, MHH);
|
||
|
||
Error9:
|
||
ND_DataStruct_Value_Remove( MHH->DSR, New_DSH);
|
||
|
||
Error8:
|
||
ND_Value_Free( MHH->DSR, New_DSH);
|
||
|
||
Error7:
|
||
ND_Deallocator_Exec( MHH->FCR, SM_Base->MHR, SM_Base->MHR->Deallocator_Name, SM_Base->MHR->Deallocator_Ptr, NULL);
|
||
|
||
Error6:
|
||
ND_Deallocator_Exec( MHH->ACR, SM_Base->MHR, SM_Base->MHR->Deallocator_Name, SM_Base->MHR->Deallocator_Ptr, NULL);
|
||
|
||
Error5:
|
||
ND_Deallocator_Exec( MHH->DSR, SM_Base->MHR, SM_Base->MHR->Deallocator_Name, SM_Base->MHR->Deallocator_Ptr, NULL);
|
||
|
||
Error4:
|
||
ND_Deallocator_Exec( MHH, SM_Base->MHR, SM_Base->MHR->Deallocator_Name, SM_Base->MHR->Deallocator_Ptr, NULL);
|
||
|
||
Error3:
|
||
semctl( SemId, 0, IPC_RMID, Sem_Ctl);
|
||
|
||
return( rc);
|
||
|
||
/* Gestion d'erreur sur ouverture */
|
||
|
||
Error2:
|
||
SM_Heap_Unlock_I( *Heap_Ptr_Ptr);
|
||
|
||
Error1:
|
||
free( ( *Heap_Ptr_Ptr)->Name);
|
||
free( *Heap_Ptr_Ptr);
|
||
|
||
*Heap_Ptr_Ptr = NULL;
|
||
|
||
return( rc);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Teste si un heap a d<>j<EFBFBD> <20>t<EFBFBD> ouvert par le processus courant */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap_Name: Nom du heap */
|
||
/* (O) Heap_Ptr_Ptr: pointeur sur le heap ouvert */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_IsOpen_I( const char *Heap_Name, SMT_Heap **Heap_Ptr_Ptr)
|
||
{
|
||
SMT_Status rc;
|
||
char prefixed_name[ SMD_NAME_SIZE];
|
||
SMT_Heap To_Find;
|
||
NDT_Node *Node_Ptr;
|
||
|
||
|
||
*Heap_Ptr_Ptr = NULL;
|
||
|
||
To_Find.Name = prefixed_name;
|
||
SM_Name_Prefix( prefixed_name, Heap_Name);
|
||
|
||
rc = ND_Index_Node_Find( &Node_Ptr, Opened_Heap_List, NDD_INDEX_PRIMARY, &To_Find, NULL);
|
||
|
||
if( ND_ERROR(rc))
|
||
{
|
||
return( SMS_KO);
|
||
}
|
||
else
|
||
{
|
||
if( Node_Ptr == NULL)
|
||
{
|
||
*Heap_Ptr_Ptr = NULL;
|
||
|
||
return( SMS_NO);
|
||
}
|
||
else
|
||
{
|
||
*Heap_Ptr_Ptr = (SMT_Heap *)( Node_Ptr->Value);
|
||
|
||
return( SMS_YES);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Destruction d'un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap : pointeur sur un heap ouvert */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_End_I( const char *Heap_Name )
|
||
{
|
||
SMT_Status rc;
|
||
SMT_Heap * Heap;
|
||
int Locked;
|
||
|
||
|
||
rc = SM_Heap_Exist_I( Heap_Name);
|
||
if( SM_ERROR(rc)) return rc;
|
||
if( rc == SMS_NO)
|
||
{
|
||
LG_LOG_ERROR_1( "SM_Heap_End: heap: [%s] does not exist", Heap_Name);
|
||
|
||
return SMS_KO;
|
||
}
|
||
|
||
rc = SM_Heap_IsOpen_I( Heap_Name, &Heap);
|
||
if( SM_ERROR(rc)) return rc;
|
||
if( rc == SMS_YES)
|
||
{
|
||
/* Verrouillage en <20>criture */
|
||
|
||
rc = SM_Heap_Lock_I( Heap, SMD_WRITE, &Locked);
|
||
}
|
||
else
|
||
{
|
||
/* Ouverture du heap en <20>criture */
|
||
|
||
rc = SM_Heap_Open_I( Heap_Name, &Heap, 0, SMD_OPEN | SMD_WRITE, &Locked);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to open the heap to remove for writing");
|
||
|
||
return( rc);
|
||
}
|
||
}
|
||
|
||
/* Suppression du heap */
|
||
|
||
rc = ND_DataStruct_Value_Remove( SM_Base->MHR, Heap->MHH);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to remove heap: [%s] from the MHR structure", Heap_Name);
|
||
|
||
return( rc);
|
||
}
|
||
|
||
rc = ND_Value_Free( SM_Base->MHR, Heap->MHH);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "SM_Heap_End: unable to free heap: [%s]", Heap_Name);
|
||
|
||
|
||
return( rc);
|
||
}
|
||
|
||
return( SMS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Fermeture d'un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap : pointeur sur un heap ouvert */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_Close_I( SMT_Heap *Heap)
|
||
{
|
||
SMT_Status rc;
|
||
NDT_Node * Node;
|
||
|
||
/*
|
||
Fermeture des segments de donn<6E>es composant le heap
|
||
en commencant par le dernier (important pour le heap syst<73>me)
|
||
*/
|
||
|
||
ND_Index_Node_Last_Get( &Node, Heap->MHH->DSR, NDD_INDEX_PRIMARY);
|
||
while( Node)
|
||
{
|
||
rc = SM_DataSegment_Close( Node->Value);
|
||
if( SM_ERROR(rc)) return rc;
|
||
|
||
ND_Index_Node_Previous_Get( &Node, Node);
|
||
}
|
||
|
||
/* D<>verrouillage du heap */
|
||
|
||
SM_Heap_Unlock_I( Heap);
|
||
|
||
/* Suppression du heap de la liste des heaps ouverts */
|
||
|
||
rc = ND_DataStruct_Value_Remove( Opened_Heap_List, Heap);
|
||
if( SM_ERROR(rc)) return rc;
|
||
|
||
rc = ND_Value_Free( Opened_Heap_List, Heap);
|
||
return rc;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Pose d'un verrou sur un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap : pointeur sur un heap ouvert */
|
||
/* (I) Lock_Mode : mode de verrouillage (SMD_READ ou SMD_WRITE) */
|
||
/* (O) Locked : verrouillage effectu<74> (TRUE ou FALSE) */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_Lock_I( SMT_Heap *Heap, SMT_Flags Lock_Mode, int *Locked )
|
||
{
|
||
SMT_Status rc;
|
||
int Nb_Detected, Nb_Corrected;
|
||
|
||
|
||
if( Lock_Mode == Heap->Lock_Mode)
|
||
{
|
||
/* Rien <20> faire : le heap est d<>j<EFBFBD> verrouill<6C> dans ce mode */
|
||
/*
|
||
fprintf( stderr, "SM_Heap_Lock: heap [%s] already locked in mode: (%d)!\n", Heap->Name, Lock_Mode);
|
||
fflush( stderr);
|
||
*/
|
||
LG_LOG_WARNING_2( "Heap: [%s] already locked in mode: (%d)", Heap->Name, Lock_Mode);
|
||
// LG_STACK_TRACE( LGD_LOG_LEVEL_DEFAULT);
|
||
|
||
*Locked = FALSE;
|
||
// *Locked = TRUE;
|
||
}
|
||
else if( Heap->Lock_Mode == SMD_NO_LOCK)
|
||
{
|
||
/*
|
||
Verrouillage d'un heap qui ne l'<27>tait pas : le heap ayant pu <20>tre modifi<66>
|
||
depuis la derni<6E>re fois qu'on y a acc<63>d<EFBFBD>, il faut proc<6F>der <20> un certain
|
||
nombre de v<>rifications.
|
||
*/
|
||
|
||
/* V<>rification de l'<27>tat du heap */
|
||
|
||
if( Heap->MHH->State == SMD_STATE_CORRUPTED)
|
||
{
|
||
LG_LOG_ERROR_1( "Heap: [%s] is flagged as being corrupted", Heap->Name);
|
||
|
||
return( SMS_KO);
|
||
}
|
||
|
||
/* Verrouillage du heap dans le mode demand<6E> */
|
||
|
||
rc = SM_Heap_Lock_Set( Heap->MHH, Lock_Mode);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_2( "Unable to lock heap [%s] for: [%s]", Heap->Name, Lock_Mode & SMD_READ ? "reading" : "writing");
|
||
|
||
return rc;
|
||
}
|
||
|
||
/* V<>rification de l'<27>tat du heap */
|
||
|
||
if( Heap->MHH->State == SMD_STATE_UNVALIDATED)
|
||
{
|
||
/* Verrouillage du heap en <20>criture pour le v<>rifier */
|
||
|
||
if( Lock_Mode == SMD_READ)
|
||
{
|
||
rc = SM_Heap_Lock_Change( Heap->MHH, SMD_WRITE);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to lock heap: [%s] for writing before checking", Heap->Name);
|
||
|
||
SM_Heap_Unlock_I( Heap);
|
||
return rc;
|
||
}
|
||
}
|
||
|
||
/* V<>rification du heap */
|
||
|
||
Nb_Detected = Nb_Corrected = 0;
|
||
rc = SM_Heap_Check_I( Heap, &Nb_Detected, &Nb_Corrected, SM_stderr);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to check heap: [%s]", Heap->Name);
|
||
|
||
SM_Heap_Unlock_I( Heap);
|
||
return rc;
|
||
}
|
||
|
||
/* On reverrouille <20>ventuellement le heap dans le mode demand<6E> */
|
||
|
||
if( Lock_Mode == SMD_READ)
|
||
{
|
||
rc = SM_Heap_Lock_Change( Heap->MHH, SMD_READ);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to lock heap: [%s] for reading", Heap->Name);
|
||
|
||
SM_Heap_Unlock_I( Heap);
|
||
return rc;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* TEST !!!! */
|
||
|
||
{
|
||
NDT_Node *node_ptr = NULL;
|
||
SMT_Heap *heap_ptr;
|
||
|
||
|
||
if( SM_Heap_IsOpen_I( "system", &heap_ptr) != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Internal Error 1 !");
|
||
}
|
||
else
|
||
{
|
||
if( Heap->Nb_Seg != Heap->MHH->DSR->Index_Tab[NDD_INDEX_PRIMARY].Node_Number)
|
||
{
|
||
ND_Index_Node_First_Get( &node_ptr, Heap->MHH->DSR, NDD_INDEX_PRIMARY);
|
||
|
||
if( node_ptr == NULL)
|
||
{
|
||
LG_LOG_ERROR_0( "Internal Error 2 !");
|
||
}
|
||
else
|
||
{
|
||
while( node_ptr)
|
||
{
|
||
if( ( rc = SM_DataSegment_Open( node_ptr->Value)) != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to open one of the data segments of heap: [%s]",
|
||
( (SMT_MHH *)(node_ptr->Value))->Name);
|
||
}
|
||
else
|
||
{
|
||
// LG_LOG_ERROR_1( "SM_Heap_Lock : Opening Segment (%x)", node_ptr->Value);
|
||
//
|
||
}
|
||
|
||
ND_Index_Node_Next_Get( &node_ptr, node_ptr);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* On v<>rifie qu'aucun nouveau segment n'a <20>t<EFBFBD> ajout<75> depuis la derni<6E>re ouverture */
|
||
|
||
if( Heap->Nb_Seg != Heap->MHH->DSR->Index_Tab[NDD_INDEX_PRIMARY].Node_Number)
|
||
{
|
||
NDT_Node * Node;
|
||
|
||
/* On ouvre tous les segments du heap */
|
||
|
||
ND_Index_Node_First_Get( &Node, Heap->MHH->DSR, NDD_INDEX_PRIMARY);
|
||
while( Node)
|
||
{
|
||
rc = SM_DataSegment_Open (Node->Value);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to open one of the data segments of heap: [%s]", Heap->Name);
|
||
|
||
SM_Heap_Unlock_I( Heap);
|
||
return rc;
|
||
}
|
||
|
||
ND_Index_Node_Next_Get( &Node, Node);
|
||
}
|
||
|
||
Heap->Nb_Seg = Heap->MHH->DSR->Index_Tab[NDD_INDEX_PRIMARY].Node_Number;
|
||
}
|
||
|
||
Heap->Lock_Mode = Lock_Mode;
|
||
*Locked = TRUE;
|
||
}
|
||
else
|
||
{
|
||
/* Verrouillage du heap qui est d<>j<EFBFBD> verrouill<6C> dans un autre mode */
|
||
|
||
rc = SM_Heap_Lock_Change( Heap->MHH, Lock_Mode);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_2( "Unable to change lock of heap: [%s] for [%s]", Heap->Name, Lock_Mode & SMD_READ ? "reading" : "writing");
|
||
|
||
return rc;
|
||
}
|
||
|
||
Heap->Lock_Mode = Lock_Mode;
|
||
*Locked = TRUE;
|
||
}
|
||
|
||
LG_LOG_TRACE_2( LGD_LOG_LEVEL_DEFAULT, "Locked: heap: [%s] lock_mode: (%d)", Heap->Name, Heap->Lock_Mode);
|
||
|
||
return( SMS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Lib<69>ration d'un verrou sur un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap : pointeur sur unheap ouvert */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_Unlock_I( SMT_Heap *Heap)
|
||
{
|
||
SMT_Status rc;
|
||
|
||
|
||
rc = SM_Heap_Lock_Release( Heap->MHH, Heap->Lock_Mode);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_2( "Unable to unlock heap: [%s] for: [%s]",
|
||
Heap->Name, Heap->Lock_Mode & SMD_READ ? "reading" : "writing");
|
||
|
||
|
||
return( rc);
|
||
}
|
||
|
||
Heap->Lock_Mode = SMD_NO_LOCK;
|
||
|
||
LG_LOG_TRACE_2( LGD_LOG_LEVEL_DEFAULT, "Unlocked: heap: [%s] lock_mode: (%d)", Heap->Name, Heap->Lock_Mode);
|
||
|
||
return( SMS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Configuration d'un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap : pointeur sur un heap ouvert */
|
||
/* (I) Tag : type de configuration */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_Config_I( SMT_Heap *Heap, SMT_Config Tag, ... )
|
||
{
|
||
va_list Arguments;
|
||
size_t Size, Current_Size;
|
||
SMT_Status rc;
|
||
|
||
va_start (Arguments, Tag);
|
||
|
||
switch( Tag)
|
||
{
|
||
case SMD_AUTO_COMPRESS:
|
||
{
|
||
Size = va_arg (Arguments, size_t);
|
||
Heap->MHH->Auto_Compress = Size;
|
||
|
||
break;
|
||
}
|
||
|
||
case SMD_SEGMENT_SIZE:
|
||
{
|
||
Size = va_arg (Arguments, size_t);
|
||
Heap->MHH->Segment_Size = Size;
|
||
|
||
break;
|
||
}
|
||
|
||
case SMD_HEAP_LIMIT:
|
||
{
|
||
Size = va_arg (Arguments, size_t);
|
||
Current_Size = 0;
|
||
|
||
if( Size != SMD_UNLIMITED)
|
||
{
|
||
/* On contr<74>le que la limite fix<69>e est inf<6E>rieure <20> la taille actuelle du heap */
|
||
|
||
rc = ND_DataStruct_Traverse( Heap->MHH->DSR, NDD_CMD_VALUE_SUM, (void *)&Current_Size);
|
||
if( rc != NDS_OK) return rc;
|
||
|
||
if( Current_Size > Size)
|
||
{
|
||
LG_LOG_ERROR_1( "The heap has already exceeded the limit size: (%d) bytes", Current_Size);
|
||
|
||
va_end( Arguments);
|
||
return SMS_ERRAPI;
|
||
}
|
||
}
|
||
|
||
Heap->MHH->Limit_Size = Size;
|
||
|
||
break;
|
||
}
|
||
|
||
default:
|
||
{
|
||
LG_LOG_ERROR_1( "Unknown config tag: (%d)", Tag);
|
||
|
||
va_end( Arguments);
|
||
|
||
return SMS_ERRAPI;
|
||
}
|
||
}
|
||
|
||
va_end( Arguments);
|
||
|
||
return SMS_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Compression d'un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap : pointeur sur un heap ouvert */
|
||
/* (O) Compress : pointeur sur la taille m<>moire gagn<67>e */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_Compress_I( SMT_Heap *Heap, size_t *Compress)
|
||
{
|
||
SMT_Status rc;
|
||
NDT_Node *Node;
|
||
|
||
|
||
*Compress = 0;
|
||
|
||
/*
|
||
Pour permettre la compression, il faut que les
|
||
chunks libres soient tri<72>s par adresse.
|
||
*/
|
||
|
||
rc = ND_DataStruct_Reorg (Heap->MHH->FCR);
|
||
if( rc != NDS_OK) return( rc);
|
||
|
||
/* Compression de chaque segment de donn<6E>es du heap */
|
||
|
||
ND_Index_Node_First_Get( &Node, Heap->MHH->DSR, NDD_INDEX_PRIMARY);
|
||
|
||
while( Node)
|
||
{
|
||
*Compress += SM_DataSegment_Compress( (SMT_DSH *)(Node->Value), Heap->MHH->FCR);
|
||
ND_Index_Node_Next_Get( &Node, Node);
|
||
}
|
||
|
||
Heap->MHH->Compress_Nb++;
|
||
|
||
return( SMS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* V<>rification/correction des structures d'un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap : pointeur sur un heap ouvert */
|
||
/* (O) Nb_Detected : pointeur sur le nombre d'erreurs d<>tect<63>es */
|
||
/* (O) Nb_Corrected : pointeur sur le nombre d'erreurs corrig<69>es */
|
||
/* (I) Out : pointeur sur le flux de sortie du rapport */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_Check_I( SMT_Heap *Heap, int *Nb_Detected, int *Nb_Corrected, FILE *Out)
|
||
{
|
||
SMT_Status rc;
|
||
NDT_Node * Node;
|
||
|
||
|
||
LG_LOG_INFO_1( "Checking heap: [%s]", Heap->Name);
|
||
|
||
if( Heap->MHH->DSR->Index_Tab[NDD_INDEX_PRIMARY].Node_Number == 0)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to check heap: [%s] which has no data segment", Heap->Name);
|
||
|
||
( *Nb_Detected) ++;
|
||
|
||
LG_LOG_INFO_2( "(%d) error(s) could not be corrected in heap: [%s] which will be declared as corrupted", *Nb_Detected - *Nb_Corrected, Heap->Name);
|
||
LG_LOG_INFO_0( "Please contact an administrator about it");
|
||
|
||
Heap->MHH->State = SMD_STATE_CORRUPTED;
|
||
|
||
return SMS_ERRAPI;
|
||
}
|
||
else
|
||
{
|
||
/* V<>rification de la structure DSR du heap */
|
||
|
||
LG_LOG_INFO_0( "Checking the DSR node structure");
|
||
|
||
rc = ND_DataStruct_Check (Heap->MHH->DSR, Nb_Detected, Nb_Corrected, Out);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to check the DSR structure");
|
||
|
||
LG_LOG_INFO_2( "(%d) error(s) could not be corrected in heap: [%s] which will be declared as corrupted", *Nb_Detected - *Nb_Corrected, Heap->Name);
|
||
LG_LOG_INFO_0( "Please contact an administrator about it");
|
||
|
||
Heap->MHH->State = SMD_STATE_CORRUPTED;
|
||
|
||
return rc;
|
||
}
|
||
}
|
||
|
||
LG_LOG_INFO_0( "Trying to open every data segment of the heap");
|
||
|
||
/* Ouverture des segments du heap au cas <20>a n'aurait pas <20>t<EFBFBD> fait */
|
||
|
||
ND_Index_Node_First_Get( &Node, Heap->MHH->DSR, NDD_INDEX_PRIMARY);
|
||
|
||
while( Node)
|
||
{
|
||
rc = SM_DataSegment_Open (Node->Value);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to open one of the data segments of heap: [%s]", Heap->Name);
|
||
|
||
( *Nb_Detected) ++;
|
||
|
||
LG_LOG_INFO_2( "(%d) error(s) could not be corrected in heap: [%s] which will be declared as corrupted.",
|
||
*Nb_Detected - *Nb_Corrected, Heap->Name);
|
||
LG_LOG_INFO_0( "Please contact an administrator about it");
|
||
|
||
Heap->MHH->State = SMD_STATE_CORRUPTED;
|
||
|
||
return rc;
|
||
}
|
||
|
||
ND_Index_Node_Next_Get( &Node, Node);
|
||
}
|
||
|
||
|
||
/* V<>rification de la structure ACR du heap */
|
||
|
||
LG_LOG_INFO_0( "Checking the ACR node structure");
|
||
|
||
rc = ND_DataStruct_Check (Heap->MHH->ACR, Nb_Detected, Nb_Corrected, Out);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "SM_Heap_Check : unable to check the ACR node structure");
|
||
|
||
LG_LOG_INFO_2( "(%d) error(s) could not be corrected in heap: [%s] which will be declared as corrupted.",
|
||
*Nb_Detected - *Nb_Corrected, Heap->Name);
|
||
LG_LOG_INFO_0( "Please contact an administrator about it");
|
||
|
||
Heap->MHH->State = SMD_STATE_CORRUPTED;
|
||
|
||
return rc;
|
||
}
|
||
|
||
/* V<>rification de la structure FCR du heap */
|
||
|
||
LG_LOG_INFO_0( "Checking the FCR node structure");
|
||
|
||
rc = ND_DataStruct_Check (Heap->MHH->FCR, Nb_Detected, Nb_Corrected, Out);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to check the ACR node structure");
|
||
|
||
|
||
LG_LOG_INFO_2( "(%d) error(s) could not be corrected in heap: [%s] which will be declared as corrupted", *Nb_Detected - *Nb_Corrected, Heap->Name);
|
||
LG_LOG_INFO_0( "Please contact an administrator about it");
|
||
|
||
Heap->MHH->State = SMD_STATE_CORRUPTED;
|
||
|
||
return rc;
|
||
}
|
||
|
||
/* Conclusion de la proc<6F>dure de v<>rification */
|
||
|
||
if( *Nb_Detected > *Nb_Corrected)
|
||
{
|
||
/* On d<>clare le heap corrompu afin que plus personne n'y acc<63>de */
|
||
|
||
LG_LOG_INFO_2( "(%d) error(s) could not be corrected in heap: [%s] which will be declared as corrupted",
|
||
*Nb_Detected - *Nb_Corrected, Heap->Name);
|
||
LG_LOG_INFO_0( "Please contact an administrator about it");
|
||
|
||
Heap->MHH->State = SMD_STATE_CORRUPTED;
|
||
|
||
return SMS_KO;
|
||
}
|
||
|
||
/* On rend le heap valide */
|
||
|
||
if( *Nb_Detected == 0)
|
||
{
|
||
LG_LOG_INFO_1( "No error detected on heap: [%s] which will be declared as a valid heap", Heap->Name);
|
||
}
|
||
else
|
||
{
|
||
LG_LOG_WARNING_2( "Every (%d) error(s) have beeen corrected on heap: [%s] which will be declared as a valid heap", *Nb_Corrected, Heap->Name);
|
||
}
|
||
|
||
Heap->MHH->State = SMD_STATE_VALID;
|
||
|
||
return SMS_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Allocation d'un chunk dans un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap : pointeur sur un heap ouvert */
|
||
/* (I) Size : taille du chunk */
|
||
/* (O) Ptr : adresse d'un pointeur sur la zone de donn<6E>es allou<6F>e */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Chunk_Alloc_I( SMT_Heap *Heap, size_t Alloc_Size, void **Ptr )
|
||
{
|
||
NDT_Node * Node;
|
||
SMT_Chunk * Chunk;
|
||
SMT_DSH * DSH;
|
||
int Found;
|
||
size_t Round_Size;
|
||
SMT_Status rc;
|
||
|
||
|
||
*Ptr = NULL;
|
||
|
||
/*
|
||
On invalide le heap jusqu'<27> ce que la proc<6F>dure d'allocation soit enti<74>rement termin<69>e.
|
||
Ainsi, si celle-ci est interrompue, le heap restera invalide jusqu'<27> ce qu'il soit
|
||
"r<>par<61>" (appel de la fonction SM_Heap_Check par la fonction SM_Heap_Open).
|
||
*/
|
||
|
||
Heap->MHH->State = SMD_STATE_UNVALIDATED;
|
||
|
||
/*
|
||
Pour le heap syst<73>me, tous les chunks allou<6F>s ont la m<>me taille (DEFAULT_CHUNK_SIZE).
|
||
Ceci facilite notamment la r<>cup<75>ration des errors (Recovery) dans le heap syst<73>me.
|
||
Ceci a aussi pour but de simplifier (et donc d'optimiser) l'allocation de nouveaux chunks
|
||
dans ce heap syst<73>me dont la m<>moire n'a pas besoin d'<27>tre optimis<69>e.
|
||
|
||
*/
|
||
|
||
if( Heap == System_Heap) Alloc_Size = DEFAULT_CHUNK_SIZE;
|
||
|
||
/*
|
||
Attention : pour les autres heaps, la taille allou<6F>e doit <20>tre arrondie <20> un multiple
|
||
de 4 octets (en 32 bits) afin que les adresses des chunks soient align<67>es (sinon SIGBUS !).
|
||
*/
|
||
|
||
Round_Size = Alloc_Size % sizeof (void *);
|
||
|
||
if( Round_Size) Alloc_Size += sizeof (void *) - Round_Size;
|
||
|
||
/* Recherche d'un chunk suffisamment grand dans la liste des chunks libres */
|
||
|
||
Found = FALSE;
|
||
|
||
ND_Index_Node_First_Get( &Node, Heap->MHH->FCR, NDD_INDEX_PRIMARY);
|
||
while( Found == FALSE && Node)
|
||
{
|
||
Chunk = (SMT_Chunk *)(Node->Value);
|
||
|
||
if( Chunk->Size >= Alloc_Size) Found = TRUE;
|
||
else ND_Index_Node_Next_Get( &Node, Node);
|
||
}
|
||
|
||
if( Found == FALSE)
|
||
{
|
||
/*
|
||
Si aucun chunk libre suffisamment grand n'a <20>t<EFBFBD> trouv<75>,
|
||
alors on cr<63>e un nouveau segment de donn<6E>es.
|
||
*/
|
||
|
||
size_t Seg_Size;
|
||
|
||
if( Alloc_Size + sizeof (NDT_Node) + sizeof (SMT_Chunk) > Heap->MHH->Segment_Size)
|
||
Seg_Size = Alloc_Size + sizeof (NDT_Node) + sizeof (SMT_Chunk);
|
||
else
|
||
Seg_Size = Heap->MHH->Segment_Size;
|
||
|
||
|
||
rc = ND_Value_Alloc( (void**)&DSH, Heap->MHH->DSR, Heap->MHH, Seg_Size);
|
||
if( rc != NDS_OK )
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to create a new data segment for heap: [%s]", Heap->Name);
|
||
|
||
return SMS_ERRSHM;
|
||
}
|
||
|
||
rc = ND_DataStruct_Value_Add (Heap->MHH->DSR, DSH);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to add a data segment to the DSR structure of heap: [%s]", Heap->Name);
|
||
|
||
ND_Value_Free(Heap->MHH->DSR, DSH);
|
||
|
||
return rc;
|
||
}
|
||
|
||
/*
|
||
Maintenant que l'on a ajout<75> un segment de donn<6E>es, il existe
|
||
un chunk libre suffisamment grand au d<>but de ce segment.
|
||
*/
|
||
|
||
Node = (NDT_Node *)DSH->Start;
|
||
Chunk = (SMT_Chunk *)(Node->Value);
|
||
}
|
||
|
||
/* Suppression du chunk de la liste des chunks libres */
|
||
|
||
rc = ND_Index_Node_Remove( Node);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to remove a chunk from the FCR structure of heap: [%s]", Heap->Name);
|
||
|
||
return rc;
|
||
}
|
||
|
||
/* Ajout du chunk <20> la liste des chunks allou<6F>s */
|
||
|
||
rc = ND_Index_Node_Add( Heap->MHH->ACR, NDD_INDEX_PRIMARY, Node);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to add a chunk to the ACR structure of heap: [%s]", Heap->Name);
|
||
|
||
/* On tente de revenir en arri<72>re */
|
||
|
||
ND_Index_Node_Add( Heap->MHH->FCR, NDD_INDEX_PRIMARY, Node);
|
||
|
||
return rc;
|
||
}
|
||
|
||
/*
|
||
Si le chunk trouv<75> est plus grand que ce dont on a besoin, alors
|
||
on peut cr<63>er un nouveau chunk libre avec le reliquat de m<>moire.
|
||
*/
|
||
|
||
if( Chunk->Size - Alloc_Size > 0)
|
||
{
|
||
size_t Remaining_Size = Chunk->Size - Alloc_Size;
|
||
|
||
/*
|
||
La cr<63>ation d'un nouveau chunk libre requiert de la place pour les
|
||
donn<6E>es syst<73>me (SMT_Chunk + NDT_Node) : on ne cr<63>e donc un nouveau
|
||
chunk libre que si le reliquat est suffisamment important.
|
||
*/
|
||
|
||
if( Remaining_Size > sizeof (SMT_Chunk) + sizeof (NDT_Node))
|
||
{
|
||
NDT_Node * New_Node;
|
||
SMT_Chunk * New_Chunk;
|
||
size_t New_Chunk_Size;
|
||
|
||
/* Cr<43>ation d'un nouveau chunk libre (noeud puis valeur) juste derri<72>re le chunk trouv<75> */
|
||
|
||
New_Node = (NDT_Node *)( (size_t)(Chunk->Data) + Alloc_Size);
|
||
|
||
New_Chunk = (SMT_Chunk *)( (size_t)New_Node + sizeof (NDT_Node) );
|
||
|
||
New_Chunk_Size = Remaining_Size - sizeof (SMT_Chunk) - sizeof (NDT_Node);
|
||
|
||
New_Chunk->Size = New_Chunk_Size;
|
||
|
||
New_Chunk->Data = (void *)( (size_t)(New_Chunk) + sizeof (SMT_Chunk) );
|
||
|
||
New_Node->Root = NULL;
|
||
New_Node->Parent = NULL;
|
||
New_Node->Left = NULL;
|
||
New_Node->Right = NULL;
|
||
New_Node->Value = New_Chunk;
|
||
|
||
rc = ND_Index_Node_Add( Heap->MHH->FCR, NDD_INDEX_PRIMARY, New_Node);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to add a chunk to the FCR structure of heap: [%s]", Heap->Name);
|
||
|
||
return rc;
|
||
}
|
||
|
||
/* Ajustement du chunk allou<6F> */
|
||
|
||
Chunk->Size = Alloc_Size;
|
||
}
|
||
}
|
||
|
||
/*
|
||
Pour une allocation dans le heap syst<73>me, on anticipe l'ajout
|
||
d'un nouveau segment pour <20>viter de se retrouver bloqu<71>.
|
||
|
||
Bien entendu, cette op<6F>ration n'est faite que si l'on n'est
|
||
pas d<>j<EFBFBD> en train d'<27>tendre le heap syst<73>me (Adding_Segment=TRUE).
|
||
*/
|
||
|
||
if( Heap == System_Heap && Adding_Segment == FALSE)
|
||
{
|
||
SMT_Chunk * Free_Chunk;
|
||
unsigned int Free_Usable_Chunk = 0;
|
||
size_t Free_Usable_Size = 0;
|
||
int New_Seg_Needed = FALSE;
|
||
|
||
/* On compte le nombre de chunks libres "utilisables" dans la structure FCR */
|
||
|
||
ND_Index_Node_First_Get( &Node, Heap->MHH->FCR, NDD_INDEX_PRIMARY);
|
||
while( Node)
|
||
{
|
||
Free_Chunk = Node->Value;
|
||
|
||
if( Free_Chunk->Size >= DEFAULT_CHUNK_SIZE)
|
||
{
|
||
Free_Usable_Chunk++;
|
||
Free_Usable_Size += Free_Chunk->Size;
|
||
}
|
||
|
||
ND_Index_Node_Next_Get( &Node, Node);
|
||
}
|
||
|
||
/*
|
||
S'il reste au moins FREE_CHUNK_LIMIT chunks libres "utilisables"
|
||
ou bien si ces chunks libres "utilisables" repr<70>sentent suffisament de
|
||
place pour allouer FREE_CHUNK_LIMIT nouveaux chunks, alors tout est OK.
|
||
|
||
Dans le cas contraire, il est urgent d'<27>tendre le heap syst<73>me.
|
||
*/
|
||
|
||
if( Free_Usable_Chunk < FREE_CHUNK_LIMIT)
|
||
{
|
||
size_t Needed_Size;
|
||
|
||
Needed_Size = (size_t)(FREE_CHUNK_LIMIT * DEFAULT_CHUNK_SIZE) + (size_t)(FREE_CHUNK_LIMIT - Free_Usable_Chunk) * (sizeof (NDT_Node) + sizeof (SMT_Chunk));
|
||
|
||
if( Free_Usable_Size < Needed_Size) New_Seg_Needed = TRUE;
|
||
}
|
||
|
||
if( New_Seg_Needed == TRUE)
|
||
{
|
||
NDT_Node * New_Node;
|
||
|
||
/*
|
||
Puisque l'ajout d'un nouveau segment va appeler cette m<>me fonction,
|
||
on positionne une variable globale pour ne pas recommencer cette op<6F>ration.
|
||
*/
|
||
|
||
Adding_Segment = TRUE;
|
||
|
||
/*
|
||
On alloue le noeud du nouveau segment avant de faire appel <20> la fonction
|
||
ND_Value_Alloc pour <20>viter que ce noeud soit allou<6F> dans le nouveau segment.
|
||
*/
|
||
|
||
SM_System_Alloc( (void **)(&New_Node), NULL, sizeof (NDT_Node), NULL);
|
||
New_Node->Root = NULL;
|
||
New_Node->Parent = NULL;
|
||
New_Node->Left = NULL;
|
||
New_Node->Right = NULL;
|
||
|
||
/* On cr<63>e le nouveau segment */
|
||
rc = ND_Value_Alloc( (void**)&DSH, Heap->MHH->DSR, Heap->MHH, Heap->MHH->Segment_Size);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to create un new data segment for the system heap (anticipation)");
|
||
|
||
|
||
return SMS_ERRSHM;
|
||
}
|
||
|
||
New_Node->Value = DSH;
|
||
|
||
/* On ajoute le nouveau segment au heap syst<73>me */
|
||
|
||
rc = ND_Index_Node_Add( Heap->MHH->DSR, NDD_INDEX_PRIMARY, New_Node);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to add a data segment to the DSR structure of the system heap (anticipation)");
|
||
|
||
ND_Value_Free( Heap->MHH->DSR, DSH);
|
||
return rc;
|
||
}
|
||
|
||
Adding_Segment = FALSE;
|
||
}
|
||
}
|
||
|
||
/*
|
||
Puisque la proc<6F>dure d'allocation d'un chunk s'est correctement
|
||
termin<69>e, on peut rendre le heap <20> nouveau valide.
|
||
*/
|
||
|
||
Heap->MHH->State = SMD_STATE_VALID;
|
||
|
||
*Ptr = Chunk->Data;
|
||
|
||
return SMS_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* D<>sallocation d'un chunk */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap : pointeur sur un heap ouvert */
|
||
/* (I) Ptr : pointeur sur la zone de donn<6E>es du chunk <20> d<>sallouer */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Chunk_Free_I( SMT_Heap *Heap, void *Ptr)
|
||
{
|
||
NDT_Node * Node;
|
||
SMT_Chunk * Chunk;
|
||
SMT_Status rc;
|
||
|
||
/*
|
||
On invalide le heap jusqu'<27> ce que la proc<6F>dure de d<>sallocation soit enti<74>rement termin<69>e.
|
||
Ainsi, si celle-ci est interrompue, le heap restera invalide jusqu'<27> ce qu'il soit
|
||
"r<>par<61>" (appel de la fonction SM_Heap_Check par la fonction SM_Heap_Open).
|
||
*/
|
||
|
||
Heap->MHH->State = SMD_STATE_UNVALIDATED;
|
||
|
||
/*
|
||
Le noeud du chunk <20>tant adjoint <20> celui-ci, on n'a pas besoin
|
||
de le rechercher dans la liste des chunks allou<6F>s.
|
||
*/
|
||
|
||
Node = (NDT_Node *)( (size_t)Ptr - sizeof (SMT_Chunk) - sizeof (NDT_Node));
|
||
|
||
Chunk = Node->Value;
|
||
|
||
/* Suppression du chunk de la liste des chunks allou<6F>s */
|
||
|
||
rc = ND_Index_Node_Remove( Node);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to remove the allocated chunk from the ACR structure of heap: [%s]", Heap->Name);
|
||
|
||
return rc;
|
||
}
|
||
|
||
/* Ajout du chunk <20> la liste des chunks libres */
|
||
|
||
rc = ND_Index_Node_Add( Heap->MHH->FCR, NDD_INDEX_PRIMARY, Node);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to add the free chunk to the FCR structure of heap: [%s]", Heap->Name);
|
||
|
||
/* Retour arri<72>re */
|
||
|
||
ND_Index_Node_Add( Heap->MHH->ACR, NDD_INDEX_PRIMARY, Node);
|
||
|
||
return rc;
|
||
}
|
||
|
||
/*
|
||
Puisque la proc<6F>dure de d<>sallocation d'un chunk s'est correctement
|
||
termin<69>, on peut rendre le heap <20> nouveau valide.
|
||
*/
|
||
|
||
Heap->MHH->State = SMD_STATE_VALID;
|
||
|
||
/* Activation de la compression automatique */
|
||
|
||
if( Heap->MHH->Auto_Compress != SMD_NO_AUTO_COMPRESS &&
|
||
Heap->MHH->FCR->Index_Tab[NDD_INDEX_PRIMARY].Node_Number > Heap->MHH->Auto_Compress)
|
||
{
|
||
size_t Compress_Size;
|
||
|
||
rc = SM_Heap_Compress (Heap, &Compress_Size);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_2( "Unable to compress FCR structure of heap: [%s] which contains: (%ld) free chunks", Heap->Name, Heap->MHH->FCR->Index_Tab[NDD_INDEX_PRIMARY].Node_Number);
|
||
|
||
return rc;
|
||
}
|
||
}
|
||
|
||
return SMS_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* FONCTIONS SECURISEES (SM_MODE = 0) */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Ouverture d'une instance de la librairie */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Instance : instance de la librairie */
|
||
/* (I) Context : nom du nouveau contexte */
|
||
/* (I) Open_Mode : indicateur cr<63>ation/ouverture + mode d'affichage des erreurs */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Library_Open_C( int Instance, const char *Context, SMT_Flags Open_Mode)
|
||
{
|
||
return SM_Library_Open_I( Instance, Context, Open_Mode);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* R<>cup<75>ration du num<75>ro de l'instance utilis<69>e */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (O) Instance : adresse du num<75>ro de l'instance utilis<69>e */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Library_Instance_Get_C( int *Instance)
|
||
{
|
||
return SM_Library_Instance_Get_I( Instance);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* R<>cup<75>ration du nom du contexte utilis<69> */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (O) Context : adresse du nom du contexte utilis<69> */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Library_Context_Get_C( char **Context)
|
||
{
|
||
return SM_Library_Context_Get_I( Context);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Changement de contexte d'utilisation de la librairie */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Context : nom du nouveau contexte */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Library_Context_Set_C( const char *Context)
|
||
{
|
||
return SM_Library_Context_Set_I( Context);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Fermeture de l'instance de la librairie */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Close_Mode : mode de fermeture (destruction ou fermeture simple) */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Library_Close_C( SMT_Flags Close_Mode)
|
||
{
|
||
SM_LIBSHMEM_OPEN_CHECK();
|
||
|
||
return SM_Library_Close_I( Close_Mode);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Affichage des informations de la base de m<>moires partag<61>es */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Library_Dump_C( FILE *Out)
|
||
{
|
||
SM_LIBSHMEM_OPEN_CHECK();
|
||
|
||
return SM_Library_Dump_I( Out);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Lib<69>ration de tous les verrous (base, heap) */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Library_Unlock_C( void)
|
||
{
|
||
SM_LIBSHMEM_OPEN_CHECK();
|
||
|
||
return SM_Library_Unlock_I( );
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* D<>finition de la sortie standard des messages d'erreur de la librairie */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Library_Stderr_Set_C( FILE *Out)
|
||
{
|
||
return SM_Library_Stderr_Set_I( Out);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Test d'existence d'un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap_Name : Nom du heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_Exist_C( const char *Heap_Name)
|
||
{
|
||
SM_LIBSHMEM_OPEN_CHECK();
|
||
SM_HEAP_NAME_CHECK( Heap_Name);
|
||
|
||
return SM_Heap_Exist_I( Heap_Name);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Ouverture/cr<63>ation d'un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap_Name : nom du heap */
|
||
/* (O) Heap : pointeur sur le heap ouvert / cr<63><72> */
|
||
/* (I) Seg_Size : taille des segments du heap */
|
||
/* (I) Open_Mode : mode d'ouverture du heap */
|
||
/* (O) Locked : verrou effectif (TRUE ou FALSE) */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_Open_C( const char * Heap_Name, SMT_Heap **Heap_Ptr_Ptr, size_t Seg_Size, SMT_Flags Open_Mode, int *Locked)
|
||
{
|
||
SM_LIBSHMEM_OPEN_CHECK();
|
||
SM_HEAP_NAME_CHECK( Heap_Name);
|
||
|
||
return SM_Heap_Open_I( Heap_Name, Heap_Ptr_Ptr, Seg_Size, Open_Mode, Locked);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Teste si un heap a d<>j<EFBFBD> <20>t<EFBFBD> ouvert par le processus courant */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap_Name : Nom du heap */
|
||
/* (O) Heap : pointeur sur le heap ouvert */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_IsOpen_C( const char * Heap_Name, SMT_Heap ** Heap )
|
||
{
|
||
SM_LIBSHMEM_OPEN_CHECK();
|
||
SM_HEAP_NAME_CHECK( Heap_Name);
|
||
|
||
return SM_Heap_IsOpen_I( Heap_Name, Heap);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Destruction d'un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap : pointeur sur un heap ouvert */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_End_C( const char * Heap_Name )
|
||
{
|
||
SM_LIBSHMEM_OPEN_CHECK();
|
||
SM_HEAP_NAME_CHECK( Heap_Name);
|
||
|
||
return SM_Heap_End_I( Heap_Name);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Fermeture d'un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap : pointeur sur un heap ouvert */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_Close_C( SMT_Heap *Heap_Ptr)
|
||
{
|
||
SM_LIBSHMEM_OPEN_CHECK();
|
||
SM_HEAP_CHECK( Heap_Ptr);
|
||
|
||
return SM_Heap_Close_I( Heap_Ptr);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Pose d'un verrou sur un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap : pointeur sur un heap ouvert */
|
||
/* (I) Lock_Mode : mode de verrouillage (SMD_READ ou SMD_WRITE) */
|
||
/* (O) Locked : verrouillage effectu<74> (TRUE ou FALSE) */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_Lock_C( SMT_Heap *Heap_Ptr, SMT_Flags Lock_Mode, int * Locked )
|
||
{
|
||
SM_LIBSHMEM_OPEN_CHECK();
|
||
SM_HEAP_CHECK( Heap_Ptr);
|
||
|
||
return SM_Heap_Lock_I( Heap_Ptr, Lock_Mode, Locked);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Lib<69>ration d'un verrou sur un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap : pointeur sur unheap ouvert */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_Unlock_C( SMT_Heap *Heap_Ptr)
|
||
{
|
||
SM_LIBSHMEM_OPEN_CHECK();
|
||
SM_HEAP_CHECK( Heap_Ptr);
|
||
|
||
return SM_Heap_Unlock_I( Heap_Ptr);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Configuration d'un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap : pointeur sur un heap ouvert */
|
||
/* (I) Tag : type de configuration */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_Config_C( SMT_Heap *Heap_Ptr, SMT_Config Tag, ... )
|
||
{
|
||
va_list Arguments;
|
||
size_t Segment_Size, Limit_Size, Current_Size;
|
||
SMT_Status rc;
|
||
|
||
|
||
SM_LIBSHMEM_OPEN_CHECK();
|
||
SM_HEAP_CHECK( Heap_Ptr);
|
||
|
||
va_start (Arguments, Tag);
|
||
|
||
switch( Tag)
|
||
{
|
||
case SMD_SEGMENT_SIZE:
|
||
{
|
||
|
||
Segment_Size = va_arg (Arguments, size_t);
|
||
Heap_Ptr->MHH->Segment_Size = Segment_Size;
|
||
|
||
break;
|
||
}
|
||
|
||
case SMD_HEAP_LIMIT:
|
||
{
|
||
Limit_Size = va_arg (Arguments, size_t);
|
||
Current_Size = 0;
|
||
|
||
if( Limit_Size != SMD_UNLIMITED)
|
||
{
|
||
/* On contr<74>le que la limite fix<69>e est inf<6E>rieure <20> la taille actuelle du heap */
|
||
|
||
rc = ND_DataStruct_Traverse( Heap_Ptr->MHH->DSR, NDD_CMD_VALUE_SUM, (void *)&Current_Size);
|
||
if( rc != NDS_OK) return rc;
|
||
|
||
if( Current_Size > Limit_Size)
|
||
{
|
||
LG_LOG_ERROR_1( "The heap has already exceeded the limit size: (%d) bytes", Current_Size);
|
||
|
||
va_end( Arguments);
|
||
return SMS_ERRAPI;
|
||
}
|
||
}
|
||
|
||
Heap_Ptr->MHH->Limit_Size = Limit_Size;
|
||
|
||
break;
|
||
}
|
||
|
||
default:
|
||
{
|
||
LG_LOG_ERROR_1( "Unknown config tag: (%d)", Tag);
|
||
|
||
va_end( Arguments);
|
||
return SMS_ERRAPI;
|
||
}
|
||
}
|
||
|
||
va_end( Arguments);
|
||
|
||
return SMS_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Compression d'un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap : pointeur sur un heap ouvert */
|
||
/* (O) Compress : pointeur sur la taille m<>moire gagn<67>e */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_Compress_C( SMT_Heap *Heap_Ptr, size_t *Compress)
|
||
{
|
||
SM_LIBSHMEM_OPEN_CHECK();
|
||
SM_HEAP_CHECK( Heap_Ptr);
|
||
|
||
if( !Compress)
|
||
{
|
||
LG_LOG_ERROR_0( "The compress size pointer is null");
|
||
|
||
return SMS_ERRAPI;
|
||
}
|
||
|
||
return SM_Heap_Compress_I( Heap_Ptr, Compress);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* V<>rification/correction des structures d'un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap : pointeur sur un heap ouvert */
|
||
/* (O) Nb_Detected : pointeur sur le nombre d'erreurs d<>tect<63>es */
|
||
/* (O) Nb_Corrected : pointeur sur le nombre d'erreurs corrig<69>es */
|
||
/* (I) Out : pointeur sur le flux de sortie du rapport */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_Check_C( SMT_Heap *Heap_Ptr, int *Nb_Detected, int *Nb_Corrected, FILE *Out)
|
||
{
|
||
SM_LIBSHMEM_OPEN_CHECK();
|
||
SM_HEAP_CHECK( Heap_Ptr);
|
||
|
||
if( !Nb_Detected || !Nb_Corrected)
|
||
{
|
||
LG_LOG_ERROR_0( "The error number pointer is null");
|
||
|
||
return SMS_ERRAPI;
|
||
}
|
||
|
||
if( !Out)
|
||
{
|
||
LG_LOG_ERROR_0( "The out stream is null");
|
||
|
||
return SMS_ERRAPI;
|
||
}
|
||
|
||
return SM_Heap_Check_I( Heap_Ptr, Nb_Detected, Nb_Corrected, Out);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Allocation d'un chunk dans un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap : pointeur sur un heap ouvert */
|
||
/* (I) Size : taille du chunk */
|
||
/* (O) Ptr : adresse d'un pointeur sur la zone de donn<6E>es allou<6F>e */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Chunk_Alloc_C( SMT_Heap *Heap_Ptr, size_t Alloc_Size, void **Ptr)
|
||
{
|
||
SM_LIBSHMEM_OPEN_CHECK();
|
||
SM_HEAP_CHECK( Heap_Ptr);
|
||
|
||
if( !Ptr)
|
||
{
|
||
LG_LOG_ERROR_0( "The chunk address is null");
|
||
|
||
return SMS_ERRAPI;
|
||
}
|
||
|
||
return SM_Chunk_Alloc_I( Heap_Ptr, Alloc_Size, Ptr);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* D<>sallocation d'un chunk */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (I) Heap : pointeur sur un heap ouvert */
|
||
/* (I) Ptr : pointeur sur la zone de donn<6E>es du chunk <20> d<>sallouer */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Chunk_Free_C( SMT_Heap *Heap_Ptr, void *Ptr)
|
||
{
|
||
SM_LIBSHMEM_OPEN_CHECK();
|
||
SM_HEAP_CHECK( Heap_Ptr);
|
||
|
||
if( !Ptr)
|
||
{
|
||
LG_LOG_ERROR_0( "The chunk pointer is null");
|
||
|
||
return SMS_ERRAPI;
|
||
}
|
||
|
||
return SM_Chunk_Free_I( Heap_Ptr, Ptr);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/*------------------------------------------------------------------------------*/
|
||
/* FONCTIONS PRIVEES */
|
||
/*------------------------------------------------------------------------------*/
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Allocation de m<>moire dans la base */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
NDT_Status SM_Base_Alloc( void **Ptr, NDT_Root *ND_Root_Ptr, size_t Size, void *Data_Ptr)
|
||
{
|
||
*Ptr = SM_Base->Free;
|
||
SM_Base->Free = (void *)( (size_t)(SM_Base->Free) + Size);
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* D<>sallocation de m<>moire dans la base */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
NDT_Status SM_Base_Free( void *Ptr, NDT_Root *ND_Root_Ptr, void *Data_Ptr)
|
||
{
|
||
if( !Ptr) return( SMS_ERRAPI);
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Allocation de m<>moire dans le heap syst<73>me */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
NDT_Status SM_System_Alloc( void **Ptr, NDT_Root *ND_Root_Ptr, size_t Size, void *Data_Ptr)
|
||
{
|
||
return( SM_Chunk_Alloc_I( System_Heap, Size, Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* D<>sallocation de m<>moire dans le heap syst<73>me */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
NDT_Status SM_System_Free( void *Ptr, NDT_Root *ND_Root_Ptr, void *Data_Ptr)
|
||
{
|
||
return( SM_Chunk_Free_I( System_Heap, Ptr));
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Initialisation de la base */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Base_Init ( void )
|
||
{
|
||
SMT_Status rc;
|
||
int SemId;
|
||
int SysMemId;
|
||
int DataMemId;
|
||
union semun Sem_Ctl;
|
||
size_t Size;
|
||
int Locked;
|
||
NDT_Index_Type index_type = ( NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_FIFO);
|
||
|
||
|
||
/* Cr<43>ation du s<>maphore pour la gestion des verrous sur la base */
|
||
|
||
SemId = semget (IPC_PRIVATE, 1, 0777|IPC_CREAT|IPC_EXCL);
|
||
if( SemId == -1)
|
||
{
|
||
switch( errno)
|
||
{
|
||
case ENOMEM:
|
||
{
|
||
LG_LOG_ERROR_0( "The amount of memory is not sufficient to create a new semaphore");
|
||
break;
|
||
}
|
||
|
||
case ENOSPC:
|
||
{
|
||
break;
|
||
}
|
||
|
||
default:
|
||
{
|
||
LG_LOG_ERROR_1( "Unknown error: (%d) while creating a semaphore", errno);
|
||
break;
|
||
}
|
||
}
|
||
|
||
return SMS_ERRSEM;
|
||
}
|
||
|
||
/* Initialisation du s<>maphore <20> 1 (aucun verrou) */
|
||
|
||
Sem_Ctl.val = 1;
|
||
|
||
if( semctl( SemId, 0, SETVAL, Sem_Ctl ))
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to initialize the value of semaphore: (%d)", SemId);
|
||
|
||
rc = SMS_ERRSEM;
|
||
goto Error1;
|
||
}
|
||
|
||
|
||
/*
|
||
Cr<43>ation d'un segment de m<>moire partag<61>e qui contiendra la structure SMT_Base.
|
||
Ce segment peut <20>tre attach<63> <20> n'importe quelle adresse.
|
||
*/
|
||
|
||
SysMemId = shmget( SM_Instance, (int) sizeof( SMT_Base), ( 0777 | IPC_CREAT | IPC_EXCL));
|
||
if( SysMemId == -1)
|
||
{
|
||
switch( errno)
|
||
{
|
||
case EEXIST:
|
||
{
|
||
LG_LOG_ERROR_1( "The shared memory segment identifier: (%d) already exists", SM_Instance);
|
||
break;
|
||
}
|
||
|
||
case EINVAL:
|
||
{
|
||
LG_LOG_ERROR_1( "The size of the shared memory segment: (%d) is out of the system-imposed bounds", sizeof( SMT_Base));
|
||
break;
|
||
}
|
||
|
||
case ENOMEM:
|
||
{
|
||
LG_LOG_ERROR_0( "The amount of memory is not sufficient to create the shared memory segment");
|
||
break;
|
||
}
|
||
|
||
case ENOSPC:
|
||
{
|
||
LG_LOG_ERROR_0( "The number of shared memory segments exceeds the system-imposed limit");
|
||
break;
|
||
}
|
||
|
||
default:
|
||
{
|
||
LG_LOG_ERROR_1( "Unknown error: (%d) while creating the shared memory segment", errno);
|
||
break;
|
||
}
|
||
}
|
||
|
||
rc = SMS_ERRSHM;
|
||
goto Error1;
|
||
}
|
||
|
||
|
||
/* On attache le segment de m<>moire partag<61>e au processus courant */
|
||
|
||
errno = 0;
|
||
SM_Base = shmat( SysMemId, 0, 0);
|
||
if( errno)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to attach the first shared memory segment to the current process, error: (%d)", errno);
|
||
|
||
rc = SMS_ERRSHM;
|
||
goto Error2;
|
||
}
|
||
|
||
/*
|
||
Attention : tant que le heap syst<73>me n'est pas cr<63><72>, on est oblig<69> d'allouer de
|
||
la m<>moire dans le segment de m<>moire partag<61>e de la base (fonction SM_Base_Alloc).
|
||
|
||
Les ressources <20> allouer (structure MHR + ressources du heap syst<73>me) sont r<>f<EFBFBD>renc<6E>es
|
||
par des pointeurs et doivent par cons<6E>quent <20>tre contenues dans un segment attach<63> <20>
|
||
une adresse commune <20> tous les processus.
|
||
On cr<63>e donc ce segment de m<>moire partag<61> sp<73>cifique dont l'adresse d'attachement
|
||
sera m<>moris<69>e dans la structure SMT_Base.
|
||
|
||
Pour ce segment de m<>moire partag<61>, on r<>serve de la place pour :
|
||
- la structure du MHR (NDT_Root)
|
||
- les ressources du heap syst<73>me, i.e :
|
||
- son noeud (NDT_Node)
|
||
- sa structure d'ent<6E>te ( SMT_MHH)
|
||
- sa structure DSR (NDT_Root)
|
||
- sa structure ACR (NDT_Root)
|
||
- sa structure FCR (NDT_Root)
|
||
- son premier segment de donn<6E>es (noeud + ent<6E>te)
|
||
*/
|
||
|
||
Size = sizeof (NDT_Root) + sizeof (NDT_Node) + sizeof (SMT_MHH) + 3 * sizeof (NDT_Root) + sizeof (NDT_Node) + sizeof (SMT_DSH);
|
||
|
||
DataMemId = shmget( IPC_PRIVATE, Size, ( 0777 | IPC_CREAT | IPC_EXCL));
|
||
if( DataMemId == -1)
|
||
{
|
||
switch( errno)
|
||
{
|
||
case EINVAL:
|
||
LG_LOG_ERROR_1( "The size of the shared memory segment: (%d) is out of the system-imposed bounds", Size);
|
||
break;
|
||
|
||
case ENOMEM:
|
||
LG_LOG_ERROR_0( "The amount of memory is not sufficient to create the shared memory segment");
|
||
break;
|
||
|
||
case ENOSPC:
|
||
LG_LOG_ERROR_0( "The number of shared memory segments exceeds the system-imposed limit");
|
||
break;
|
||
|
||
default :
|
||
LG_LOG_ERROR_1( "Unknown error: (%d) while creating a shared memory segment", errno);
|
||
break;
|
||
}
|
||
|
||
rc = SMS_ERRSHM;
|
||
goto Error3;
|
||
}
|
||
|
||
/* Initialisation des informations rattach<63>es <20> la base */
|
||
|
||
SM_Base->SemId = SemId;
|
||
SM_Base->SysMemId = SysMemId;
|
||
SM_Base->DataMemId = DataMemId;
|
||
SM_Base->Size = Size;
|
||
SM_Base->Creator = getpid ();
|
||
SM_Base->Writer = SM_Base->Creator;
|
||
SM_Base->Attach = (void *)MEM_LIMIT;
|
||
SM_Base->MHR = NULL;
|
||
|
||
/*
|
||
On attache le segment de m<>moire partag<61>e au processus courant
|
||
<20> une adresse la plus haute possible (MEM_LIMIT) afin d'<27>viter
|
||
de d<>border sur la plage d'adressage des symboles.
|
||
*/
|
||
|
||
errno = 0;
|
||
|
||
#ifndef __hpux
|
||
SM_Base->Free = shmat( DataMemId, (void *)( (size_t)(SM_Base->Attach) - Size), SHM_RND);
|
||
#else
|
||
SM_Base->Free = shmat( DataMemId, 0, 0);
|
||
#endif
|
||
|
||
if( errno)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to attach the second shared memory segment to the current process: (%d)", errno);
|
||
|
||
rc = SMS_ERRSHM;
|
||
goto Error4;
|
||
}
|
||
|
||
SM_Base->Attach = SM_Base->Free;
|
||
|
||
/* Cr<43>ation du MHR dans la base */
|
||
|
||
rc = ND_DataStruct_Open( &( SM_Base->MHR), 1, &index_type, "MHR_Manager", NULL, "SM_Base_Alloc", NULL, "SM_Base_Free", NULL, TRUE, NULL);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to create the MHR structure");
|
||
|
||
goto Error4;
|
||
}
|
||
|
||
|
||
/*
|
||
Cr<43>ation d'un premier heap qui constituera le heap syst<73>me
|
||
(l'allocation du MHN, du MHH et des structures DSR, ACR et FCR
|
||
sont effectu<74>es dans la base)
|
||
*/
|
||
|
||
rc = SM_Heap_Open_I( HEAP_SYSTEM, &System_Heap, 0, SMD_CREATE, &Locked);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to create the system heap");
|
||
|
||
goto Error5;
|
||
}
|
||
|
||
/*
|
||
On change les fonctions d'allocation et de d<>sallocation du MHR afin que d<>sormais,
|
||
les allocations des nouveaux heaps soient faites dans le heap syst<73>me.
|
||
*/
|
||
|
||
strcpy( SM_Base->MHR->Allocator_Name, "SM_System_Alloc");
|
||
strcpy( SM_Base->MHR->Deallocator_Name, "SM_System_Free");
|
||
|
||
/*
|
||
On change les fonctions Allocator et Deallocator du DSR, ACR
|
||
et FCR du heap syst<73>me afin que d<>sormais, les allocations des
|
||
nouveaux segments et chunks soient faites dans le segment de
|
||
donn<6E>es du heap syst<73>me.
|
||
*/
|
||
|
||
strcpy( System_Heap->MHH->DSR->Allocator_Name, "SM_System_Alloc");
|
||
strcpy( System_Heap->MHH->DSR->Deallocator_Name, "SM_System_Free");
|
||
strcpy( System_Heap->MHH->ACR->Allocator_Name, "SM_System_Alloc");
|
||
strcpy( System_Heap->MHH->ACR->Deallocator_Name, "SM_System_Free");
|
||
strcpy( System_Heap->MHH->FCR->Allocator_Name, "SM_System_Alloc");
|
||
strcpy( System_Heap->MHH->FCR->Deallocator_Name, "SM_System_Free");
|
||
|
||
/* Verrouillage de la base en lecture */
|
||
|
||
rc = SM_Base_Lock( SMD_READ);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to lock the shared memory base for reading");
|
||
|
||
goto Error5;
|
||
}
|
||
|
||
return SMS_OK;
|
||
|
||
/* Gestion d'erreur */
|
||
|
||
Error5:
|
||
ND_DataStruct_Close( SM_Base->MHR);
|
||
|
||
Error4:
|
||
shmdt ( (void *)(SM_Base->Free));
|
||
|
||
Error3:
|
||
shmctl (DataMemId, IPC_RMID, 0);
|
||
|
||
Error2:
|
||
shmdt ( (void *)SM_Base);
|
||
shmctl (SysMemId, IPC_RMID, 0);
|
||
SM_Base = NULL;
|
||
|
||
Error1:
|
||
semctl( SemId, 0, IPC_RMID, Sem_Ctl);
|
||
|
||
return rc;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Destruction de la base */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Base_End ( void )
|
||
{
|
||
int SemId;
|
||
int SysMemId, DataMemId;
|
||
SMT_Status rc;
|
||
union semun Sem_Ctl;
|
||
NDT_Node * Node, * Previous_Node;
|
||
|
||
/* Retrait du verrou en lecture sur la base */
|
||
|
||
rc = SM_Base_Unlock( SMD_READ);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to unlock the shared memory base");
|
||
|
||
return rc;
|
||
}
|
||
|
||
/* Verrouillage de la base en <20>criture */
|
||
|
||
rc = SM_Base_Lock( SMD_WRITE);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to lock the shared memory base for writing");
|
||
|
||
SM_Base_Lock( SMD_READ);
|
||
|
||
return rc;
|
||
}
|
||
|
||
/*
|
||
Destruction de tous les heaps (parcours du MHR en
|
||
sens inverse pour d<>truire le heap syst<73>me en dernier).
|
||
|
||
NB : <20> chaque destruction de heap, la base est verrouill<6C>e en <20>criture
|
||
*/
|
||
|
||
ND_Index_Node_Last_Get( &Node, SM_Base->MHR, NDD_INDEX_PRIMARY);
|
||
|
||
while( Node)
|
||
{
|
||
SMT_MHH * MHH = (SMT_MHH *)(Node->Value);
|
||
|
||
ND_Index_Node_Previous_Get( &Previous_Node, Node);
|
||
|
||
/*
|
||
Pour la suppression du heap syst<73>me, il faut red<65>finir la fonction de
|
||
d<>sallocation du MHR, car il a <20>t<EFBFBD> allou<6F> dans la base (voir SM_Base_Init)
|
||
*/
|
||
|
||
if( !Previous_Node)
|
||
{
|
||
strcpy( SM_Base->MHR->Deallocator_Name, "SM_Base_Free");
|
||
}
|
||
|
||
/* Retrait du heap de la structure du MHR */
|
||
|
||
rc = ND_DataStruct_Value_Remove( SM_Base->MHR, MHH);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to remove heap: [%s] from the MHR", MHH->Name);
|
||
|
||
SM_Base_Unlock( SMD_WRITE);
|
||
SM_Base_Lock( SMD_READ);
|
||
|
||
return rc;
|
||
}
|
||
|
||
/* Suppression du heap */
|
||
|
||
rc = ND_Value_Free( SM_Base->MHR, MHH);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to free heap: [%s]", MHH->Name);
|
||
|
||
SM_Base_Unlock( SMD_WRITE);
|
||
SM_Base_Lock( SMD_READ);
|
||
|
||
return rc;
|
||
}
|
||
|
||
Node = Previous_Node;
|
||
}
|
||
|
||
SemId = SM_Base->SemId;
|
||
SysMemId = SM_Base->SysMemId;
|
||
DataMemId = SM_Base->DataMemId;
|
||
|
||
/* Destruction des segments de m<>moire partag<61>e de la base */
|
||
|
||
if( shmctl( DataMemId, IPC_RMID, 0) == -1 || shmctl( SysMemId, IPC_RMID, 0) == -1)
|
||
{
|
||
switch( errno)
|
||
{
|
||
case EPERM:
|
||
{
|
||
LG_LOG_ERROR_3( "Current process: (%d) is not allowed to destroy the shared memory segment: (%d) or (%d)", (int)getpid(), SysMemId, DataMemId);
|
||
|
||
break;
|
||
}
|
||
|
||
case EINVAL:
|
||
{
|
||
LG_LOG_ERROR_2( "No shared memory segment exists for identifier: (%d) or (%d)", SysMemId, DataMemId);
|
||
|
||
break;
|
||
}
|
||
|
||
default :
|
||
{
|
||
LG_LOG_ERROR_3( "Unknown error: (%d) while destroying the shared memory segment: (%d) or (%d)", errno, SysMemId, DataMemId);
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
SM_Base = NULL;
|
||
|
||
return SMS_ERRSHM;
|
||
}
|
||
|
||
SM_Base = NULL;
|
||
|
||
|
||
/* Destruction du s<>maphore de gestion des verrous sur la base */
|
||
|
||
if( semctl( SemId, 0, IPC_RMID, Sem_Ctl) == -1)
|
||
{
|
||
switch( errno)
|
||
{
|
||
case EPERM:
|
||
{
|
||
LG_LOG_ERROR_2( "Current process: (%d) is not allowed to destroy semaphore: (%d)", (int)getpid (), SemId);
|
||
|
||
break;
|
||
}
|
||
|
||
case EINVAL:
|
||
{
|
||
LG_LOG_ERROR_1( "No semaphore corresponds to the identifier: (%d)", SemId);
|
||
|
||
break;
|
||
}
|
||
|
||
default:
|
||
{
|
||
LG_LOG_ERROR_2( "Unknown error: (%d) while destroying semaphore: (%d)", errno, SemId);
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
return SMS_ERRSEM;
|
||
}
|
||
|
||
return SMS_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Ouverture de la base */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Base_Open ( void )
|
||
{
|
||
SMT_Status rc;
|
||
void * Ptr;
|
||
int MemId;
|
||
int Locked;
|
||
|
||
|
||
if( SM_Base) return SMS_OK;
|
||
|
||
/* R<>cup<75>ration de l'identifiant du segment de m<>moire partag<61>e de la base */
|
||
|
||
MemId = shmget( SM_Instance, 0, 0);
|
||
if( MemId == -1)
|
||
{
|
||
switch( errno)
|
||
{
|
||
case EACCES:
|
||
{
|
||
LG_LOG_ERROR_1( "The shared memory segment: (%d) is not accessible to the current process", SM_Instance);
|
||
|
||
break;
|
||
}
|
||
|
||
case EIDRM:
|
||
{
|
||
LG_LOG_ERROR_1( "The shared memory segment: (%d) has been deleted", SM_Instance);
|
||
|
||
break;
|
||
}
|
||
|
||
case ENOENT:
|
||
{
|
||
LG_LOG_ERROR_1( "No shared memory segment corresponds to the identifier: (%d)", SM_Instance);
|
||
|
||
break;
|
||
}
|
||
|
||
default:
|
||
{
|
||
LG_LOG_ERROR_1( "Unknown error: (%d) while retrieving a shared memory segment", errno);
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
return SMS_ERRSHM;
|
||
}
|
||
|
||
|
||
/* On attache les segments de m<>moire partag<61>e de la base */
|
||
|
||
errno = 0;
|
||
SM_Base = shmat( MemId, 0, 0);
|
||
|
||
if( errno)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to attach the shared memory segment to the current process, error: (%d)", errno);
|
||
|
||
SM_Base = NULL;
|
||
|
||
return SMS_ERRSHM;
|
||
}
|
||
|
||
errno = 0;
|
||
Ptr = shmat (SM_Base->DataMemId, SM_Base->MHR, 0);
|
||
if( errno)
|
||
{
|
||
LG_LOG_ERROR_2( "Unable to attach the shared memory segment to the current process at the specified address: (%p) error: (%d)", SM_Base->MHR, errno);
|
||
|
||
shmdt( (void *)SM_Base);
|
||
SM_Base = NULL;
|
||
|
||
return SMS_ERRSHM;
|
||
}
|
||
|
||
|
||
/* Verrouillage de la base en lecture */
|
||
|
||
rc = SM_Base_Lock( SMD_READ);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to lock the shared memory base for reading");
|
||
|
||
shmdt( (void *)SM_Base);
|
||
SM_Base = NULL;
|
||
|
||
return rc;
|
||
}
|
||
|
||
|
||
/* Ouverture du heap syst<73>me (sans le verrouiller) */
|
||
|
||
rc = SM_Heap_Open_I( HEAP_SYSTEM, &System_Heap, 0, SMD_OPEN, &Locked);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to open the system heap");
|
||
|
||
shmdt ( (void *)SM_Base);
|
||
SM_Base = NULL;
|
||
|
||
return rc;
|
||
}
|
||
|
||
return SMS_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Fermeture de la base */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Base_Close( void )
|
||
{
|
||
NDT_Node * Node;
|
||
|
||
|
||
SM_LIBSHMEM_OPEN_CHECK();
|
||
|
||
/*
|
||
Fermeture de tous les heaps (sans d<>verrouillage) ouverts.
|
||
|
||
Attention : il faut fermer le heap syst<73>me en dernier.
|
||
*/
|
||
|
||
ND_Index_Node_First_Get( &Node, Opened_Heap_List, NDD_INDEX_PRIMARY);
|
||
|
||
while( Node)
|
||
{
|
||
NDT_Node *Next_Node;
|
||
ND_Index_Node_Next_Get( &Next_Node, Node);
|
||
SM_Heap_Close_I( (SMT_Heap *)(Node->Value));
|
||
Node = Next_Node;
|
||
}
|
||
|
||
|
||
/* D<>verrouillage de la base en lecture */
|
||
|
||
SM_Base_Unlock( SMD_READ);
|
||
|
||
|
||
/* D<>tachement des segments de m<>moire partag<61>e de la base */
|
||
|
||
shmdt ( (void *)SM_Base->MHR);
|
||
shmdt ( (void *)SM_Base);
|
||
|
||
SM_Base = NULL;
|
||
|
||
return SMS_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Pose d'un verrou sur la base */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Base_Lock( SMT_Flags Lock_Mode )
|
||
{
|
||
SMT_Status rc;
|
||
|
||
if( Lock_Mode & SMD_READ)
|
||
{
|
||
rc = SM_Semaphore_Operate( SM_Base->SemId, SM_SemOp_SSL, 2);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to lock the library base for reading");
|
||
|
||
return rc;
|
||
}
|
||
}
|
||
|
||
if( Lock_Mode & SMD_WRITE)
|
||
{
|
||
rc = SM_Semaphore_Operate( SM_Base->SemId, SM_SemOp_SEL, 2);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to lock the library base for writing");
|
||
|
||
return rc;
|
||
}
|
||
}
|
||
|
||
return SMS_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Lib<69>ration d'un verrou sur la base */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Base_Unlock( SMT_Flags Lock_Mode )
|
||
{
|
||
SMT_Status rc;
|
||
|
||
if( Lock_Mode & SMD_READ)
|
||
{
|
||
rc = SM_Semaphore_Operate( SM_Base->SemId, SM_SemOp_RSL, 2);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to unlock the library base which had been locked for reading");
|
||
|
||
return rc;
|
||
}
|
||
}
|
||
|
||
if( Lock_Mode & SMD_WRITE)
|
||
{
|
||
rc = SM_Semaphore_Operate( SM_Base->SemId, SM_SemOp_REL, 2);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to unlock the library base which had been locked for writing");
|
||
|
||
return rc;
|
||
}
|
||
}
|
||
|
||
return SMS_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Fonction manager de la liste des heaps ouverts */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
NDT_Status SM_Opened_Heap_List_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, va_list *Args_Ptr)
|
||
{
|
||
NDT_Command_Name Command_Name;
|
||
|
||
|
||
switch( Command)
|
||
{
|
||
case NDD_CMD_MANAGER_VERSION:
|
||
{
|
||
ND_VA_ARG_GET( Version_Name_Ptr, *Args_Ptr, NDT_Version_Name *);
|
||
|
||
|
||
Command_Name = "NDD_CMD_MANAGER_VERSION";
|
||
|
||
*Version_Name_Ptr = "$Revision: 2.4 $ $Name: $ $Date: 2005/06/26 23:40:14 $ $Author: agibert $";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_INDEX_GET:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *);
|
||
ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *);
|
||
ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command);
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *);
|
||
ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *);
|
||
ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command);
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
|
||
Command_Name = "NDD_CMD_INDEX_GET";
|
||
|
||
switch( Cmd)
|
||
{
|
||
/*
|
||
case NDT_CMD_SOME_USER_CMD:
|
||
{
|
||
*Reply_Index_Id_Ptr = 0;
|
||
*Reply_Command_Ptr = NDD_CMD_SOME_OTHER_CMD;
|
||
break;
|
||
}
|
||
|
||
...
|
||
*/
|
||
|
||
default:
|
||
{
|
||
*Reply_Index_Id_Ptr = Index_Id;
|
||
*Reply_Command_Ptr = Cmd;
|
||
break;
|
||
}
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_ALLOC:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr_Ptr, *Args_Ptr, void **);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_ALLOC";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_FREE:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Heap_Ptr, *Args_Ptr, SMT_Heap *);
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_FREE";
|
||
|
||
free( Heap_Ptr->Name);
|
||
free( Heap_Ptr);
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_COMP:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value1_Ptr, *Args_Ptr, void *);
|
||
ND_VA_ARG_GET( Value2_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Heap1_Ptr, *Args_Ptr, SMT_Heap *);
|
||
ND_VA_ARG_GET( Heap2_Ptr, *Args_Ptr, SMT_Heap *);
|
||
|
||
long comp;
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_COMP";
|
||
|
||
comp = strcmp( Heap1_Ptr->Name, Heap2_Ptr->Name);
|
||
|
||
if( comp < 0) return( NDS_LOWER);
|
||
|
||
if( comp > 0) return( NDS_GREATER);
|
||
|
||
return( NDS_EQUAL);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_ADD:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_ADD";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_REMOVE:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_REMOVE";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_PRINT:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
ND_VA_LIST_OPEN( user_args, lib_args);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
ND_VA_LIST_CLOSE( lib_args);
|
||
|
||
void *Value_Ptr = Node_Ptr->Value;
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
ND_VA_LIST_CLOSE( lib_args);
|
||
|
||
SMT_Heap *Heap_Ptr = ( SMT_Heap *)( Node_Ptr->Value);
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_PRINT";
|
||
/*
|
||
fprintf( Out, "Heap_Name: [%s]/[%s] Heap_Addr: (%p) MHH_Ptr: (%p) Lock_Mode: (%d) Seg_Nb: (%d)\n",
|
||
SM_Context, Heap_Ptr->Name, Heap_Ptr, Heap_Ptr->MHH, Heap_Ptr->Lock_Mode, Heap_Ptr->Nb_Seg);
|
||
*/
|
||
|
||
LG_LOG_INFO_6( "Heap_Name: [%s]/[%s] Heap_Addr: (%p) MHH_Ptr: (%p) Lock_Mode: (%d) Seg_Nb: (%d)",
|
||
SM_Context, Heap_Ptr->Name, Heap_Ptr, Heap_Ptr->MHH, Heap_Ptr->Lock_Mode, Heap_Ptr->Nb_Seg);
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_INFO_PRINT:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
ND_VA_LIST_OPEN( user_args, lib_args);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
ND_VA_LIST_CLOSE( lib_args);
|
||
|
||
void *Value_Ptr = Node_Ptr->Value;
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_INFO_PRINT";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
default:
|
||
{
|
||
LG_LOG_ERROR_1( "Manager called with an undefined command: (%d)", Command);
|
||
|
||
return( NDS_ERRAPI);
|
||
}
|
||
}
|
||
|
||
LG_LOG_ERROR_1( "Manager internal error in command: (%d)", Command);
|
||
|
||
return( NDS_ERRAPI);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Fonction manager du MHR (Memory Heap Root) */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
NDT_Status MHR_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, va_list *Args_Ptr)
|
||
{
|
||
NDT_Command_Name Command_Name;
|
||
|
||
|
||
switch( Command)
|
||
{
|
||
case NDD_CMD_MANAGER_VERSION:
|
||
{
|
||
ND_VA_ARG_GET( Version_Name_Ptr, *Args_Ptr, NDT_Version_Name *);
|
||
|
||
|
||
Command_Name = "NDD_CMD_MANAGER_VERSION";
|
||
|
||
*Version_Name_Ptr = "$Revision: 2.4 $ $Name: $ $Date: 2005/06/26 23:40:14 $ $Author: agibert $";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_INDEX_GET:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *);
|
||
ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *);
|
||
ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command);
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *);
|
||
ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *);
|
||
ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command);
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
|
||
Command_Name = "NDD_CMD_INDEX_GET";
|
||
|
||
switch( Cmd)
|
||
{
|
||
/*
|
||
case NDT_CMD_SOME_USER_CMD:
|
||
{
|
||
*Reply_Index_Id_Ptr = 0;
|
||
*Reply_Command_Ptr = NDD_CMD_SOME_OTHER_CMD;
|
||
break;
|
||
}
|
||
|
||
...
|
||
*/
|
||
|
||
default:
|
||
{
|
||
*Reply_Index_Id_Ptr = Index_Id;
|
||
*Reply_Command_Ptr = Cmd;
|
||
break;
|
||
}
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_ALLOC:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr_Ptr, *Args_Ptr, void **);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( MHH_Ptr_Ptr, *Args_Ptr, SMT_MHH **);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Prefixed_Name, user_args, char *);
|
||
ND_VA_ARG_GET( Seg_Size, user_args, size_t);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
|
||
union semun Sem_Ctl;
|
||
int SemId;
|
||
NDT_Status rc;
|
||
NDT_Index_Type index_type = ( NDD_INDEX_STATUS_OPENED | NDD_INDEX_TYPE_LIST | NDD_INDEX_SUBTYPE_FIFO);
|
||
SMT_DSH *DSH_Ptr;
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_ALLOC";
|
||
|
||
/* Cr<43>ation du s<>maphore pour g<>rer les verrous sur le nouveau MHH */
|
||
|
||
SemId = semget( IPC_PRIVATE, 1, 0777 | IPC_CREAT | IPC_EXCL);
|
||
if( SemId == -1)
|
||
{
|
||
switch( errno)
|
||
{
|
||
case ENOMEM:
|
||
{
|
||
LG_LOG_ERROR_0( "The amount of memory is not sufficient to create a new semaphore");
|
||
break;
|
||
}
|
||
|
||
case ENOSPC:
|
||
{
|
||
LG_LOG_ERROR_0( "The number of semaphores exceeds the system-imposed limit");
|
||
break;
|
||
}
|
||
|
||
default:
|
||
{
|
||
LG_LOG_ERROR_1( "Unknown error: (%d) while creating a semaphore", errno);
|
||
break;
|
||
}
|
||
}
|
||
|
||
return( NDS_ERRMEM);
|
||
}
|
||
|
||
|
||
/* Initialisation du s<>maphore <20> 1 (<28>quivaut <20> aucun verrou pos<6F>) */
|
||
|
||
Sem_Ctl.val = 1;
|
||
|
||
if( semctl( SemId, 0, SETVAL, Sem_Ctl))
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to initialize the value of the semaphore: (%d)", SemId);
|
||
|
||
rc = SMS_ERRSEM;
|
||
goto Error3;
|
||
}
|
||
|
||
|
||
/* R<>servation du MHH (dans la base pour le heap syst<73>me, dans le heap syst<73>me pour les autres heaps) */
|
||
|
||
if( ND_Allocator_Exec( (void **)(MHH_Ptr_Ptr), SM_Base->MHR, sizeof( SMT_MHH), SM_Base->MHR->Allocator_Name, SM_Base->MHR->Allocator_Ptr, NULL) != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to allocate memory for the heap header");
|
||
|
||
rc = SMS_ERRSHM;
|
||
goto Error3;
|
||
}
|
||
|
||
/* Initialisation de la structure du nouveau MHH */
|
||
|
||
|
||
strcpy( ( *MHH_Ptr_Ptr)->Name, Prefixed_Name);
|
||
( *MHH_Ptr_Ptr)->Writer = getpid();
|
||
( *MHH_Ptr_Ptr)->SemId = SemId;
|
||
( *MHH_Ptr_Ptr)->State = SMD_STATE_UNVALIDATED;
|
||
( *MHH_Ptr_Ptr)->Segment_Size = ( ( Seg_Size > 0) ? Seg_Size : SEGMENT_DEFAULT_SIZE);
|
||
( *MHH_Ptr_Ptr)->Limit_Size = SMD_UNLIMITED;
|
||
( *MHH_Ptr_Ptr)->Auto_Compress = SMD_DEFAULT_COMPRESS;
|
||
( *MHH_Ptr_Ptr)->Compress_Nb = 0L;
|
||
|
||
/*
|
||
Cr<43>ation de la structure DSR :
|
||
- dans la base pour le heap syst<73>me
|
||
- dans le heap syst<73>me pour les autres heaps
|
||
*/
|
||
|
||
rc = ND_DataStruct_Open( &( ( *MHH_Ptr_Ptr)->DSR), 1, &index_type, "SM_DSR_Manager", NULL, SM_Base->MHR->Allocator_Name, NULL, SM_Base->MHR->Deallocator_Name, NULL, TRUE, NULL);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to create the DSR structure");
|
||
goto Error4;
|
||
}
|
||
|
||
|
||
/*
|
||
Cr<43>ation de la structure ACR :
|
||
- dans la base pour le heap syst<73>me
|
||
- dans le heap syst<73>me pour les autres heaps
|
||
*/
|
||
|
||
rc = ND_DataStruct_Open( &( ( *MHH_Ptr_Ptr)->ACR), 1, &index_type, "SM_ACR_Manager", NULL, SM_Base->MHR->Allocator_Name, NULL, SM_Base->MHR->Deallocator_Name, NULL, TRUE, NULL);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to create the ACR structure");
|
||
goto Error5;
|
||
|
||
}
|
||
|
||
|
||
/*
|
||
Cr<43>ation de la structure FCR :
|
||
- dans la base pour le heap syst<73>me
|
||
- dans le heap syst<73>me pour les autres heaps
|
||
*/
|
||
|
||
rc = ND_DataStruct_Open( &( ( *MHH_Ptr_Ptr)->FCR), 1, &index_type, "SM_FCR_Manager", NULL, SM_Base->MHR->Allocator_Name, NULL, SM_Base->MHR->Deallocator_Name, NULL, TRUE, NULL);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to create the FCR structure");
|
||
goto Error6;
|
||
|
||
}
|
||
|
||
/*alloction du premier segement de donnee pour le heap*/
|
||
rc = ND_Value_Alloc( (void **)&DSH_Ptr, ( *MHH_Ptr_Ptr)->DSR, *MHH_Ptr_Ptr, ( *MHH_Ptr_Ptr)->Segment_Size);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to create the DSH structure");
|
||
rc = SMS_ERRSHM;
|
||
goto Error7;
|
||
}
|
||
|
||
rc = ND_DataStruct_Value_Add( ( *MHH_Ptr_Ptr)->DSR, DSH_Ptr);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to add a data segment to the DSR structure");
|
||
|
||
goto Error8;
|
||
}
|
||
|
||
( *MHH_Ptr_Ptr)->State = SMD_STATE_VALID;
|
||
|
||
return( NDS_OK);
|
||
|
||
|
||
/* Gestion d'erreur sur cr<63>ation */
|
||
|
||
Error9:
|
||
ND_DataStruct_Value_Remove( ( *MHH_Ptr_Ptr)->DSR, DSH_Ptr);
|
||
|
||
Error8:
|
||
ND_Value_Free( ( *MHH_Ptr_Ptr)->DSR, DSH_Ptr);
|
||
|
||
Error7:
|
||
ND_Deallocator_Exec( ( *MHH_Ptr_Ptr)->FCR, SM_Base->MHR, SM_Base->MHR->Deallocator_Name, SM_Base->MHR->Deallocator_Ptr, NULL);
|
||
|
||
Error6:
|
||
ND_Deallocator_Exec( ( *MHH_Ptr_Ptr)->ACR, SM_Base->MHR, SM_Base->MHR->Deallocator_Name, SM_Base->MHR->Deallocator_Ptr, NULL);
|
||
|
||
Error5:
|
||
ND_Deallocator_Exec( ( *MHH_Ptr_Ptr)->DSR, SM_Base->MHR, SM_Base->MHR->Deallocator_Name, SM_Base->MHR->Deallocator_Ptr, NULL);
|
||
|
||
Error4:
|
||
ND_Deallocator_Exec( *MHH_Ptr_Ptr, SM_Base->MHR, SM_Base->MHR->Deallocator_Name, SM_Base->MHR->Deallocator_Ptr, NULL);
|
||
|
||
Error3:
|
||
semctl( SemId, 0, IPC_RMID, Sem_Ctl);
|
||
|
||
return( rc);
|
||
|
||
|
||
}
|
||
|
||
case NDD_CMD_VALUE_FREE:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( MHH_Ptr, *Args_Ptr, SMT_MHH *);
|
||
|
||
SMT_Status rc;
|
||
SMT_Heap To_Find;
|
||
union semun Sem_Ctl;
|
||
SMT_Heap * Opened_Heap;
|
||
|
||
Command_Name = "NDD_CMD_VALUE_FREE";
|
||
|
||
/* Destruction de la structure DSR (et de toutes ses valeurs) */
|
||
|
||
if( !strcmp( MHH_Ptr->Name, HEAP_SYSTEM))
|
||
{
|
||
NDT_Node * Node, * Previous_Node;
|
||
SMT_DSH * DSH;
|
||
|
||
/*
|
||
Pour le heap syst<73>me, on doit proc<6F>der de mani<6E>re sp<73>cifique
|
||
car le premier segment contient des r<>f<EFBFBD>rences sur les autres
|
||
segments. Il faut donc supprimer celui-ci en dernier.
|
||
|
||
Par ailleurs, ce premier segment a <20>t<EFBFBD> allou<6F> dans la base.
|
||
Il faudra donc aussi red<65>finir la fonction de d<>sallocation
|
||
du DSR pour celui-ci.
|
||
*/
|
||
|
||
ND_Index_Node_Last_Get( &Node, MHH_Ptr->DSR, NDD_INDEX_PRIMARY);
|
||
|
||
while( Node)
|
||
{
|
||
DSH = (SMT_DSH *)(Node->Value);
|
||
|
||
ND_Index_Node_Previous_Get( &Previous_Node, Node);
|
||
|
||
/* S'agit-il du heap syst<73>me ? */
|
||
|
||
if( !Previous_Node)
|
||
{
|
||
strcpy( MHH_Ptr->DSR->Deallocator_Name, "SM_Base_Free");
|
||
}
|
||
|
||
/* Retrait du segment du DSR */
|
||
|
||
rc = ND_DataStruct_Value_Remove( MHH_Ptr->DSR, DSH);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to remove the shared memory segment at address: (%p) from the DSR structure", DSH->Start);
|
||
|
||
if( SM_ERROR(rc)) return rc;
|
||
}
|
||
|
||
/* Destruction du segment */
|
||
|
||
rc = ND_Value_Free( MHH_Ptr->DSR, DSH);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to free the shared memory segment at address: (%p)", DSH->Start);
|
||
|
||
if( SM_ERROR(rc)) return rc;
|
||
}
|
||
|
||
Node = Previous_Node;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
rc = ND_DataStruct_Close( MHH_Ptr->DSR);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to destroy the DSR structure of heap: [%s]", MHH_Ptr->Name);
|
||
}
|
||
}
|
||
|
||
/*
|
||
Destruction des structures ACR et FCR.
|
||
|
||
NB : puisque tous les chunks r<>f<EFBFBD>nrenc<6E>s par les ACR et FCR <20>taient allou<6F>s
|
||
dans les segments qui viennent d'<27>tre supprim<69>s, on se contente de d<>tuire
|
||
leur racine.
|
||
*/
|
||
|
||
rc = ND_Deallocator_Exec( MHH_Ptr->ACR, SM_Base->MHR, SM_Base->MHR->Deallocator_Name, SM_Base->MHR->Deallocator_Ptr, NULL);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to free the ACR root of heap: [%s]", MHH_Ptr->Name);
|
||
}
|
||
|
||
rc = ND_Deallocator_Exec( MHH_Ptr->FCR, SM_Base->MHR, SM_Base->MHR->Deallocator_Name, SM_Base->MHR->Deallocator_Ptr, NULL);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to free the FCR root of heap: [%s]", MHH_Ptr->Name);
|
||
}
|
||
|
||
/* Suppression du heap de la liste des heaps ouverts */
|
||
|
||
To_Find.Name = MHH_Ptr->Name;
|
||
rc = ND_DataStruct_Value_Find( (void **)&Opened_Heap, Opened_Heap_List, &To_Find);
|
||
|
||
if( ( rc == NDS_OK) && ( Opened_Heap != NULL))
|
||
{
|
||
rc = ND_DataStruct_Value_Remove( Opened_Heap_List, Opened_Heap);
|
||
|
||
if( rc != NDS_OK)
|
||
{
|
||
return( rc);
|
||
}
|
||
else
|
||
{
|
||
rc = ND_Value_Free( Opened_Heap_List, Opened_Heap);
|
||
|
||
if( rc != NDS_OK)
|
||
{
|
||
return( rc);
|
||
}
|
||
}
|
||
}
|
||
|
||
/* Destruction du s<>maphore attach<63> au heap */
|
||
|
||
semctl( MHH_Ptr->SemId, 0, IPC_RMID, Sem_Ctl);
|
||
|
||
/* D<>sallocation de la structure du MHH */
|
||
|
||
rc = ND_Deallocator_Exec( MHH_Ptr, SM_Base->MHR, SM_Base->MHR->Deallocator_Name, SM_Base->MHR->Deallocator_Ptr, NULL);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to free the header of heap: [%s]", MHH_Ptr->Name);
|
||
}
|
||
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_COMP:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value1_Ptr, *Args_Ptr, void *);
|
||
ND_VA_ARG_GET( Value2_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( MHH1_Ptr, *Args_Ptr, SMT_MHH *);
|
||
ND_VA_ARG_GET( MHH2_Ptr, *Args_Ptr, SMT_MHH *);
|
||
|
||
long comp;
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_COMP";
|
||
|
||
comp = strcmp( MHH1_Ptr->Name, MHH2_Ptr->Name);
|
||
|
||
if( comp < 0) return( NDS_LOWER);
|
||
|
||
if( comp > 0) return( NDS_GREATER);
|
||
|
||
return( NDS_EQUAL);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_ADD:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_ADD";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_REMOVE:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_REMOVE";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_PRINT:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
ND_VA_LIST_OPEN( user_args, lib_args);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
ND_VA_LIST_CLOSE( lib_args);
|
||
|
||
void *Value_Ptr = Node_Ptr->Value;
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
ND_VA_LIST_CLOSE( lib_args);
|
||
|
||
SMT_MHH *MHH_Ptr = (SMT_MHH *)( Node_Ptr->Value);
|
||
|
||
SMT_Status status;
|
||
size_t segment_size=0, alloc_size=0, free_size=0;
|
||
int segment_nb, alloc_chunk_nb, free_chunk_nb;
|
||
SMT_Heap *heap_ptr;
|
||
char *heap_name;
|
||
int locked;
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_PRINT";
|
||
|
||
/* On n'affiche le heap que s'il fait partie du contexte courant */
|
||
|
||
if( ( heap_name = strstr( MHH_Ptr->Name, SM_Context)) != 0)
|
||
{
|
||
heap_name += strlen( SM_Context) + 1;
|
||
}
|
||
else
|
||
{
|
||
if( strcmp( HEAP_SYSTEM, MHH_Ptr->Name) == 0)
|
||
{
|
||
heap_name = MHH_Ptr->Name;
|
||
}
|
||
else
|
||
{
|
||
return( NDS_OK);
|
||
}
|
||
}
|
||
|
||
if( MHH_Ptr->State == SMD_STATE_CORRUPTED)
|
||
{
|
||
/*
|
||
fprintf( Out, "Heap_Name: [%s]/[%s] Heap_Addr: (%lx) *** CORRUPTED *** Checker_PId: (%ld)\n",
|
||
SM_Context, MHH_Ptr->Name, MHH_Ptr, MHH_Ptr->Writer);
|
||
*/
|
||
LG_LOG_INFO_4( "Heap_Name: [%s]/[%s] Heap_Addr: (%lx) *** CORRUPTED *** Checker_PId: (%ld)",
|
||
SM_Context, MHH_Ptr->Name, MHH_Ptr, MHH_Ptr->Writer);
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
if( status = ( SM_Heap_Open_I( heap_name, &heap_ptr, 0, ( SMD_OPEN | SMD_READ), &locked)) != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to open Heap_Name: [%s] for reading", MHH_Ptr->Name);
|
||
|
||
return( status);
|
||
}
|
||
/* TEST !!! */
|
||
|
||
if( locked != TRUE)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to lock Heap_Name: [%s] for reading", MHH_Ptr->Name);
|
||
|
||
// return( SMS_KO);
|
||
}
|
||
|
||
segment_nb = MHH_Ptr->DSR->Index_Tab[NDD_INDEX_PRIMARY].Node_Number;
|
||
ND_DataStruct_Traverse( MHH_Ptr->DSR, NDD_CMD_VALUE_SUM, (void *)&segment_size);
|
||
|
||
alloc_chunk_nb = MHH_Ptr->ACR->Index_Tab[NDD_INDEX_PRIMARY].Node_Number;
|
||
ND_DataStruct_Traverse( MHH_Ptr->ACR, NDD_CMD_VALUE_SUM, (void *)&alloc_size);
|
||
|
||
free_chunk_nb = MHH_Ptr->FCR->Index_Tab[NDD_INDEX_PRIMARY].Node_Number;
|
||
ND_DataStruct_Traverse( MHH_Ptr->FCR, NDD_CMD_VALUE_SUM, (void *)&free_size);
|
||
/*
|
||
fprintf( Out, "Heap_Name: [%s]/[%s] Heap_Addr: (%p) Sem_Id: (%d) Lock_Status: [%s]\nWriter_PId: (%ld) Seg_Nb: (%d) Heap_Size: (%lu) Size_Limit: (%ld) Auto_Compress: (%d) Compress_Nb: (%ld)\nAlloc_Chunk_Nb: (%d) Alloc_Size: (%lu) Free_Chunk_Nb: (%d) Free_Size: (%lu)\n\n",
|
||
SM_Context, heap_name, MHH_Ptr, MHH_Ptr->SemId, SM_Lock_Status_Get( "heap", MHH_Ptr),
|
||
MHH_Ptr->Writer, segment_nb, segment_size, MHH_Ptr->Limit_Size, MHH_Ptr->Auto_Compress, MHH_Ptr->Compress_Nb,
|
||
alloc_chunk_nb, alloc_size, free_chunk_nb, free_size);
|
||
*/
|
||
|
||
LG_LOG_INFO_5( "Heap_Name: [%s]/[%s] Heap_Addr: (%p) Sem_Id: (%d) Lock_Status: [%s]",
|
||
SM_Context, heap_name, MHH_Ptr, MHH_Ptr->SemId, SM_Lock_Status_Get( "heap", MHH_Ptr));
|
||
LG_LOG_INFO_6( "Writer_PId: (%ld) Seg_Nb: (%d) Heap_Size: (%lu) Size_Limit: (%ld) Auto_Compress: (%d) Compress_Nb: (%ld)",
|
||
MHH_Ptr->Writer, segment_nb, segment_size, MHH_Ptr->Limit_Size, MHH_Ptr->Auto_Compress, MHH_Ptr->Compress_Nb);
|
||
LG_LOG_INFO_4( "Alloc_Chunk_Nb: (%d) Alloc_Size: (%lu) Free_Chunk_Nb: (%d) Free_Size: (%lu)",
|
||
alloc_chunk_nb, alloc_size, free_chunk_nb, free_size);
|
||
LG_LOG_INFO_0( "");
|
||
|
||
if( locked == TRUE)
|
||
{
|
||
SM_Heap_Unlock_I( heap_ptr);
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_INFO_PRINT:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
ND_VA_LIST_OPEN( user_args, lib_args);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
ND_VA_LIST_CLOSE( lib_args);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
ND_VA_LIST_CLOSE( lib_args);
|
||
|
||
|
||
Command_Name = "NDD_CMD_INFO_PRINT";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
default:
|
||
{
|
||
LG_LOG_ERROR_1( "Manager called with an undefined command: (%d)", Command);
|
||
return( NDS_ERRAPI);
|
||
}
|
||
}
|
||
|
||
LG_LOG_ERROR_1( "Manager internal error in command: (%d)", Command);
|
||
|
||
return( NDS_ERRAPI);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Destruction d'un MHH (Memory Heap Header) */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_MHH_End( SMT_MHH *MHH)
|
||
{
|
||
SMT_Status rc;
|
||
SMT_Heap To_Find;
|
||
union semun Sem_Ctl;
|
||
SMT_Heap * Opened_Heap;
|
||
|
||
|
||
/* Destruction de la structure DSR (et de toutes ses valeurs) */
|
||
|
||
if( !strcmp( MHH->Name, HEAP_SYSTEM))
|
||
{
|
||
NDT_Node * Node, * Previous_Node;
|
||
SMT_DSH * DSH;
|
||
|
||
/*
|
||
Pour le heap syst<73>me, on doit proc<6F>der de mani<6E>re sp<73>cifique
|
||
car le premier segment contient des r<>f<EFBFBD>rences sur les autres
|
||
segments. Il faut donc supprimer celui-ci en dernier.
|
||
|
||
Par ailleurs, ce premier segment a <20>t<EFBFBD> allou<6F> dans la base.
|
||
Il faudra donc aussi red<65>finir la fonction de d<>sallocation
|
||
du DSR pour celui-ci.
|
||
*/
|
||
|
||
ND_Index_Node_Last_Get( &Node, MHH->DSR, NDD_INDEX_PRIMARY);
|
||
|
||
while( Node)
|
||
{
|
||
DSH = (SMT_DSH *)(Node->Value);
|
||
|
||
ND_Index_Node_Previous_Get( &Previous_Node, Node);
|
||
|
||
/* S'agit-il du heap syst<73>me ? */
|
||
|
||
if( !Previous_Node)
|
||
{
|
||
strcpy( MHH->DSR->Deallocator_Name, "SM_Base_Free");
|
||
}
|
||
|
||
/* Retrait du segment du DSR */
|
||
|
||
rc = ND_DataStruct_Value_Remove( MHH->DSR, DSH);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to remove the shared memory segment at address: (%p) from the DSR structure", DSH->Start);
|
||
|
||
if( SM_ERROR(rc)) return rc;
|
||
}
|
||
|
||
/* Destruction du segment */
|
||
|
||
rc = ND_Value_Free( MHH->DSR, DSH);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to free the shared memory segment at address: (%p)", DSH->Start);
|
||
|
||
if( SM_ERROR(rc)) return rc;
|
||
}
|
||
|
||
Node = Previous_Node;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
rc = ND_DataStruct_Close( MHH->DSR);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to destroy the DSR structure of heap: [%s]", MHH->Name);
|
||
}
|
||
}
|
||
|
||
/*
|
||
Destruction des structures ACR et FCR.
|
||
|
||
NB : puisque tous les chunks r<>f<EFBFBD>nrenc<6E>s par les ACR et FCR <20>taient allou<6F>s
|
||
dans les segments qui viennent d'<27>tre supprim<69>s, on se contente de d<>tuire
|
||
leur racine.
|
||
*/
|
||
|
||
rc = ND_Deallocator_Exec( MHH->ACR, SM_Base->MHR, SM_Base->MHR->Deallocator_Name, SM_Base->MHR->Deallocator_Ptr, NULL);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to free the ACR root of heap: [%s]", MHH->Name);
|
||
}
|
||
|
||
rc = ND_Deallocator_Exec( MHH->FCR, SM_Base->MHR, SM_Base->MHR->Deallocator_Name, SM_Base->MHR->Deallocator_Ptr, NULL);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to free the FCR root of heap: [%s]", MHH->Name);
|
||
}
|
||
|
||
/* Suppression du heap de la liste des heaps ouverts */
|
||
|
||
To_Find.Name = MHH->Name;
|
||
rc = ND_DataStruct_Value_Find( (void **)&Opened_Heap, Opened_Heap_List, &To_Find);
|
||
|
||
if( ( rc == NDS_OK) && ( Opened_Heap != NULL))
|
||
{
|
||
rc = ND_DataStruct_Value_Remove( Opened_Heap_List, Opened_Heap);
|
||
|
||
if( rc != NDS_OK)
|
||
{
|
||
return( rc);
|
||
}
|
||
else
|
||
{
|
||
rc = ND_Value_Free( Opened_Heap_List, Opened_Heap);
|
||
|
||
if( rc != NDS_OK)
|
||
{
|
||
return( rc);
|
||
}
|
||
}
|
||
}
|
||
|
||
/* Destruction du s<>maphore attach<63> au heap */
|
||
|
||
semctl( MHH->SemId, 0, IPC_RMID, Sem_Ctl);
|
||
|
||
/* D<>sallocation de la structure du MHH */
|
||
|
||
rc = ND_Deallocator_Exec( MHH, SM_Base->MHR, SM_Base->MHR->Deallocator_Name, SM_Base->MHR->Deallocator_Ptr, NULL);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to free the header of heap: [%s]", MHH->Name);
|
||
}
|
||
|
||
return rc;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Gestion des segments de donn<6E>es */
|
||
/*------------------------------------------------------------------------------*/
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Fonction manager pour un DSR (Data Segment Root) */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
NDT_Status SM_DSR_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, va_list *Args_Ptr)
|
||
{
|
||
NDT_Command_Name Command_Name;
|
||
NDT_Node * Chunk_Node;
|
||
SMT_Chunk * Chunk;
|
||
|
||
|
||
switch( Command)
|
||
{
|
||
case NDD_CMD_MANAGER_VERSION:
|
||
{
|
||
ND_VA_ARG_GET( Version_Name_Ptr, *Args_Ptr, NDT_Version_Name *);
|
||
|
||
|
||
Command_Name = "NDD_CMD_MANAGER_VERSION";
|
||
|
||
*Version_Name_Ptr = "$Revision: 2.4 $ $Name: $ $Date: 2005/06/26 23:40:14 $ $Author: agibert $";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_INDEX_GET:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *);
|
||
ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *);
|
||
ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command);
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *);
|
||
ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *);
|
||
ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command);
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
|
||
Command_Name = "NDD_CMD_INDEX_GET";
|
||
|
||
switch( Cmd)
|
||
{
|
||
/*
|
||
case NDT_CMD_SOME_USER_CMD:
|
||
{
|
||
*Reply_Index_Id_Ptr = 0;
|
||
*Reply_Command_Ptr = NDD_CMD_SOME_OTHER_CMD;
|
||
break;
|
||
}
|
||
|
||
...
|
||
*/
|
||
|
||
default:
|
||
{
|
||
*Reply_Index_Id_Ptr = Index_Id;
|
||
*Reply_Command_Ptr = Cmd;
|
||
break;
|
||
}
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_ALLOC:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr_Ptr, *Args_Ptr, void **);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( DSH_Ptr_Ptr, *Args_Ptr, SMT_DSH **);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( MHH_Ptr, user_args, SMT_MHH *);
|
||
ND_VA_ARG_GET( Segment_Size, user_args, size_t);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_ALLOC";
|
||
|
||
/* On v<>rifie que le heap n'atteint pas sa limite */
|
||
if( MHH_Ptr->Limit_Size != SMD_UNLIMITED)
|
||
{
|
||
size_t Current_Size;
|
||
|
||
ND_DataStruct_Traverse( MHH_Ptr->DSR, NDD_CMD_VALUE_SUM, (void *)&Current_Size);
|
||
|
||
if( Current_Size + Segment_Size > MHH_Ptr->Limit_Size)
|
||
{
|
||
LG_LOG_ERROR_0( "The heap limit size would be exceeded");
|
||
|
||
*DSH_Ptr_Ptr = NULL;
|
||
|
||
return( NDS_KO);
|
||
}
|
||
}
|
||
|
||
/* Cr<43>ation de l'ent<6E>te */
|
||
|
||
if( ND_Allocator_Exec( (void **)DSH_Ptr_Ptr, MHH_Ptr->DSR, sizeof (SMT_DSH), MHH_Ptr->DSR->Allocator_Name, MHH_Ptr->DSR->Allocator_Ptr, NULL) != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "Unable to allocate memory for the new data segment header");
|
||
|
||
return( NDS_KO);
|
||
}
|
||
|
||
|
||
/* Cr<43>ation d'un segment de m<>moire partag<61>e */
|
||
if( ( ( *DSH_Ptr_Ptr)->MemId = shmget (IPC_PRIVATE, Segment_Size, 0777|IPC_CREAT|IPC_EXCL)) == -1)
|
||
{
|
||
switch( errno)
|
||
{
|
||
case EINVAL:
|
||
{
|
||
LG_LOG_ERROR_1( "The size of the shared memory segment: (%d) is out of the system-imposed bounds", Segment_Size);
|
||
break;
|
||
}
|
||
|
||
case ENOMEM:
|
||
{
|
||
LG_LOG_ERROR_0( "The amount of memory is not sufficient to create the shared memory segment");
|
||
break;
|
||
}
|
||
|
||
case ENOSPC:
|
||
{
|
||
LG_LOG_ERROR_0( "The number of shared memory segments exceeds the system-imposed limit");
|
||
break;
|
||
}
|
||
|
||
default:
|
||
{
|
||
LG_LOG_ERROR_1( "Unknown error: (%d) while creating a shared memory segment", errno);
|
||
break;
|
||
}
|
||
}
|
||
|
||
ND_Deallocator_Exec( ( *DSH_Ptr_Ptr), MHH_Ptr->DSR, MHH_Ptr->DSR->Deallocator_Name, MHH_Ptr->DSR->Deallocator_Ptr, NULL);
|
||
|
||
return( NDS_KO);
|
||
}
|
||
|
||
/* On attache le segment de m<>moire partag<61>e au processus courant */
|
||
|
||
errno = 0;
|
||
#ifndef __hpux
|
||
( *DSH_Ptr_Ptr)->Start = shmat( ( *DSH_Ptr_Ptr)->MemId, (void *)( (size_t)(SM_Base->Attach) - Segment_Size), SHM_RND);
|
||
#else
|
||
( *DSH_Ptr_Ptr)->Start = shmat( ( *DSH_Ptr_Ptr)->MemId, 0, 0);
|
||
#endif
|
||
if( errno)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to attach the shared memory segment to the current process, error: (%d)", errno);
|
||
|
||
shmctl( ( *DSH_Ptr_Ptr)->MemId, IPC_RMID, 0);
|
||
|
||
ND_Deallocator_Exec( *DSH_Ptr_Ptr, MHH_Ptr->DSR, MHH_Ptr->DSR->Deallocator_Name, MHH_Ptr->DSR->Deallocator_Ptr, NULL);
|
||
|
||
return( NDS_KO);
|
||
}
|
||
|
||
SM_Base->Attach = ( *DSH_Ptr_Ptr)->Start;
|
||
|
||
|
||
/* Initialisation des informations de l'ent<6E>te */
|
||
|
||
( *DSH_Ptr_Ptr)->Size = Segment_Size;
|
||
|
||
|
||
/* Cr<43>ation d'un chunk libre au d<>but du segment de donn<6E>es */
|
||
|
||
Chunk_Node = (NDT_Node *)( *DSH_Ptr_Ptr)->Start;
|
||
|
||
Chunk = (SMT_Chunk *)( (size_t)Chunk_Node + sizeof (NDT_Node) );
|
||
|
||
Chunk_Node->Value = Chunk;
|
||
|
||
Chunk->Data = (void *)( (size_t)Chunk + sizeof (SMT_Chunk) );
|
||
|
||
Chunk->Size = ( *DSH_Ptr_Ptr)->Size - sizeof (NDT_Node) - sizeof (SMT_Chunk);
|
||
|
||
|
||
/* Ajout du chunk libre <20> la liste des chunks libres du heap */
|
||
|
||
if( ND_Index_Node_Add( MHH_Ptr->FCR, NDD_INDEX_PRIMARY, Chunk_Node) != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to add a first chunk to the FCR structure of heap: [%s]", MHH_Ptr->Name);
|
||
|
||
shmctl ( ( *DSH_Ptr_Ptr)->MemId, IPC_RMID, 0);
|
||
|
||
ND_Deallocator_Exec( ( *DSH_Ptr_Ptr), MHH_Ptr->DSR, MHH_Ptr->DSR->Deallocator_Name, MHH_Ptr->DSR->Deallocator_Ptr, NULL);
|
||
|
||
return( NDS_KO);
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_FREE:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( DSH_Ptr, *Args_Ptr, SMT_DSH *);
|
||
|
||
SMT_Status rc;
|
||
|
||
Command_Name = "NDD_CMD_VALUE_FREE";
|
||
|
||
|
||
/* Destruction du segment de m<>moire partag<61>e du segment de donn<6E>es */
|
||
|
||
if( shmctl (DSH_Ptr->MemId, IPC_RMID, 0) == -1)
|
||
{
|
||
switch( errno)
|
||
{
|
||
case EPERM:
|
||
{
|
||
LG_LOG_ERROR_2( "Current process: (%d) is not allowed to destroy the shared memory segment: (%d)", (int)getpid (), DSH_Ptr->MemId);
|
||
break;
|
||
}
|
||
|
||
case EINVAL:
|
||
{
|
||
LG_LOG_ERROR_1( "No shared memory segment exists for identifier: (%d)", DSH_Ptr->MemId);
|
||
break;
|
||
}
|
||
|
||
default:
|
||
{
|
||
LG_LOG_ERROR_2( "Unknown error: (%d) while destroying the shared memory segment: (%d)", errno, DSH_Ptr->MemId);
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
return SMS_ERRSHM;
|
||
}
|
||
|
||
/* D<>sallocation de l'ent<6E>te */
|
||
|
||
rc = ND_Deallocator_Exec( DSH_Ptr, Root_Ptr, Root_Ptr->Deallocator_Name, Root_Ptr->Deallocator_Ptr, NULL);
|
||
if( rc != NDS_OK)
|
||
{
|
||
LG_LOG_ERROR_0( "The data segment header is nul");
|
||
|
||
return rc;
|
||
}
|
||
|
||
return NDS_OK;
|
||
|
||
}
|
||
|
||
case NDD_CMD_VALUE_COMP:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value1_Ptr, *Args_Ptr, void *);
|
||
ND_VA_ARG_GET( Value2_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( DSH1_Ptr, *Args_Ptr, SMT_DSH *);
|
||
ND_VA_ARG_GET( DSH2_Ptr, *Args_Ptr, SMT_DSH *);
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_COMP";
|
||
|
||
if( DSH1_Ptr->MemId < DSH2_Ptr->MemId) return( NDS_LOWER);
|
||
|
||
if( DSH1_Ptr->MemId > DSH2_Ptr->MemId) return( NDS_GREATER);
|
||
|
||
return( NDS_EQUAL);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_ADD:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_ADD";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_REMOVE:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_REMOVE";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_PRINT:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
ND_VA_LIST_OPEN( user_args, lib_args);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
ND_VA_LIST_CLOSE( lib_args);
|
||
|
||
void *Value_Ptr = Node_Ptr->Value;
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
ND_VA_LIST_CLOSE( lib_args);
|
||
|
||
SMT_DSH *DSH_Ptr = (SMT_DSH *)( Node_Ptr->Value);
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_PRINT";
|
||
/*
|
||
fprintf( Out, "Data Segment Header: Mem_Id: (%d) Start: (%p) Size: (%ld)\n",
|
||
DSH_Ptr->MemId, DSH_Ptr->Start, DSH_Ptr->Size);
|
||
*/
|
||
|
||
LG_LOG_INFO_3( "Data Segment Header: Mem_Id: (%d) Start: (%p) Size: (%ld)",
|
||
DSH_Ptr->MemId, DSH_Ptr->Start, DSH_Ptr->Size);
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_INFO_PRINT:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
ND_VA_LIST_OPEN( user_args, lib_args);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
ND_VA_LIST_CLOSE( lib_args);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
ND_VA_LIST_CLOSE( lib_args);
|
||
|
||
|
||
Command_Name = "NDD_CMD_INFO_PRINT";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_SUM:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
|
||
|
||
void *Value_Ptr = Node_Ptr->Value;
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Total_Size, user_args, size_t *);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
|
||
|
||
SMT_DSH *DSH_Ptr = (SMT_DSH *)( Node_Ptr->Value);
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_SUM";
|
||
|
||
*Total_Size += DSH_Ptr->Size;
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
default:
|
||
{
|
||
LG_LOG_ERROR_1( "Manager called with an undefined command: (%d)", Command);
|
||
return( NDS_ERRAPI);
|
||
}
|
||
}
|
||
|
||
LG_LOG_ERROR_1( "Manager internal error in command: (%d)", Command);
|
||
|
||
return( NDS_ERRAPI);
|
||
}
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Ouverture d'un segment de donn<6E>es */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_DataSegment_Open ( SMT_DSH *DSH)
|
||
{
|
||
void *Ptr;
|
||
|
||
/*
|
||
On attache le segment de m<>moire partag<61>e au processus courant.
|
||
|
||
Attention : il faut que ce segment soit attach<63> <20> la m<>me adresse
|
||
que lorsqu'il a <20>t<EFBFBD> cr<63><72> afin que les pointeurs qui pointent dans
|
||
ce segment soient valides.
|
||
*/
|
||
|
||
shmdt ( (void *)DSH->Start);
|
||
|
||
errno = 0;
|
||
Ptr = shmat( DSH->MemId, DSH->Start, 0);
|
||
if( errno)
|
||
{
|
||
LG_LOG_ERROR_2( "Unable to attach the shared memory segment at the specified address: (%p) error: (%d)", DSH->Start, errno);
|
||
|
||
return SMS_ERRSHM;
|
||
}
|
||
|
||
return SMS_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Fermeture d'un segment de donn<6E>es */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_DataSegment_Close( SMT_DSH *DSH)
|
||
{
|
||
/* On d<>tache le segment de m<>moire partag<61>e du processus courant */
|
||
|
||
shmdt ( (void *)DSH->Start);
|
||
|
||
return SMS_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Compression d'un segment de donn<6E>es */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
size_t SM_DataSegment_Compress ( SMT_DSH *DSH, NDT_Root *FCR)
|
||
{
|
||
size_t Total_Compress = 0;
|
||
size_t Compress;
|
||
SMT_Chunk *Chunk, *Next_Chunk;
|
||
NDT_Node * Node, *Next_Node;
|
||
void *DSH_End;
|
||
int Found = FALSE;
|
||
|
||
|
||
DSH_End = (void *)( (size_t)(DSH->Start) + DSH->Size);
|
||
|
||
/* Recherche du premier chunk libre contenu dans le segment courant */
|
||
|
||
ND_Index_Node_First_Get( &Node, FCR, NDD_INDEX_PRIMARY);
|
||
|
||
while( Found == FALSE && Node)
|
||
{
|
||
if( Node > (NDT_Node *)DSH_End) Node = NULL;
|
||
else
|
||
{
|
||
if( Node >= (NDT_Node *)(DSH->Start)) Found = TRUE;
|
||
else ND_Index_Node_Next_Get( &Node, Node);
|
||
}
|
||
}
|
||
|
||
if( !Node) return 0;
|
||
|
||
/* Parcours de tous les chunks libres du segment courant */
|
||
|
||
ND_Index_Node_Next_Get( &Next_Node, Node);
|
||
|
||
while( Next_Node && (void *)Next_Node < DSH_End)
|
||
{
|
||
Chunk = (SMT_Chunk *)(Node->Value);
|
||
|
||
Next_Chunk = (SMT_Chunk *)(Next_Node->Value);
|
||
|
||
/* Si le chunk suivant est "coll<6C>" au chunk courant, alors on les fusionne */
|
||
|
||
if( Next_Node == (NDT_Node *)( (size_t)(Chunk->Data) + Chunk->Size))
|
||
{
|
||
ND_Index_Node_Remove( Next_Node);
|
||
|
||
Compress = sizeof (SMT_Chunk) + sizeof (NDT_Node);
|
||
|
||
Chunk->Size += Next_Chunk->Size + Compress;
|
||
|
||
Total_Compress += Compress;
|
||
|
||
ND_Index_Node_Next_Get( &Next_Node, Node);
|
||
}
|
||
else
|
||
{
|
||
Node = Next_Node;
|
||
ND_Index_Node_Next_Get( &Next_Node, Next_Node);
|
||
}
|
||
}
|
||
|
||
return Total_Compress;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Fonction de gestion de chunks */
|
||
/*------------------------------------------------------------------------------*/
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Fonction manager pour un ACR (Allocated Chunk Root) */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
NDT_Status SM_ACR_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, va_list *Args_Ptr)
|
||
{
|
||
NDT_Command_Name Command_Name;
|
||
|
||
|
||
switch( Command)
|
||
{
|
||
case NDD_CMD_MANAGER_VERSION:
|
||
{
|
||
ND_VA_ARG_GET( Version_Name_Ptr, *Args_Ptr, NDT_Version_Name *);
|
||
|
||
|
||
Command_Name = "NDD_CMD_MANAGER_VERSION";
|
||
|
||
*Version_Name_Ptr = "$Revision: 2.4 $ $Name: $ $Date: 2005/06/26 23:40:14 $ $Author: agibert $";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_INDEX_GET:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *);
|
||
ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *);
|
||
ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command);
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *);
|
||
ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *);
|
||
ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command);
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
|
||
Command_Name = "NDD_CMD_INDEX_GET";
|
||
|
||
switch( Cmd)
|
||
{
|
||
/*
|
||
case NDT_CMD_SOME_USER_CMD:
|
||
{
|
||
*Reply_Index_Id_Ptr = 0;
|
||
*Reply_Command_Ptr = NDD_CMD_SOME_OTHER_CMD;
|
||
break;
|
||
}
|
||
|
||
...
|
||
*/
|
||
|
||
default:
|
||
{
|
||
*Reply_Index_Id_Ptr = Index_Id;
|
||
*Reply_Command_Ptr = Cmd;
|
||
break;
|
||
}
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_ALLOC:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr_Ptr, *Args_Ptr, void **);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_ALLOC";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_FREE:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
Command_Name = "NDD_CMD_VALUE_FREE";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_COMP:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value1_Ptr, *Args_Ptr, void *);
|
||
ND_VA_ARG_GET( Value2_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Chunk1_Ptr, *Args_Ptr, SMT_Chunk *);
|
||
ND_VA_ARG_GET( Chunk2_Ptr, *Args_Ptr, SMT_Chunk *);
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_COMP";
|
||
|
||
/* Les chunks allou<6F>s sont tri<72>s sur le champ <Data> (adresse d'allocation) */
|
||
|
||
if( Chunk1_Ptr->Data < Chunk1_Ptr->Data) return( NDS_LOWER);
|
||
|
||
if( Chunk1_Ptr->Data > Chunk2_Ptr->Data) return( NDS_GREATER);
|
||
|
||
return( NDS_EQUAL);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_ADD:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_ADD";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_REMOVE:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_REMOVE";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_PRINT:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
ND_VA_LIST_OPEN( user_args, lib_args);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
ND_VA_LIST_CLOSE( lib_args);
|
||
|
||
void *Value_Ptr = Node_Ptr->Value;
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
SMT_Chunk *Chunk_Ptr = (SMT_Chunk *)( Node_Ptr->Value);
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_PRINT";
|
||
/*
|
||
fprintf( Out, "Allocated Chunk: Chunk_Addr: (%p) Data_Addr: (%p) Data_Size: (%ld)\n",
|
||
Chunk_Ptr, Chunk_Ptr->Data, Chunk_Ptr->Size);
|
||
*/
|
||
|
||
LG_LOG_INFO_3( "Allocated Chunk: Chunk_Addr: (%p) Data_Addr: (%p) Data_Size: (%ld)",
|
||
Chunk_Ptr, Chunk_Ptr->Data, Chunk_Ptr->Size);
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_INFO_PRINT:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
ND_VA_LIST_OPEN( user_args, lib_args);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
ND_VA_LIST_CLOSE( lib_args);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
|
||
Command_Name = "NDD_CMD_INFO_PRINT";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_SUM:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
|
||
void *Value_Ptr = Node_Ptr->Value;
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Total_Size_Ptr, user_args, size_t *);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
|
||
SMT_Chunk *Chunk_Ptr = (SMT_Chunk *)( Node_Ptr->Value);
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_SUM";
|
||
|
||
*Total_Size_Ptr += Chunk_Ptr->Size;
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
default:
|
||
{
|
||
LG_LOG_ERROR_1( "Manager called with an undefined command: (%d)", Command);
|
||
return( NDS_ERRAPI);
|
||
}
|
||
}
|
||
|
||
LG_LOG_ERROR_1( "Manager internal error in command: (%d)", Command);
|
||
|
||
return( NDS_ERRAPI);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Fonction manager pour un FCR (Free Chunk Root) */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
NDT_Status SM_FCR_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, va_list *Args_Ptr)
|
||
{
|
||
NDT_Command_Name Command_Name;
|
||
|
||
|
||
switch( Command)
|
||
{
|
||
case NDD_CMD_MANAGER_VERSION:
|
||
{
|
||
ND_VA_ARG_GET( Version_Name_Ptr, *Args_Ptr, NDT_Version_Name *);
|
||
|
||
|
||
Command_Name = "NDD_CMD_MANAGER_VERSION";
|
||
|
||
*Version_Name_Ptr = "$Revision: 2.4 $ $Name: $ $Date: 2005/06/26 23:40:14 $ $Author: agibert $";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_INDEX_GET:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *);
|
||
ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *);
|
||
ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command);
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Reply_Index_Id_Ptr, *Args_Ptr, NDT_Index_Id *);
|
||
ND_VA_ARG_GET( Reply_Command_Ptr, *Args_Ptr, NDT_Command *);
|
||
ND_VA_ARG_GET( Cmd, *Args_Ptr, NDT_Command);
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
|
||
Command_Name = "NDD_CMD_INDEX_GET";
|
||
|
||
switch( Cmd)
|
||
{
|
||
/*
|
||
case NDT_CMD_SOME_USER_CMD:
|
||
{
|
||
*Reply_Index_Id_Ptr = 0;
|
||
*Reply_Command_Ptr = NDD_CMD_SOME_OTHER_CMD;
|
||
break;
|
||
}
|
||
|
||
...
|
||
*/
|
||
|
||
default:
|
||
{
|
||
*Reply_Index_Id_Ptr = Index_Id;
|
||
*Reply_Command_Ptr = Cmd;
|
||
break;
|
||
}
|
||
}
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_ALLOC:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr_Ptr, *Args_Ptr, void **);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_ALLOC";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_FREE:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_FREE";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_COMP:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value1_Ptr, *Args_Ptr, void *);
|
||
ND_VA_ARG_GET( Value2_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Chunk1_Ptr, *Args_Ptr, SMT_Chunk *);
|
||
ND_VA_ARG_GET( Chunk2_Ptr, *Args_Ptr, SMT_Chunk *);
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_COMP";
|
||
|
||
/*
|
||
La comparaison des chunks libres porte sur le champ <Data>
|
||
pour faciliter la compression des heaps.
|
||
*/
|
||
|
||
if( Chunk1_Ptr->Data < Chunk1_Ptr->Data) return( NDS_LOWER);
|
||
|
||
if( Chunk1_Ptr->Data > Chunk2_Ptr->Data) return( NDS_GREATER);
|
||
|
||
return( NDS_EQUAL);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_ADD:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_ADD";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_REMOVE:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Value_Ptr, *Args_Ptr, void *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
*/
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_REMOVE";
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_PRINT:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
ND_VA_LIST_OPEN( user_args, lib_args);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
ND_VA_LIST_CLOSE( lib_args);
|
||
|
||
void *Value_Ptr = Node_Ptr->Value;
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
SMT_Chunk *Chunk_Ptr = (SMT_Chunk *)( Node_Ptr->Value);
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_PRINT";
|
||
|
||
// fprintf( Out, "Free Chunk: Chunk_Addr: (%p) Data_Ptr: (%p) Size: (%ld)\n", Chunk_Ptr, Chunk_Ptr->Data, Chunk_Ptr->Size);
|
||
|
||
LG_LOG_INFO_3( "Free Chunk: Chunk_Addr: (%p) Data_Ptr: (%p) Size: (%ld)", Chunk_Ptr, Chunk_Ptr->Data, Chunk_Ptr->Size);
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_INFO_PRINT:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
ND_VA_LIST_OPEN( user_args, lib_args);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
ND_VA_LIST_CLOSE( lib_args);
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( lib_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Out, lib_args, FILE *);
|
||
ND_VA_ARG_GET( Recursive_Mode, lib_args, NDT_Recursive_Mode);
|
||
ND_VA_ARG_GET( Recursive_Depth, lib_args, NDT_Recursive_Depth);
|
||
ND_VA_ARG_GET( Recursive_Offset, lib_args, NDT_Recursive_Offset);
|
||
|
||
|
||
Command_Name = "NDD_CMD_INFO_PRINT";
|
||
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
case NDD_CMD_VALUE_SUM:
|
||
{
|
||
/*
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( user_data, user_args, user_type);
|
||
ND_VA_ARG_GET( ..., user_args, ...);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
|
||
void *Value_Ptr = Node_Ptr->Value;
|
||
*/
|
||
|
||
ND_VA_ARG_GET( Next_Node_Ptr, *Args_Ptr, NDT_Node *);
|
||
|
||
ND_VA_LIST_OPEN( user_args, *Args_Ptr);
|
||
|
||
ND_VA_ARG_GET( Total_Size_Ptr, user_args, size_t *);
|
||
|
||
ND_VA_LIST_CLOSE( user_args);
|
||
|
||
SMT_Chunk *Chunk_Ptr = (SMT_Chunk *)( Node_Ptr->Value);
|
||
|
||
|
||
Command_Name = "NDD_CMD_VALUE_SUM";
|
||
|
||
*Total_Size_Ptr += Chunk_Ptr->Size;
|
||
|
||
return( NDS_OK);
|
||
}
|
||
|
||
default:
|
||
{
|
||
LG_LOG_ERROR_1( "Manager called with an undefined command: (%d)", Command);
|
||
return( NDS_ERRAPI);
|
||
}
|
||
}
|
||
|
||
LG_LOG_ERROR_1( "Manager internal error in command: (%d)", Command);
|
||
|
||
return( NDS_ERRAPI);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Pose d'un verrou sur un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_Lock_Set ( SMT_MHH * MHH, SMT_Flags Lock_Mode )
|
||
{
|
||
SMT_Status rc;
|
||
|
||
if( Lock_Mode & SMD_READ)
|
||
{
|
||
rc = SM_Semaphore_Operate( MHH->SemId, SM_SemOp_SSL, 2);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to lock the heap: [%s] for reading", MHH->Name);
|
||
|
||
return rc;
|
||
}
|
||
}
|
||
|
||
if( Lock_Mode & SMD_WRITE)
|
||
{
|
||
rc = SM_Semaphore_Operate( MHH->SemId, SM_SemOp_SEL, 2);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to lock the heap: [%s] for writing", MHH->Name);
|
||
|
||
return rc;
|
||
}
|
||
}
|
||
|
||
return SMS_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Changement d'un verrou sur un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_Lock_Change( SMT_MHH * MHH, SMT_Flags Lock_Mode )
|
||
{
|
||
SMT_Status rc;
|
||
|
||
if( Lock_Mode & SMD_WRITE)
|
||
{
|
||
/*
|
||
Attention : il ne faut pas tenter de transformer directement un verrou en lecture en
|
||
un verrou en <20>criture car cela pourrait aboutir <20> un deadlock entre deux processus
|
||
qui voudraient r<>aliser cette op<6F>ration en m<>me temps.
|
||
|
||
=> On passe donc par un d<>verrouillage interm<72>diaire.
|
||
*/
|
||
|
||
if( (rc = SM_Semaphore_Operate( MHH->SemId, SM_SemOp_RSL, 2)) != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to transform the heap: [%s] lock for writing", MHH->Name);
|
||
|
||
return rc;
|
||
}
|
||
|
||
if( (rc = SM_Semaphore_Operate( MHH->SemId, SM_SemOp_SEL, 2)) != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to transform the heap: [%s] lock for writing", MHH->Name);
|
||
|
||
/* On tente de revenir <20> l'<27>tat de verrouillage pr<70>c<EFBFBD>dent */
|
||
|
||
SM_Semaphore_Operate( MHH->SemId, SM_SemOp_SSL, 2);
|
||
|
||
return rc;
|
||
}
|
||
}
|
||
else if( Lock_Mode & SMD_READ)
|
||
{
|
||
rc = SM_Semaphore_Operate( MHH->SemId, SM_SemOp_TSL, 2);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to transform the heap: [%s] lock for reading", MHH->Name);
|
||
|
||
return rc;
|
||
}
|
||
}
|
||
|
||
return SMS_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Lib<69>ration d'un verrou sur un heap */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Heap_Lock_Release( SMT_MHH * MHH, SMT_Flags Lock_Mode )
|
||
{
|
||
SMT_Status rc;
|
||
|
||
if( Lock_Mode & SMD_READ)
|
||
{
|
||
rc = SM_Semaphore_Operate( MHH->SemId, SM_SemOp_RSL, 2);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to unlock the heap: [%s] which had been locked for reading", MHH->Name);
|
||
|
||
return rc;
|
||
}
|
||
}
|
||
|
||
if( Lock_Mode & SMD_WRITE)
|
||
{
|
||
rc = SM_Semaphore_Operate( MHH->SemId, SM_SemOp_REL, 2);
|
||
if( rc != SMS_OK)
|
||
{
|
||
LG_LOG_ERROR_1( "Unable to unlock the heap: [%s] which had been locked for writing", MHH->Name);
|
||
|
||
return rc;
|
||
}
|
||
}
|
||
|
||
return SMS_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Op<4F>ration sur un s<>maphore */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Semaphore_Operate( int SemId, struct sembuf * Operations, unsigned int Nb_Oper)
|
||
{
|
||
if( semop( SemId, Operations, Nb_Oper) == -1)
|
||
{
|
||
switch( errno)
|
||
{
|
||
case EAGAIN:
|
||
{
|
||
LG_LOG_ERROR_0( "The operation would result in suspension of the calling process but the operations have been defined in no wait mode");
|
||
|
||
return SMS_NO_WAIT;
|
||
}
|
||
|
||
case EACCES:
|
||
{
|
||
LG_LOG_ERROR_1( "Current process is not allowed to operate on semaphore: (%d)", SemId);
|
||
|
||
break;
|
||
}
|
||
|
||
case EIDRM:
|
||
{
|
||
LG_LOG_ERROR_1( "Semaphore: (%d) does not exist", SemId);
|
||
|
||
break;
|
||
}
|
||
|
||
case EINTR:
|
||
{
|
||
LG_LOG_ERROR_1( "A signal was received while operating on semaphore: (%d)", SemId);
|
||
|
||
return SMS_ERRSIG;
|
||
}
|
||
|
||
case EINVAL:
|
||
{
|
||
LG_LOG_ERROR_1( "The semaphore identifier: (%d) is incorrect or the number of operations which can be done in UNDO mode exceeds the system-imposed limit", SemId);
|
||
|
||
break;
|
||
}
|
||
|
||
case ENOSPC:
|
||
{
|
||
LG_LOG_ERROR_1( "The maximum number of process which can operate on semaphore: (%d) in UNDO mode has been reached", SemId);
|
||
|
||
break;
|
||
}
|
||
|
||
case ERANGE:
|
||
{
|
||
LG_LOG_ERROR_1( "The value of semaphore: (%d) has reached the system-imposed limit", SemId);
|
||
|
||
break;
|
||
}
|
||
|
||
default:
|
||
{
|
||
LG_LOG_ERROR_2( "Unknown error: (%d) while operating on semaphore: (%d)", errno, SemId);
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
return SMS_ERRSEM;
|
||
}
|
||
|
||
return SMS_OK;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* R<>cup<75>re sous forme explicite l'<27>tat d'un verrou */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
char *SM_Lock_Status_Get( const char *Type_Name, void *Struct_Ptr)
|
||
{
|
||
static char status[50];
|
||
int i, sem_id;
|
||
pid_t writer;
|
||
union semun sem_ctl;
|
||
|
||
|
||
if( !strcmp( Type_Name, "base"))
|
||
{
|
||
sem_id = SM_Base->SemId;
|
||
writer = SM_Base->Writer;
|
||
}
|
||
else
|
||
{
|
||
if( !strcmp( Type_Name, "heap"))
|
||
{
|
||
SMT_MHH *MHH_Ptr = (SMT_MHH *)Struct_Ptr;
|
||
|
||
sem_id = MHH_Ptr->SemId;
|
||
writer = MHH_Ptr->Writer;
|
||
}
|
||
else
|
||
{
|
||
strcpy( status, "Unknown");
|
||
|
||
return( status);
|
||
}
|
||
}
|
||
|
||
i = semctl( sem_id, 0, GETVAL, sem_ctl);
|
||
|
||
switch( i)
|
||
{
|
||
case 0:
|
||
{
|
||
sprintf( status, "Exclusive Lock for PId: (%ld)", writer);
|
||
|
||
break;
|
||
}
|
||
|
||
case 1:
|
||
{
|
||
sprintf( status, "Unlocked");
|
||
|
||
break;
|
||
}
|
||
|
||
default :
|
||
{
|
||
if( i < 0)
|
||
{
|
||
sprintf( status, "Abnormal Status: (%d)", i);
|
||
}
|
||
else
|
||
{
|
||
sprintf( status, "Shared Lock Process_Nb: (%d)", i - 1);
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
return( status);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*------------------------------------------------------------------------------*/
|
||
/* Add context prefix to heap name */
|
||
/*------------------------------------------------------------------------------*/
|
||
/* (O) Prefixed: Prefixed heap name */
|
||
/* (I) Unprefixed: Unprefixed heap name */
|
||
/*------------------------------------------------------------------------------*/
|
||
|
||
SMT_Status SM_Name_Prefix( char *Prefixed, const char *Unprefixed)
|
||
{
|
||
if( !SM_Context || !strlen( SM_Context) || !strcmp( Unprefixed, HEAP_SYSTEM))
|
||
{
|
||
strcpy( Prefixed, Unprefixed);
|
||
}
|
||
else
|
||
{
|
||
snprintf( Prefixed, SMD_NAME_SIZE, "%s/%s", SM_Context, Unprefixed);
|
||
}
|
||
|
||
return( SMS_OK);
|
||
}
|