• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()32 bool default_initialize_func()
33 {
34     return false;
35 }
36 
default_lock_func(pthread_mutex_t * restrict m)37 void 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)49 static 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()61 static 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()78 static 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