@@ -11,7 +11,7 @@ pub(crate) struct Dispatcher {
1111
1212impl ToTokens for Dispatcher {
1313 fn to_tokens ( & self , tokens : & mut TokenStream ) {
14- let function_arguments = & self . signature . inputs . iter ( ) ;
14+ let function_arguments = self . signature . inputs . iter ( ) ;
1515 let argument_names = & self
1616 . signature
1717 . inputs
@@ -48,50 +48,41 @@ impl ToTokens for Dispatcher {
4848 let return_if_detected = self . functions . iter ( ) . map ( |( target, function) | {
4949 let target_arch = target. target_arch ( ) ;
5050 let features_detected = target. features_detected ( ) ;
51- let function_arguments = function_arguments. clone ( ) ;
52- let argument_names = argument_names. clone ( ) ;
5351 quote ! {
5452 #target_arch
5553 {
56- // wrap the function in an unsafe function with the same signature
57- unsafe fn unsafe_wrapper( #( #function_arguments) , * ) #returns {
58- #function( #( #argument_names) , * )
59- }
6054 if #features_detected {
61- return unsafe_wrapper
55+ return #function
6256 }
6357 }
6458 }
6559 } ) ;
6660 let default = & self . default ;
67- let function_arguments = function_arguments. clone ( ) ;
68- let argument_names = argument_names. clone ( ) ;
6961 quote ! {
7062 #( #return_if_detected) *
7163 #[ cfg( not( any( #( target_arch = #defaulted_arches) , * ) ) ) ]
7264 {
73- unsafe fn unsafe_wrapper( #( #function_arguments) , * ) #returns {
74- #default ( #( #argument_names) , * )
75- }
76- return unsafe_wrapper
65+ return #default
7766 }
7867 }
7968 } ;
8069 tokens. extend ( quote ! {
81- use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
70+ use std:: sync:: atomic:: { AtomicPtr , Ordering } ;
8271 type __fn_ty = unsafe fn ( #( #argument_ty) , * ) #returns;
8372 #[ cold]
8473 fn __get_fn( ) -> __fn_ty {
8574 #feature_detection
8675 }
87- static __DISPATCHED_FN : AtomicUsize = AtomicUsize :: new ( 0usize ) ;
88- let mut __current_ptr = __DISPATCHED_FN . load ( Ordering :: SeqCst ) ;
89- if __current_ptr == 0 {
90- __current_ptr = unsafe { std :: mem :: transmute ( __get_fn ( ) ) } ;
91- __DISPATCHED_FN . store ( __current_ptr , Ordering :: SeqCst ) ;
76+ # [ cold ]
77+ unsafe fn __resolver_fn ( # ( #function_arguments ) , * ) #returns {
78+ let __current_fn = __get_fn ( ) ;
79+ __DISPATCHED_FN . store ( __current_fn as * mut ( ) , Ordering :: SeqCst ) ;
80+ __current_fn ( # ( #argument_names ) , * )
9281 }
82+ static __DISPATCHED_FN: AtomicPtr <( ) > = AtomicPtr :: new( __resolver_fn as * mut ( ) ) ;
83+ let __current_ptr = __DISPATCHED_FN. load( Ordering :: SeqCst ) ;
9384 unsafe {
94- let __current_fn = std:: mem:: transmute:: <usize , __fn_ty>( __current_ptr) ;
85+ let __current_fn = std:: mem:: transmute:: <* mut ( ) , __fn_ty>( __current_ptr) ;
9586 __current_fn( #( #argument_names) , * )
9687 }
9788 } ) ;
0 commit comments