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