@@ -720,6 +720,117 @@ static umf_result_t os_allocation_merge(void *provider, void *lowPtr,
720
720
return UMF_RESULT_SUCCESS ;
721
721
}
722
722
723
+ typedef struct os_ipc_data_t {
724
+ int pid ;
725
+ int fd ;
726
+ size_t fd_offset ;
727
+ size_t size ;
728
+ } os_ipc_data_t ;
729
+
730
+ static umf_result_t os_get_ipc_handle_size (void * provider , size_t * size ) {
731
+ (void )provider ; // unused
732
+
733
+ if (size == NULL ) {
734
+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
735
+ }
736
+
737
+ * size = sizeof (os_ipc_data_t );
738
+ return UMF_RESULT_SUCCESS ;
739
+ }
740
+
741
+ static umf_result_t os_get_ipc_handle (void * provider , const void * ptr ,
742
+ size_t size , void * providerIpcData ) {
743
+ if (provider == NULL || ptr == NULL || providerIpcData == NULL ) {
744
+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
745
+ }
746
+
747
+ os_memory_provider_t * os_provider = (os_memory_provider_t * )provider ;
748
+ if (os_provider -> fd <= 0 ) {
749
+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
750
+ }
751
+
752
+ void * value = critnib_get (os_provider -> fd_offset_map , (uintptr_t )ptr );
753
+ if (value == NULL ) {
754
+ LOG_ERR ("os_get_ipc_handle(): getting a value from the IPC cache "
755
+ "failed (addr=%p)" ,
756
+ ptr );
757
+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
758
+ }
759
+
760
+ os_ipc_data_t * os_ipc_data = (os_ipc_data_t * )providerIpcData ;
761
+ os_ipc_data -> pid = os_getpid ();
762
+ os_ipc_data -> fd = os_provider -> fd ;
763
+ os_ipc_data -> fd_offset = (size_t )value - 1 ;
764
+ os_ipc_data -> size = size ;
765
+
766
+ return UMF_RESULT_SUCCESS ;
767
+ }
768
+
769
+ static umf_result_t os_put_ipc_handle (void * provider , void * providerIpcData ) {
770
+ if (provider == NULL || providerIpcData == NULL ) {
771
+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
772
+ }
773
+
774
+ os_memory_provider_t * os_provider = (os_memory_provider_t * )provider ;
775
+ os_ipc_data_t * os_ipc_data = (os_ipc_data_t * )providerIpcData ;
776
+
777
+ if (os_ipc_data -> fd != os_provider -> fd || os_ipc_data -> pid != os_getpid ()) {
778
+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
779
+ }
780
+
781
+ return UMF_RESULT_SUCCESS ;
782
+ }
783
+
784
+ static umf_result_t os_open_ipc_handle (void * provider , void * providerIpcData ,
785
+ void * * ptr ) {
786
+ if (provider == NULL || providerIpcData == NULL || ptr == NULL ) {
787
+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
788
+ }
789
+
790
+ os_memory_provider_t * os_provider = (os_memory_provider_t * )provider ;
791
+ os_ipc_data_t * os_ipc_data = (os_ipc_data_t * )providerIpcData ;
792
+ umf_result_t ret = UMF_RESULT_SUCCESS ;
793
+ int fd ;
794
+
795
+ umf_result_t umf_result =
796
+ os_duplicate_fd (os_ipc_data -> pid , os_ipc_data -> fd , & fd );
797
+ if (umf_result != UMF_RESULT_SUCCESS ) {
798
+ LOG_PERR ("duplicating file descriptor failed" );
799
+ return umf_result ;
800
+ }
801
+
802
+ * ptr = os_mmap (NULL , os_ipc_data -> size , os_provider -> protection ,
803
+ os_provider -> visibility , fd , os_ipc_data -> fd_offset );
804
+ if (* ptr == NULL ) {
805
+ os_store_last_native_error (UMF_OS_RESULT_ERROR_ALLOC_FAILED , errno );
806
+ LOG_PERR ("memory mapping failed" );
807
+ ret = UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC ;
808
+ }
809
+
810
+ (void )os_close_fd (fd );
811
+
812
+ return ret ;
813
+ }
814
+
815
+ static umf_result_t os_close_ipc_handle (void * provider , void * ptr ,
816
+ size_t size ) {
817
+ if (provider == NULL || ptr == NULL ) {
818
+ return UMF_RESULT_ERROR_INVALID_ARGUMENT ;
819
+ }
820
+
821
+ errno = 0 ;
822
+ int ret = os_munmap (ptr , size );
823
+ // ignore error when size == 0
824
+ if (ret && (size > 0 )) {
825
+ os_store_last_native_error (UMF_OS_RESULT_ERROR_FREE_FAILED , errno );
826
+ LOG_PERR ("memory unmapping failed" );
827
+
828
+ return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC ;
829
+ }
830
+
831
+ return UMF_RESULT_SUCCESS ;
832
+ }
833
+
723
834
static umf_memory_provider_ops_t UMF_OS_MEMORY_PROVIDER_OPS = {
724
835
.version = UMF_VERSION_CURRENT ,
725
836
.initialize = os_initialize ,
@@ -734,11 +845,11 @@ static umf_memory_provider_ops_t UMF_OS_MEMORY_PROVIDER_OPS = {
734
845
.ext .purge_force = os_purge_force ,
735
846
.ext .allocation_merge = os_allocation_merge ,
736
847
.ext .allocation_split = os_allocation_split ,
737
- .ipc .get_ipc_handle_size = NULL ,
738
- .ipc .get_ipc_handle = NULL ,
739
- .ipc .put_ipc_handle = NULL ,
740
- .ipc .open_ipc_handle = NULL ,
741
- .ipc .close_ipc_handle = NULL };
848
+ .ipc .get_ipc_handle_size = os_get_ipc_handle_size ,
849
+ .ipc .get_ipc_handle = os_get_ipc_handle ,
850
+ .ipc .put_ipc_handle = os_put_ipc_handle ,
851
+ .ipc .open_ipc_handle = os_open_ipc_handle ,
852
+ .ipc .close_ipc_handle = os_close_ipc_handle };
742
853
743
854
umf_memory_provider_ops_t * umfOsMemoryProviderOps (void ) {
744
855
return & UMF_OS_MEMORY_PROVIDER_OPS ;
0 commit comments