На самом деле существовала NGPT-библиотека потоков для linux, которая использует не текущую модель потоков 1: 1 (каждый пользовательский поток является потоком ядра или LWP), а модель потоков M: N (несколько пользовательских потоков соответствуютдругое, меньшее количество потоков ядра).
Согласно ftp: //ftp.uni-duisburg.de/Linux/NGPT/ngpt-0.9.4.tar.gz/ngpt-0.9.4 / pth_sched.c: 170 pth_scheduler было возможно перемещать контексты пользовательских потоков между собственными потоками (ядра):
/*
* See if the thread is unbound...
* Break out and schedule if so...
*/
if (current->boundnative == 0)
break;
/*
* See if the thread is bound to a different native thread...
* Break out and schedule if not...
*/
if (current->boundnative == this_sched->lastrannative)
break;
Для сохранения и восстановления пользовательских потоков можно использовать ucontext ftp://ftp.uni-duisburg.de/Linux/NGPT/ngpt-0.9.4.tar.gz/ngpt-0.9.4/pth_mctx.c:64 и, похоже, это был предпочтительный метод (mcsc
):
/*
* save the current machine context
*/
#if PTH_MCTX_MTH(mcsc)
#define pth_mctx_save(mctx) \
( (mctx)->error = errno, \
getcontext(&(mctx)->uc) )
#elif
....
/*
* restore the current machine context
* (at the location of the old context)
*/
#if PTH_MCTX_MTH(mcsc)
#define pth_mctx_restore(mctx) \
( errno = (mctx)->error, \
(void)setcontext(&(mctx)->uc) )
#elif PTH_MCTX_MTH(sjlj)
...
#if PTH_MCTX_MTH(mcsc)
/*
* VARIANT 1: THE STANDARDIZED SVR4/SUSv2 APPROACH
*
* This is the preferred variant, because it uses the standardized
* SVR4/SUSv2 makecontext(2) and friends which is a facility intended
* for user-space context switching. The thread creation therefore is
* straight-foreward.
*/
Таким образом, даже если NGPT мертв и не используется, он выбрал * context () для переключения пользовательских потоков даже между потоками ядра.Я предполагаю, что использование семейства * context () достаточно безопасно в Linux.
При смешивании ucontexts и других библиотек нативных потоков могут возникнуть некоторые проблемы.Я рассмотрю NPTL, которая является стандартной нативной библиотекой потоков linux начиная с glibc 2.4.Основная проблема - THREAD_SELF - указатель на struct pthread
текущего потока.TLS (Thread-local storage) также работает через THREAD_SELF.THREAD_SELF обычно сохраняется в регистре ( r2 на powerpc , %gs
на x86 и т. Д.).get / setcontext может сохранять и восстанавливать этот регистр, нарушая внутреннее содержимое нативной библиотеки pthread (например, локальное хранилище потока, идентификация потока и т. д.). * glibc setcontext не будет сохранять / восстанавливать %gs
register для совместимости с pthreads:
/* Restore the FS segment register. We don't touch the GS register
since it is used for threads. */
movl oFS(%eax), %ecx
movw %cx, %fs
Вы должны проверить, сохраняет ли setcontext регистр THREAD_SELF в интересующей вас архитектуре. Кроме того, ваш код может не переноситься между операционными системами и libc
s.