Re: высскажитесь о реализации
От: watchmaker  
Дата: 03.10.14 11:00
Оценка: 25 (3) +1
Здравствуйте, 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 через этот механизм, хотя может и будет работать.
Отредактировано 03.10.2014 11:38 watchmaker . Предыдущая версия . Еще …
Отредактировано 03.10.2014 11:36 watchmaker . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.