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