Определение версии ОС и выбор функций потоков - PullRequest
0 голосов
/ 13 июня 2011

Есть ли хороший способ проверить версию ОС (в данном случае Windows Vista + или нет) и решить во время выполнения, какую версию функции планируется использовать.

Конкретно я говорю о реализации pthreadsв Win32 темы.В моем идеальном случае библиотека pthreads будет определять при запуске программы, какая ОС работает.Если это Vista +, все вызовы функций будут перенаправлены на новые крутые и быстрые функции, в противном случае будет использоваться старый слой эмуляции.

Таким образом, в действительности библиотека будет иметь две версии каждой функции, однуновый и один старый.И одноразовая проверка во время выполнения будет определять во время выполнения, прежде чем программа войдет в main, так сказать, какую версию она будет использовать.Я знаю, что есть библиотеки, которые обнаруживают функции ЦП, такие как SSE во время выполнения, и используют соответствующие функции, но я думаю, что они проверяют при каждом вызове функции.Это было бы слишком дорого, чтобы сделать это в низкоуровневой библиотеке потоков IMO.

Возможно ли это?Можно ли, так сказать, «перекомпоновывать» / перенаправлять вызовы функций во время выполнения?

РЕДАКТИРОВАТЬ: для этого возможны такие сумасшедшие вещи, как пользовательский код запуска crt (я говорю о winpthreads для mingw-w64, который предоставляет свой собственныйкод запуска)

1 Ответ

1 голос
/ 13 июня 2011

Простой ответ? Определите и создайте диспетчерскую таблицу / структуру для вашей библиотеки. Примерно так:

// Define function pointers and dispatch structure.
typedef void( *PFN_pthread_exit )( void *value_ptr );
typedef struct tag_PTHREAD_IMPL
{
    PFN_pthread_create ptr_pthread_exit;
    // Add the rest rest here.
} PTHREAD_IMPL;

// Define your various implementations dispatcher structures.
static PTHREAD_IMPL legacy_impl = { 
    &legacy_pthread_exit_impl
};
static PTHREAD_IMPL latest_andgreatest_impl = { 
    &pthread_exit_impl
};
static PTHREAD_IMPL* s_pImpl = NULL;

Далее, функция инициализации вашей библиотеки должна содержать что-то вроде этого:

int StaticInitialize( )
{
    // Initalize dispatcher
    if( latest and greatest OS version )
        s_pImpl = &latest_andgreatest_impl
    else
        s_pImpl = &legacy_impl;
}

Наконец, экспортируемые из вашей библиотеки функции должны выглядеть примерно так:

int pthread_exit( void *value_ptr )
{
    ASSERT( s_pImpl );
    ASSERT( s_pImpl->ptr_pthread_exit );
    return s_pImpl->ptr_pthread_exit( value_ptr );
}

Естественно, вам необходимо убедиться, что в ваших современных реализациях используется привязка во время выполнения для экспорта, которого нет на устаревших платформах.

Веселись!

...