Здравствуйте, niXman, Вы писали:
X>так вот, я хочу переделать все эти обертки так, чтоб в каждой из них использовалась функция '__gthread_active_p()', но которая в своем теле будет производить проверку, на предмет подгружена ли winpthreads.dll, и если не подгружена — производить ее подгрузку и резолвить нужные символы. символы резолвится будут в некоторую структуру, мемберы которой и будут использоваться в обертках.
X> в качестве проверки флага думаю использовать атомарные операции.
Не стоит бросаться сразу использовать атомарные операции — подход
double check работает быстрее — будет лишь небольшая проверка при первом вызове (всё равно незаметная на фоне инициализации библиотеки), а все остальные вызовы даже атомарные операции для проверки использовать не будут — лишь одно неатомарное чтение флага, что всё же менее накладно.
X>да, я понимаю что это даст некоторую просадку в производительности из-за постоянной проверки некоторого флага.
X>в общем, что думаете об этом?
Да и без самого флага можно обойтись. Смотри, при загрузке библиотеки у тебя появляется переменная, куда сохраняется адрес функции. Соответственно, когда тебе нужно вызвать функцию, то происходит переход по адресу, записанному в этой переменной. И это по сути неуменьшаемые расходы по вызову функции из dll загруженных после старта программы (за исключением хаков вроде самодифицирующегося кода).
Так вот, обычно эта самая переменная с адресом функции не инициализирована при старте программы ничем интересным (там либо мусор, либо null). А ты просто запиши в неё указатель на функцию, делающую загрузку библиотеки:
using sched_yield_ptr = int (*)(void);
sched_yield_ptr sched_yield = sched_yield_delayed_load;
int sched_yield_delayed_load(void) {
delayed_load();
return sched_yield();
}
void delayed_load() {
mutex.lock();
load_pthread_library();
sched_yield = load_real_sched_yield();
pthread_self = load_real_pthread_self();
// и все остальные функции из pthread
mutex.unlock();
}
Теперь у тебя вызов функций (очевидно, за исключением первого) стоит столько же, сколько и обычный вызов функции из dll — никаких проверок флагов.
Также этот механизм уже доступен кое-где
из коробки, то есть без модификации исходного кода. Правда, в таких автоматических решениях иногда, как нас предупреждают, бывают проблемы с потоками и tls, так что на первый взгляд несколько опрометчиво было бы загружать pthreads через этот механизм, хотя может и будет работать.