diff --git a/lib/libshmem.c b/lib/libshmem.c index 5245643..e4c4f99 100644 --- a/lib/libshmem.c +++ b/lib/libshmem.c @@ -1,9 +1,9 @@ /*---------------------------------------------------------------------------------*/ /* $RCSfile: libshmem.c,v $ */ /*---------------------------------------------------------------------------------*/ -/* $Revision: 2.2 $ */ +/* $Revision: 2.3 $ */ /* $Name: $ */ -/* $Date: 2005/02/23 23:31:06 $ */ +/* $Date: 2005/06/26 22:50:49 $ */ /* $Author: agibert $ */ /*---------------------------------------------------------------------------------*/ @@ -36,7 +36,7 @@ #include #ifdef _LIBVER_SUPPORT -VER_INFO_EXPORT(libshmem,"$Revision: 2.2 $", "$Name: $",__FILE__,"$Author: agibert $") +VER_INFO_EXPORT(libshmem,"$Revision: 2.3 $", "$Name: $",__FILE__,"$Author: agibert $") #endif /*------------------------------------------------------------------------------*/ @@ -359,7 +359,7 @@ SMT_Status SM_Library_Dump_I( FILE *Out) { /* Affichage des informations sur la base */ - fprintf( Out, "Base [%d/%s] :\n\t- Size = %d bytes\n\t- Creator pid = %ld\n\t- Last write access pid = %ld\n\t- Id Mem = %d (+%d)\n\t- Id Sem = %d\n\t- Status = %s\n\n", + 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)); /* Affichage des informations du MHR */ @@ -646,144 +646,15 @@ SMT_Status SM_Heap_Open_I( const char *Heap_Name, SMT_Heap **Heap, size_t Se return( SMS_ERRAPI); } - /* Cré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: - { - sprintf( SM_Error_Msg, "SM_Heap_Open : the amount of memory is not sufficient to create a new semaphore"); - break; - } - - case ENOSPC: - { - sprintf( SM_Error_Msg, "SM_Heap_Open : the number of semaphores exceeds the system-imposed limit"); - break; - } - - default : - { - sprintf( SM_Error_Msg, "SM_Heap_Open : unknown error (%d) while creating a semaphore", errno); - break; - } - } - - SM_Error_Print(); - - return( SMS_ERRSEM); - } - - /* Initialisation du sémaphore à 1 (équivaut à aucun verrou posé) */ - - Sem_Ctl.val = 1; - - if( semctl( SemId, 0, SETVAL, Sem_Ctl)) - { - sprintf( SM_Error_Msg, "SM_Heap_Open : unable to initialize the value of the semaphore %d", SemId); - SM_Error_Print(); - - rc = SMS_ERRSEM; - goto Error3; - } - - /* Réservation du MHH (dans la base pour le heap système, dans le heap système pour les autres heaps) */ - - if( ND_Allocator_Exec( (void **)(&MHH), sizeof( SMT_MHH), SM_Base->MHR->Allocator_Name, SM_Base->MHR->Allocator_Ptr, NULL) != NDS_OK) - { - sprintf( SM_Error_Msg, "SM_Heap_Open : unable to allocate memory for the heap header"); - SM_Error_Print(); - - rc = SMS_ERRSHM; - goto Error3; - } - - /* Initialisation de la structure du nouveau MHH */ - - strcpy( MHH->Name, Prefixed_Name); - MHH->Writer = getpid(); - MHH->SemId = SemId; - MHH->State = SMD_STATE_UNVALIDATED; - MHH->Segment_Size = ( ( Seg_Size > 0) ? Seg_Size : SEGMENT_DEFAULT_SIZE); - MHH->Limit_Size = SMD_UNLIMITED; - MHH->Auto_Compress = SMD_DEFAULT_COMPRESS; - - - /* - Création de la structure DSR : - - dans la base pour le heap système - - dans le heap système pour les autres heaps - */ - - rc = ND_DataStruct_Open( &( MHH->DSR), 1, &index_type, "SM_DSR_Manager", NULL, SM_Base->MHR->Allocator_Name, NULL, SM_Base->MHR->Desallocator_Name, NULL, TRUE, NULL); + /*Alloc du MHH qui fait l'alloccation du premier segment de donnees*/ + rc = ND_Value_Alloc(SM_Base->MHR,(void**)&MHH,Prefixed_Name,Seg_Size); if (rc != NDS_OK) { - sprintf( SM_Error_Msg, "SM_Heap_Open : unable to create the DSR structure"); + sprintf( SM_Error_Msg, "SM_Heap_Open : unable to to create the MHR structure"); SM_Error_Print(); - - goto Error4; + return(SMS_ERRAPI); } - - /* - Création de la structure ACR : - - dans la base pour le heap système - - dans le heap système pour les autres heaps - */ - - rc = ND_DataStruct_Open( &( MHH->ACR), 1, &index_type, "SM_ACR_Manager", NULL, SM_Base->MHR->Allocator_Name, NULL, SM_Base->MHR->Desallocator_Name, NULL, TRUE, NULL); - if (rc != NDS_OK) - { - sprintf( SM_Error_Msg, "SM_Heap_Open : unable to create the ACR structure"); - SM_Error_Print(); - - goto Error5; - } - - - /* - Création de la structure FCR : - - dans la base pour le heap système - - dans le heap système pour les autres heaps - */ - - rc = ND_DataStruct_Open( &( MHH->FCR), 1, &index_type, "SM_FCR_Manager", NULL, SM_Base->MHR->Allocator_Name, NULL, SM_Base->MHR->Desallocator_Name, NULL, TRUE, NULL); - if( rc != NDS_OK) - { - sprintf( SM_Error_Msg, "SM_Heap_Open : unable to create the FCR structure"); - SM_Error_Print(); - - goto Error6; - } - - - /* Création d'un premier segment de données */ - - New_DSH = SM_DataSegment_Init( MHH, MHH->Segment_Size); - if( !New_DSH) - { - sprintf( SM_Error_Msg, "SM_Heap_Open : unable to create a data segment for the new heap"); - SM_Error_Print(); - - rc = SMS_ERRSHM; - - goto Error7; - } - - rc = ND_DataStruct_Value_Add( MHH->DSR, New_DSH); - if( rc != NDS_OK) - { - sprintf( SM_Error_Msg, "SM_Heap_Open : unable to add a data segment to the DSR structure"); - SM_Error_Print(); - - goto Error8; - } - - MHH->State = SMD_STATE_VALID; - /* Ajout du nouveau heap à la structure MHR */ rc = ND_DataStruct_Value_Add( SM_Base->MHR, MHH); @@ -791,7 +662,6 @@ SMT_Status SM_Heap_Open_I( const char *Heap_Name, SMT_Heap **Heap, size_t Se { sprintf( SM_Error_Msg, "SM_Heap_Open : unable to add the new heap to the MHR structure"); SM_Error_Print(); - goto Error9; } @@ -803,7 +673,6 @@ SMT_Status SM_Heap_Open_I( const char *Heap_Name, SMT_Heap **Heap, size_t Se sprintf( SM_Error_Msg, "SM_Heap_Open : unable to lock heap \"%s\" for %s", Prefixed_Name, Open_Mode & SMD_READ ? "reading" : "writing"); SM_Error_Print(); - goto Error10; } @@ -854,7 +723,7 @@ SMT_Status SM_Heap_Open_I( const char *Heap_Name, SMT_Heap **Heap, size_t Se ND_DataStruct_Value_Remove( MHH->DSR, New_DSH); Error8: - SM_DataSegment_End( MHH->DSR, New_DSH); + ND_Value_Free( MHH->DSR, New_DSH); Error7: ND_Desallocator_Exec( MHH->FCR, SM_Base->MHR->Desallocator_Name, SM_Base->MHR->Desallocator_Ptr, NULL); @@ -1308,10 +1177,10 @@ SMT_Status SM_Heap_Config_I ( SMT_Heap * Heap, SMT_Config Tag, ... ) /* (O) Compress : pointeur sur la taille mémoire gagnée */ /*------------------------------------------------------------------------------*/ -SMT_Status SM_Heap_Compress_I ( SMT_Heap * Heap, size_t * Compress) +SMT_Status SM_Heap_Compress_I( SMT_Heap *Heap, size_t *Compress) { - SMT_Status rc; - NDT_Node * Node; + SMT_Status rc; + NDT_Node *Node; *Compress = 0; @@ -1322,18 +1191,21 @@ SMT_Status SM_Heap_Compress_I ( SMT_Heap * Heap, size_t * Compress) */ rc = ND_DataStruct_Reorg (Heap->MHH->FCR); - if (rc != NDS_OK) return rc; + if( rc != NDS_OK) return( rc); /* Compression de chaque segment de données du heap */ ND_Index_Node_First_Get( &Node, Heap->MHH->DSR, NDD_INDEX_PRIMARY); - while (Node) + + while( Node) { - *Compress += SM_DataSegment_Compress ((SMT_DSH *)(Node->Value), Heap->MHH->FCR); + *Compress += SM_DataSegment_Compress( (SMT_DSH *)(Node->Value), Heap->MHH->FCR); ND_Index_Node_Next_Get( &Node, Node); } - return SMS_OK; + Heap->MHH->Compress_Nb++; + + return( SMS_OK); } @@ -1551,8 +1423,9 @@ SMT_Status SM_Chunk_Alloc_I ( SMT_Heap * Heap, size_t Alloc_Size, void ** Ptr ) else Seg_Size = Heap->MHH->Segment_Size; - DSH = SM_DataSegment_Init (Heap->MHH, Seg_Size); - if (!DSH) + + rc = ND_Value_Alloc(Heap->MHH->DSR,(void**)&DSH,Heap->MHH, Seg_Size); + if (rc != NDS_OK ) { sprintf (SM_Error_Msg, "SM_Chunk_Alloc : unable to create a new data segment for heap \"%s\"", Heap->Name); SM_Error_Print (); @@ -1566,7 +1439,8 @@ SMT_Status SM_Chunk_Alloc_I ( SMT_Heap * Heap, size_t Alloc_Size, void ** Ptr ) sprintf (SM_Error_Msg, "SM_Chunk_Alloc : unable to add a data segment to the DSR structure of heap \"%s\"", Heap->Name); SM_Error_Print (); - SM_DataSegment_End (Heap->MHH->DSR, DSH); + + ND_Value_Free(Heap->MHH->DSR, DSH); return rc; } @@ -1721,7 +1595,7 @@ SMT_Status SM_Chunk_Alloc_I ( SMT_Heap * Heap, size_t Alloc_Size, void ** Ptr ) /* On alloue le noeud du nouveau segment avant de faire appel à la fonction - SM_DataSegment_Init pour éviter que ce noeud soit alloué dans le nouveau segment. + ND_Value_Alloc pour éviter que ce noeud soit alloué dans le nouveau segment. */ SM_System_Alloc( (void **)(&New_Node), sizeof (NDT_Node), NULL); @@ -1731,9 +1605,8 @@ SMT_Status SM_Chunk_Alloc_I ( SMT_Heap * Heap, size_t Alloc_Size, void ** Ptr ) New_Node->Right = NULL; /* On crée le nouveau segment */ - - DSH = SM_DataSegment_Init (Heap->MHH, Heap->MHH->Segment_Size); - if (!DSH) + rc = ND_Value_Alloc(Heap->MHH->DSR,(void**)&DSH,Heap->MHH,Heap->MHH->Segment_Size); + if (rc != NDS_OK) { sprintf (SM_Error_Msg, "SM_Chunk_Alloc : unable to create un new data segment for the system heap (anticipation)"); SM_Error_Print (); @@ -1751,8 +1624,8 @@ SMT_Status SM_Chunk_Alloc_I ( SMT_Heap * Heap, size_t Alloc_Size, void ** Ptr ) sprintf (SM_Error_Msg, "SM_Chunk_Alloc : unable to add a data segment to the DSR structure of the system heap (anticipation)"); SM_Error_Print (); - SM_DataSegment_End (Heap->MHH->DSR, DSH); + ND_Value_Free(Heap->MHH->DSR, DSH); return rc; } @@ -2624,7 +2497,7 @@ SMT_Status SM_Base_Init ( void ) /* On attache le segment de mémoire partagée au processus courant */ errno = 0; - SM_Base = shmat (SysMemId, 0, 0); + SM_Base = shmat( SysMemId, 0, 0); if (errno) { sprintf (SM_Error_Msg, "SM_Base_Init : unable to attach the first shared memory segment to the current process (error %d)", errno); @@ -2703,7 +2576,13 @@ SMT_Status SM_Base_Init ( void ) */ errno = 0; - SM_Base->Free = shmat (DataMemId, (void *)((size_t)(SM_Base->Attach) - Size), SHM_RND); + +#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) { sprintf (SM_Error_Msg, "SM_Base_Init : unable to attach the second shared memory segment to the current process (error %d)", errno); @@ -3001,7 +2880,7 @@ SMT_Status SM_Base_Open ( void ) /* On attache les segments de mémoire partagée de la base */ errno = 0; - SM_Base = shmat (MemId, 0, 0); + SM_Base = shmat( MemId, 0, 0); if (errno) { sprintf (SM_Error_Msg, "SM_Base_Open : unable to attach the shared memory segment to the current process (error %d)", errno); @@ -3207,7 +3086,7 @@ NDT_Status SM_Opened_Heap_List_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Inde Command_Name = "NDD_CMD_MANAGER_VERSION"; - *Version_Name_Ptr = "$Revision: 2.2 $ $Name: $ $Date: 2005/02/23 23:31:06 $ $Author: agibert $"; + *Version_Name_Ptr = "$Revision: 2.3 $ $Name: $ $Date: 2005/06/26 22:50:49 $ $Author: agibert $"; return( NDS_OK); } @@ -3434,7 +3313,7 @@ NDT_Status MHR_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node Command_Name = "NDD_CMD_MANAGER_VERSION"; - *Version_Name_Ptr = "$Revision: 2.2 $ $Name: $ $Date: 2005/02/23 23:31:06 $ $Author: agibert $"; + *Version_Name_Ptr = "$Revision: 2.3 $ $Name: $ $Date: 2005/06/26 22:50:49 $ $Author: agibert $"; return( NDS_OK); } @@ -3488,11 +3367,183 @@ NDT_Status MHR_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node user_type user_data = (user_type)va_arg( user_args, user_type); ... = (...)va_arg( user_args, ...); */ + SMT_MHH **MHH_Ptr_Ptr = (SMT_MHH **)va_arg( Args, SMT_MHH **); + va_list user_args = (va_list)va_arg( Args, va_list ); + char *Prefixed_Name = (char*)va_arg( user_args, char *); + size_t Seg_Size = (size_t)va_arg( user_args, size_t ); + + 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"; + Command_Name = "NDD_CMD_VALUE_ALLOC"; + + /* Cré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: + { + sprintf( SM_Error_Msg, "SM_Heap_Open : the amount of memory is not sufficient to create a new semaphore"); + break; + } + + case ENOSPC: + { + sprintf( SM_Error_Msg, "SM_Heap_Open : the number of semaphores exceeds the system-imposed limit"); + break; + } + + default : + { + sprintf( SM_Error_Msg, "SM_Heap_Open : unknown error (%d) while creating a semaphore", errno); + break; + } + } + + SM_Error_Print(); + return(NDS_ERRMEM); + } + + /* Initialisation du sémaphore à 1 (équivaut à aucun verrou posé) */ + + Sem_Ctl.val = 1; + + if( semctl( SemId, 0, SETVAL, Sem_Ctl)) + { + sprintf( SM_Error_Msg, "SM_Heap_Open : unable to initialize the value of the semaphore %d", SemId); + SM_Error_Print(); + + rc = SMS_ERRSEM; + goto Error3; + } + + + /* Réservation du MHH (dans la base pour le heap système, dans le heap système pour les autres heaps) */ + + if( ND_Allocator_Exec( (void **)(MHH_Ptr_Ptr), sizeof( SMT_MHH), SM_Base->MHR->Allocator_Name, SM_Base->MHR->Allocator_Ptr, NULL) != NDS_OK) + { + sprintf( SM_Error_Msg, "SM_Heap_Open : unable to allocate memory for the heap header"); + SM_Error_Print(); + + 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éation de la structure DSR : + - dans la base pour le heap système + - dans le heap systè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->Desallocator_Name, NULL, TRUE, NULL); + if (rc != NDS_OK) + { + sprintf( SM_Error_Msg, "SM_Heap_Open : unable to create the DSR structure"); + SM_Error_Print(); + goto Error4; + } + + + /* + Création de la structure ACR : + - dans la base pour le heap système + - dans le heap systè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->Desallocator_Name, NULL, TRUE, NULL); + if (rc != NDS_OK) + { + sprintf( SM_Error_Msg, "SM_Heap_Open : unable to create the ACR structure"); + SM_Error_Print(); + goto Error5; + + } + + + /* + Création de la structure FCR : + - dans la base pour le heap système + - dans le heap systè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->Desallocator_Name, NULL, TRUE, NULL); + if( rc != NDS_OK) + { + sprintf( SM_Error_Msg, "SM_Heap_Open : unable to create the FCR structure"); + SM_Error_Print(); + goto Error6; + + } + + /*alloction du premier segement de donnee pour le heap*/ + rc = ND_Value_Alloc( (*MHH_Ptr_Ptr)->DSR, (void **)&DSH_Ptr, *MHH_Ptr_Ptr, (*MHH_Ptr_Ptr)->Segment_Size); + if( rc != NDS_OK) + { + sprintf( SM_Error_Msg, "MHR_Manager : unable to create the DSH structure"); + SM_Error_Print(); + rc = SMS_ERRSHM; + goto Error7; + } + + rc = ND_DataStruct_Value_Add( (*MHH_Ptr_Ptr)->DSR, DSH_Ptr); + if( rc != NDS_OK) + { + sprintf( SM_Error_Msg, "SM_Heap_Open : unable to add a data segment to the DSR structure"); + SM_Error_Print(); + + goto Error8; + } + + (*MHH_Ptr_Ptr)->State = SMD_STATE_VALID; return( NDS_OK); + + + /* Gestion d'erreur sur création */ + + Error9: + ND_DataStruct_Value_Remove( (*MHH_Ptr_Ptr)->DSR, DSH_Ptr); + + Error8: + ND_Value_Free( (*MHH_Ptr_Ptr)->DSR, DSH_Ptr); + + Error7: + ND_Desallocator_Exec( (*MHH_Ptr_Ptr)->FCR, SM_Base->MHR->Desallocator_Name, SM_Base->MHR->Desallocator_Ptr, NULL); + + Error6: + ND_Desallocator_Exec( (*MHH_Ptr_Ptr)->ACR, SM_Base->MHR->Desallocator_Name, SM_Base->MHR->Desallocator_Ptr, NULL); + + Error5: + ND_Desallocator_Exec( (*MHH_Ptr_Ptr)->DSR, SM_Base->MHR->Desallocator_Name, SM_Base->MHR->Desallocator_Ptr, NULL); + + Error4: + ND_Desallocator_Exec( *MHH_Ptr_Ptr, SM_Base->MHR->Desallocator_Name, SM_Base->MHR->Desallocator_Ptr, NULL); + + Error3: + semctl( SemId, 0, IPC_RMID, Sem_Ctl); + + return( rc); + + } case NDD_CMD_VALUE_FREE: @@ -3504,13 +3555,142 @@ NDT_Status MHR_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node ... = (...)va_arg( user_args, ...); */ - SMT_MHH *MHH_Ptr = (SMT_MHH *)va_arg( Args, SMT_MHH *); - + SMT_MHH *MHH_Ptr = (SMT_MHH *)va_arg( Args, 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) */ - return( SM_MHH_End( MHH_Ptr)); + if (!strcmp (MHH_Ptr->Name, HEAP_SYSTEM)) + { + NDT_Node * Node, * Previous_Node; + SMT_DSH * DSH; + + /* + Pour le heap système, on doit procéder de manière spécifique + car le premier segment contient des références sur les autres + segments. Il faut donc supprimer celui-ci en dernier. + + Par ailleurs, ce premier segment a été alloué dans la base. + Il faudra donc aussi redé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ème ? */ + + if( !Previous_Node) + { + strcpy( MHH_Ptr->DSR->Desallocator_Name, "SM_Base_Free"); + } + + /* Retrait du segment du DSR */ + + rc = ND_DataStruct_Value_Remove( MHH_Ptr->DSR, DSH); + if (rc != NDS_OK) + { + sprintf (SM_Error_Msg, "MHR_Manager NDD_CMD_VALUE_FREE : unable to remove the shared memory segment (address=%p) from the DSR structure", DSH->Start); + SM_Error_Print (); + + if (SM_ERROR(rc)) return rc; + } + + /* Destruction du segment */ + + rc = ND_Value_Free( MHH_Ptr->DSR, DSH); + if (rc != NDS_OK) + { + sprintf (SM_Error_Msg, " MHR_Manager NDD_CMD_VALUE_FREE: unable to free the shared memory segment (address=%p)", DSH->Start); + SM_Error_Print (); + + if (SM_ERROR(rc)) return rc; + } + + Node = Previous_Node; + } + } + else + { + rc = ND_DataStruct_Close (MHH_Ptr->DSR); + if (rc != NDS_OK) + { + sprintf (SM_Error_Msg, "MHR_Manager NDD_CMD_VALUE_FREE : unable to destroy the DSR structure of heap \"%s\"", MHH_Ptr->Name); + SM_Error_Print (); + } + } + + /* + Destruction des structures ACR et FCR. + + NB : puisque tous les chunks réfénrencés par les ACR et FCR étaient alloués + dans les segments qui viennent d'être supprimés, on se contente de détuire + leur racine. + */ + + rc = ND_Desallocator_Exec( MHH_Ptr->ACR, SM_Base->MHR->Desallocator_Name, SM_Base->MHR->Desallocator_Ptr, NULL); + if (rc != NDS_OK) + { + sprintf (SM_Error_Msg, "MHR_Manager NDD_CMD_VALUE_FREE : unable to free the ACR root of heap \"%s\"", MHH_Ptr->Name); + SM_Error_Print (); + } + + rc = ND_Desallocator_Exec( MHH_Ptr->FCR, SM_Base->MHR->Desallocator_Name, SM_Base->MHR->Desallocator_Ptr, NULL); + if (rc != NDS_OK) + { + sprintf (SM_Error_Msg, "MHR_Manager NDD_CMD_VALUE_FREE : unable to free the FCR root of heap \"%s\"", MHH_Ptr->Name); + SM_Error_Print (); + } + + /* 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é au heap */ + + semctl (MHH_Ptr->SemId, 0, IPC_RMID, Sem_Ctl); + + /* Désallocation de la structure du MHH */ + + rc = ND_Desallocator_Exec( MHH_Ptr, SM_Base->MHR->Desallocator_Name, SM_Base->MHR->Desallocator_Ptr, NULL); + if (rc != SMS_OK) + { + sprintf (SM_Error_Msg, "MHR_Manager NDD_CMD_VALUE_FREE : unable to free the header of heap \"%s\"", MHH_Ptr->Name); + SM_Error_Print (); + } + + + return(NDS_OK); } case NDD_CMD_VALUE_COMP: @@ -3596,7 +3776,7 @@ NDT_Status MHR_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node SMT_MHH *MHH_Ptr = (SMT_MHH *)( Node_Ptr->Value); SMT_Status status; - size_t segment_size, alloc_size, free_size; + 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; @@ -3648,9 +3828,10 @@ NDT_Status MHR_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node 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]\n\tWriter_PId: (%ld) Size_Limit: (%ld) Auto_Compress: (%d) Seg_Nb: (%d) Heap_Size: (%ld)\n\tAlloc_Chunk_Nb: (%d) Alloc_Size: (%ld) Free_Chunk_Nb: (%d) Free_Size: (%ld)\n\n", - SM_Context, heap_name, MHH_Ptr, MHH_Ptr->SemId, SM_Lock_Status_Get( "heap", MHH_Ptr), MHH_Ptr->Writer, MHH_Ptr->Limit_Size, MHH_Ptr->Auto_Compress, - segment_nb, segment_size, alloc_chunk_nb, alloc_size, free_chunk_nb, 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); if( locked == TRUE) { @@ -3864,6 +4045,8 @@ SMT_Status SM_MHH_End( SMT_MHH *MHH) NDT_Status SM_DSR_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node *Node_Ptr, NDT_Command Command, va_list Args) { NDT_Command_Name Command_Name; + NDT_Node * Chunk_Node; + SMT_Chunk * Chunk; switch( Command) @@ -3875,7 +4058,7 @@ NDT_Status SM_DSR_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node Command_Name = "NDD_CMD_MANAGER_VERSION"; - *Version_Name_Ptr = "$Revision: 2.2 $ $Name: $ $Date: 2005/02/23 23:31:06 $ $Author: agibert $"; + *Version_Name_Ptr = "$Revision: 2.3 $ $Name: $ $Date: 2005/06/26 22:50:49 $ $Author: agibert $"; return( NDS_OK); } @@ -3928,11 +4111,122 @@ NDT_Status SM_DSR_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node va_list user_args = (va_list)va_arg( Args, va_list); user_type user_data = (user_type)va_arg( user_args, user_type); ... = (...)va_arg( user_args, ...); - */ + */ + SMT_DSH **DSH_Ptr_Ptr = (SMT_DSH **)va_arg( Args, SMT_DSH **); + va_list user_args = (va_list)va_arg( Args, va_list ); + SMT_MHH *MHH_Ptr = (SMT_MHH*)va_arg( user_args, SMT_MHH *); + size_t Segment_Size = (size_t)va_arg( user_args, size_t ); 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) + { + sprintf (SM_Error_Msg, "SM_DSR_Manager NDD_CMD_VALUE_ALLOC : the heap limit size would be exceeded"); + SM_Error_Print (); + + return NULL; + } + } + + /* Création de l'entête */ + + if( ND_Allocator_Exec( (void **)DSH_Ptr_Ptr, sizeof (SMT_DSH), MHH_Ptr->DSR->Allocator_Name, MHH_Ptr->DSR->Allocator_Ptr, NULL) != NDS_OK) + { + sprintf (SM_Error_Msg, "SM_DSR_Manager NDD_CMD_VALUE_ALLOC : unable to allocate memory for the new data segment header"); + SM_Error_Print (); + + return NULL; + } + + /* Création d'un segment de mémoire partagée */ + if (((*DSH_Ptr_Ptr)->MemId = shmget (IPC_PRIVATE, Segment_Size, 0777|IPC_CREAT|IPC_EXCL)) == -1) + { + switch (errno) + { + case EINVAL: + sprintf (SM_Error_Msg, "SM_DSR_Manager NDD_CMD_VALUE_ALLOC : the size of the shared memory segment (%d) is out of the system-imposed bounds", Segment_Size); + break; + + case ENOMEM: + sprintf (SM_Error_Msg, "SM_DSR_Manager NDD_CMD_VALUE_ALLOC : the amount of memory is not sufficient to create the shared memory segment"); + break; + + case ENOSPC: + sprintf (SM_Error_Msg, "SM_DSR_Manager NDD_CMD_VALUE_ALLOC : the number of shared memory segments exceeds the system-imposed limit"); + break; + + default : + sprintf (SM_Error_Msg, "SM_DSR_Manager NDD_CMD_VALUE_ALLOC : unknown error (%d) while creating a shared memory segment", errno); + break; + } + + SM_Error_Print (); + + ND_Desallocator_Exec( (*DSH_Ptr_Ptr), MHH_Ptr->DSR->Desallocator_Name, MHH_Ptr->DSR->Desallocator_Ptr, NULL); + + return NULL; + } + + /* On attache le segment de mémoire partagé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) + { + sprintf (SM_Error_Msg, "SM_DSR_Manager NDD_CMD_VALUE_ALLOC : unable to attach the shared memory segment to the current process (error %d)", errno); + SM_Error_Print (); + + shmctl ((*DSH_Ptr_Ptr)->MemId, IPC_RMID, 0); + + ND_Desallocator_Exec( *DSH_Ptr_Ptr, MHH_Ptr->DSR->Desallocator_Name, MHH_Ptr->DSR->Desallocator_Ptr, NULL); + + return NULL; + } + + SM_Base->Attach = (*DSH_Ptr_Ptr)->Start; + + /* Initialisation des informations de l'entête */ + + (*DSH_Ptr_Ptr)->Size = Segment_Size; + + /* Création d'un chunk libre au début du segment de donné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 à la liste des chunks libres du heap */ + + if (ND_Index_Node_Add( MHH_Ptr->FCR, NDD_INDEX_PRIMARY, Chunk_Node) != NDS_OK) + { + sprintf (SM_Error_Msg, "SM_DSR_Manager NDD_CMD_VALUE_ALLOC : unable to add a first chunk to the FCR structure of heap \"%s\"", MHH_Ptr->Name); + SM_Error_Print (); + + shmctl ((*DSH_Ptr_Ptr)->MemId, IPC_RMID, 0); + + ND_Desallocator_Exec( (*DSH_Ptr_Ptr), MHH_Ptr->DSR->Desallocator_Name, MHH_Ptr->DSR->Desallocator_Ptr, NULL); + + return NULL; + } + return( NDS_OK); } @@ -3946,12 +4240,48 @@ NDT_Status SM_DSR_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node */ SMT_DSH *DSH_Ptr = (SMT_DSH *)va_arg( Args, SMT_DSH *); - + SMT_Status rc; Command_Name = "NDD_CMD_VALUE_FREE"; + + /* Destruction du segment de mémoire partagée du segment de données */ + + if (shmctl (DSH_Ptr->MemId, IPC_RMID, 0) == -1) + { + switch (errno) + { + case EPERM: + sprintf (SM_Error_Msg, "SM_DSR_Manager NDD_CMD_VALUE_FREE : current process (%d) is not allowed to destroy the shared memory segment %d", (int)getpid (), DSH_Ptr->MemId); + break; + + case EINVAL: + sprintf (SM_Error_Msg, "SM_DSR_Manager NDD_CMD_VALUE_FREE : no shared memory segment exists for identifier %d", DSH_Ptr->MemId); + break; + + default : + sprintf (SM_Error_Msg, "SM_DSR_Manager NDD_CMD_VALUE_FREE: unknown error %d while destroying the shared memory segment %d", errno, DSH_Ptr->MemId); + break; + } + + SM_Error_Print (); + + return SMS_ERRSHM; + } + + /* Désallocation de l'entête */ + + rc = ND_Desallocator_Exec( DSH_Ptr, Root_Ptr->Desallocator_Name, Root_Ptr->Desallocator_Ptr, NULL); + if (rc != NDS_OK) + { + sprintf (SM_Error_Msg, "SM_DSR_Manager NDD_CMD_VALUE_FREE : the data segment header is nul"); + SM_Error_Print (); + + return rc; + } + + return NDS_OK; - return( SM_DataSegment_End( Root_Ptr, DSH_Ptr)); } case NDD_CMD_VALUE_COMP: @@ -4112,181 +4442,6 @@ NDT_Status SM_DSR_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node } - - - -/*------------------------------------------------------------------------------*/ -/* Création d'un nouveau segment de données */ -/*------------------------------------------------------------------------------*/ - -SMT_DSH * SM_DataSegment_Init ( SMT_MHH * MHH, size_t Segment_Size) -{ - SMT_DSH * New_DSH; - NDT_Node * Chunk_Node; - SMT_Chunk * Chunk; - - /* On vérifie que le heap n'atteint pas sa limite */ - - if (MHH->Limit_Size != SMD_UNLIMITED) - { - size_t Current_Size; - - ND_DataStruct_Traverse (MHH->DSR, NDD_CMD_VALUE_SUM, (void *)&Current_Size); - - if (Current_Size + Segment_Size > MHH->Limit_Size) - { - sprintf (SM_Error_Msg, "SM_DataSegment_Init : the heap limit size would be exceeded"); - SM_Error_Print (); - - return NULL; - } - } - - /* Création de l'entête */ - - if( ND_Allocator_Exec( (void **)(&New_DSH), sizeof (SMT_DSH), MHH->DSR->Allocator_Name, MHH->DSR->Allocator_Ptr, NULL) != NDS_OK) - { - sprintf (SM_Error_Msg, "SM_DataSegment_Init : unable to allocate memory for the new data segment header"); - SM_Error_Print (); - - return NULL; - } - - /* Création d'un segment de mémoire partagée */ - - if ((New_DSH->MemId = shmget (IPC_PRIVATE, Segment_Size, 0777|IPC_CREAT|IPC_EXCL)) == -1) - { - switch (errno) - { - case EINVAL: - sprintf (SM_Error_Msg, "SM_DataSegment_Init : the size of the shared memory segment (%d) is out of the system-imposed bounds", Segment_Size); - break; - - case ENOMEM: - sprintf (SM_Error_Msg, "SM_DataSegment_Init : the amount of memory is not sufficient to create the shared memory segment"); - break; - - case ENOSPC: - sprintf (SM_Error_Msg, "SM_DataSegment_Init : the number of shared memory segments exceeds the system-imposed limit"); - break; - - default : - sprintf (SM_Error_Msg, "SM_DataSegment_Init : unknown error (%d) while creating a shared memory segment", errno); - break; - } - - SM_Error_Print (); - - ND_Desallocator_Exec( New_DSH, MHH->DSR->Desallocator_Name, MHH->DSR->Desallocator_Ptr, NULL); - - return NULL; - } - - /* On attache le segment de mémoire partagée au processus courant */ - - errno = 0; - New_DSH->Start = shmat (New_DSH->MemId, (void *)((size_t)(SM_Base->Attach) - Segment_Size), SHM_RND); - if (errno) - { - sprintf (SM_Error_Msg, "SM_DataSegment_Init : unable to attach the shared memory segment to the current process (error %d)", errno); - SM_Error_Print (); - - shmctl (New_DSH->MemId, IPC_RMID, 0); - - ND_Desallocator_Exec( New_DSH, MHH->DSR->Desallocator_Name, MHH->DSR->Desallocator_Ptr, NULL); - - return NULL; - } - - SM_Base->Attach = New_DSH->Start; - - /* Initialisation des informations de l'entête */ - - New_DSH->Size = Segment_Size; - - /* Création d'un chunk libre au début du segment de données */ - - Chunk_Node = (NDT_Node *)New_DSH->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 = New_DSH->Size - sizeof (NDT_Node) - sizeof (SMT_Chunk); - - /* Ajout du chunk libre à la liste des chunks libres du heap */ - - if (ND_Index_Node_Add( MHH->FCR, NDD_INDEX_PRIMARY, Chunk_Node) != NDS_OK) - { - sprintf (SM_Error_Msg, "SM_DataSegment_Init : unable to add a first chunk to the FCR structure of heap \"%s\"", MHH->Name); - SM_Error_Print (); - - shmctl (New_DSH->MemId, IPC_RMID, 0); - - ND_Desallocator_Exec( New_DSH, MHH->DSR->Desallocator_Name, MHH->DSR->Desallocator_Ptr, NULL); - - return NULL; - } - - return New_DSH; -} - - - - - -/*------------------------------------------------------------------------------*/ -/* Terminaison d'un segment de données */ -/*------------------------------------------------------------------------------*/ - -SMT_Status SM_DataSegment_End (NDT_Root * Root, SMT_DSH *DSH) -{ - SMT_Status rc; - - /* Destruction du segment de mémoire partagée du segment de données */ - - if (shmctl (DSH->MemId, IPC_RMID, 0) == -1) - { - switch (errno) - { - case EPERM: - sprintf (SM_Error_Msg, "SM_DataSegment_End : current process (%d) is not allowed to destroy the shared memory segment %d", (int)getpid (), DSH->MemId); - break; - - case EINVAL: - sprintf (SM_Error_Msg, "SM_DataSegment_End : no shared memory segment exists for identifier %d", DSH->MemId); - break; - - default : - sprintf (SM_Error_Msg, "SM_DataSegment_End : unknown error %d while destroying the shared memory segment %d", errno, DSH->MemId); - break; - } - - SM_Error_Print (); - - return SMS_ERRSHM; - } - - /* Désallocation de l'entête */ - - rc = ND_Desallocator_Exec( DSH, Root->Desallocator_Name, Root->Desallocator_Ptr, NULL); - if (rc != NDS_OK) - { - sprintf (SM_Error_Msg, "SM_DataSegment_End : the data segment header is nul"); - SM_Error_Print (); - - return rc; - } - - return SMS_OK; -} - - - - - /*------------------------------------------------------------------------------*/ /* Ouverture d'un segment de données */ /*------------------------------------------------------------------------------*/ @@ -4306,7 +4461,7 @@ SMT_Status SM_DataSegment_Open ( SMT_DSH *DSH) shmdt ((void *)DSH->Start); errno = 0; - Ptr = shmat (DSH->MemId, DSH->Start, 0); + Ptr = shmat( DSH->MemId, DSH->Start, 0); if (errno) { sprintf (SM_Error_Msg, "SM_DataSegment_Open : unable to attach the shared memory segment at the specified address %p (error %d)", DSH->Start, errno); @@ -4435,7 +4590,7 @@ NDT_Status SM_ACR_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node Command_Name = "NDD_CMD_MANAGER_VERSION"; - *Version_Name_Ptr = "$Revision: 2.2 $ $Name: $ $Date: 2005/02/23 23:31:06 $ $Author: agibert $"; + *Version_Name_Ptr = "$Revision: 2.3 $ $Name: $ $Date: 2005/06/26 22:50:49 $ $Author: agibert $"; return( NDS_OK); } @@ -4691,7 +4846,7 @@ NDT_Status SM_FCR_Manager( NDT_Root *Root_Ptr, NDT_Index_Id Index_Id, NDT_Node Command_Name = "NDD_CMD_MANAGER_VERSION"; - *Version_Name_Ptr = "$Revision: 2.2 $ $Name: $ $Date: 2005/02/23 23:31:06 $ $Author: agibert $"; + *Version_Name_Ptr = "$Revision: 2.3 $ $Name: $ $Date: 2005/06/26 22:50:49 $ $Author: agibert $"; return( NDS_OK); }