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