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