1 /* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifdef USE_MUTEX_WAIT_OPT 17 #include <unistd.h> 18 #include <signal.h> 19 #include <stdlib.h> 20 #include <limits.h> 21 #include <dlfcn.h> 22 #include <errno.h> 23 #include <ctype.h> 24 #include <assert.h> 25 #include <string.h> 26 #include <stdio.h> 27 #include <pthread.h> 28 #include "musl_log.h" 29 #include "musl_opt.h" 30 #include "atomic.h" 31 default_initialize_func()32bool default_initialize_func() 33 { 34 return false; 35 } 36 default_lock_func(pthread_mutex_t * restrict m)37void default_lock_func(pthread_mutex_t *restrict m) 38 { 39 int spins = 100; 40 while (spins-- && m->_m_lock && !m->_m_waiters) a_spin(); 41 } 42 43 static char *__musl_opt_hook_shared_lib = "lib_kccllockopt.so"; 44 long long __ohos_musl_opt_hook_shared_library = NULL; 45 typedef bool (*initialize_func_type)(); 46 initialize_func_type initialize_func = default_initialize_func; 47 lock_func_type lock_func = default_lock_func; 48 init_musl_opt_hook_shared_library(void * shared_library_handle)49static bool init_musl_opt_hook_shared_library(void *shared_library_handle) 50 { 51 initialize_func_type pfunc_initialize = (initialize_func_type)dlsym(shared_library_handle, "musl_opt_initialize"); 52 lock_func_type pfunc_lock = (lock_func_type)dlsym(shared_library_handle, "musl_opt_lock"); 53 if (pfunc_initialize == NULL || pfunc_lock == NULL) { 54 return false; 55 } 56 initialize_func = pfunc_initialize; 57 lock_func = pfunc_lock; 58 return true; 59 } 60 load_musl_opt_hook_shared_library()61static void* load_musl_opt_hook_shared_library() 62 { 63 void* shared_library_handle = NULL; 64 65 shared_library_handle = dlopen(__musl_opt_hook_shared_lib, RTLD_NOW | RTLD_LOCAL); 66 67 if (shared_library_handle == NULL) { 68 return NULL; 69 } 70 71 if (!init_musl_opt_hook_shared_library(shared_library_handle)) { 72 dlclose(shared_library_handle); 73 shared_library_handle = NULL; 74 } 75 return shared_library_handle; 76 } 77 init_musl_opt_hook()78static void init_musl_opt_hook() 79 { 80 bool enable = initialize_func(); 81 if (!enable) { 82 lock_func = default_lock_func; 83 } 84 } 85 __musl_opt_initialize()86__attribute__((constructor())) static void __musl_opt_initialize() 87 { 88 void *shared_library_handle = (void *)__ohos_musl_opt_hook_shared_library; 89 if (shared_library_handle != NULL && shared_library_handle != (void *)-1) { 90 return; 91 } 92 shared_library_handle = load_musl_opt_hook_shared_library(); 93 if (shared_library_handle == NULL) { 94 initialize_func = default_initialize_func; 95 lock_func = default_lock_func; 96 } 97 98 init_musl_opt_hook(); 99 __ohos_musl_opt_hook_shared_library = (long long)shared_library_handle; 100 } 101 102 #endif