⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gthreads.c

📁 T-kernel 的extension源代码
💻 C
字号:
/* *---------------------------------------------------------------------- *    T-Kernel / Standard Extension * *    Copyright (C) 2006 by Ken Sakamura. All rights reserved. *    T-Kernel / Standard Extension is distributed  *      under the T-License for T-Kernel / Standard Extension. *---------------------------------------------------------------------- * *    Version:   1.00.00 *    Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/11. * *---------------------------------------------------------------------- *//* *	gthreads.c (libtkse) * *	Multi-thread support routine for "gcc"'s exclusive use */#include <basic.h>#include <tk/tkernel.h>#include <sys/libs.h>#include <extension/errno.h>#include "gthreads.h"LOCAL int thread_mutex_init( long *mutex );LOCAL int thread_mutex_lock( long *mutex );LOCAL int thread_mutex_unlock( long *mutex );LOCAL void thread_mutex_setup( void );LOCAL int thread_key_create( long *keyp, void (*destructor)(void*) );LOCAL int thread_key_set( long key, void *value );LOCAL int thread_key_get( long key, void **valuep );LOCAL void thread_key_setup( void );LOCAL int thread_once( long *once_block, void (*init_routine)() );LOCAL int _1st_thread_once( long *once_block, void (*init_routine)() );#define TSD_TKC_RTN_M1	(-1)/*  * Lock uses the common and single library shared lock in the processing of "mutex" , * once_block, and user information. *  * It is based on the following assumption. *	- Use "_thread_once" in calling(invoking) "_thread_mutex_init" and  *         "_thread_key_create". * 	   	libgcc2.c:eh_context_initialize(),  * 	  	frame.c:init_object_mutex_once() *	- Exclude "_thread_key_create()" at caller. *	- "_thread_key_set()" and "_thread_key_get()" are not used together with "mutex"  *        and once_block. *	- Initialize only one "mutex" * 	   ("_thread_mutex_lock()" and "_thread_mutex_unlock()" are not used by nesting) * These are truths in implementing "gcc2.95.2" *//* ------------------------------------------------------------------------ *//* *	Mutex * *	Use a single lock since only one mutex is requested in implementing "gcc2.95.2". *//* * Initialize the mutex *	Return value	0:normal  <0:error */LOCAL int thread_mutex_init( long *mutex ){	return 0;}/* * Lock the mutex *	Return value	0:normal  <0:error */LOCAL int thread_mutex_lock( long *mutex ){	return _lib_lock(_LL_GCC, TRUE);}/* * Unlock the mutex *	Return value	0:normal  <0:error */LOCAL int thread_mutex_unlock( long *mutex ){	_lib_unlock(_LL_GCC);	return 0;}/* * Setup-processing at first call. *	Execute the setup at first call of "thread_once()"on the assumption that it is used *      in combination with "thread_once()". *//* Multi-thread-compliant */LOCAL void thread_mutex_setup( void ){	if ( _isUseMT() != 0 ) {		/* Multi-thread-compliant */		_thread_mutex_lock   = thread_mutex_lock;		_thread_mutex_unlock = thread_mutex_unlock;		_thread_mutex_init   = thread_mutex_init;	} else {		/* Non-multi-thread-compliant */		_thread_mutex_lock   = NULL;		_thread_mutex_unlock = NULL;		_thread_mutex_init   = NULL;	}}EXPORT int (*_thread_mutex_init)();EXPORT int (*_thread_mutex_lock)();EXPORT int (*_thread_mutex_unlock)();/* ------------------------------------------------------------------------ *//* *	Thread-specific information *//* * Create the key *	Create the area to store the thread-specific information, and the key to refer to the area. *	Call "destructor" when exiting thread, and discard the value set to the key. *	Return value   0:normal  <0:error */LOCAL int thread_key_create( long *keyp, void (*destructor)(void*) ){	ID	keyid;	keyid = _CreateLibCtxKey(destructor);	if ( keyid < E_OK ) {		return TSD_TKC_RTN_M1;	}	*keyp = keyid;	return 0;}/* * Set the value to key *	Set the value to the thread-specific information indicated by key. *	Return value   0:normal  <0:error */LOCAL int thread_key_set( long key, void *value ){	return _SetLibCtx(key, value);}/* * Refer to the value of key *	Refer to the value from the thread-specific information indicated by key *	Return value	0:normal  <0:error */LOCAL int thread_key_get( long key, void **valuep ){	return _GetLibCtx(key, valuep);}/* * Setup-processing at first call *	Execute a setup at the first call of "thread_once()"on the assumption that it is used *      in combination with "thread_once()". */LOCAL void thread_key_setup( void ){	if ( _isUseMT() != 0 ) {		/* Multi-thread-compliant */		_thread_key_create = thread_key_create;		_thread_key_set    = thread_key_set;		_thread_key_get    = thread_key_get;	} else {		/* Non-multi-thread-compliant */		_thread_key_create = NULL;		_thread_key_set    = NULL;		_thread_key_get    = NULL;	}}EXPORT int (*_thread_key_create)();EXPORT int (*_thread_key_set)();EXPORT int (*_thread_key_get)();/* ------------------------------------------------------------------------ *//* *	Once_block *//* * Once_block *	Exclusively execute "init_routine" only once. *	Use "once_block" as the already executed flag. *	Return value	0:normal <0:error */LOCAL int thread_once( long *once_block, void (*init_routine)() ){	if ( *once_block == (long)0 ) {		(void)_lib_lock(_LL_GCC, TRUE);		if ( *once_block == (long)0 ) {			(*init_routine)();			*once_block = 1;		}		_lib_unlock(_LL_GCC);	}	return 0;}/* * Setup-processing at first call */LOCAL int _1st_thread_once( long *once_block, void (*init_routine)() ){	(void)_lib_lock(_LL_GCC, TRUE);	/* Set up "once_block" */	if ( _isUseMT() != 0 ) {		/* Multi-task-compliant */		_thread_once = thread_once;	} else {		/* Non-multi-task-compliant */		_thread_once = NULL;	}	/* Set up mutex */	thread_mutex_setup();	/* Set up "thread_key" */	thread_key_setup();	_lib_unlock(_LL_GCC);	return thread_once(once_block, init_routine);}EXPORT int (*_thread_once)() = _1st_thread_once;/* ------------------------------------------------------------------------ */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -