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

📄 vxworks.cc

📁 编译工具
💻 CC
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////////////// Filename:	 vxWorks.cc// Author:		Tihomir Sokcevic//					Acterna, Eningen.// Description: vxWorks adaptation of the omnithread wrapper classes// Notes:		 Munching strategy is imperative//////////////////////////////////////////////////////////////////////////////// $Log: vxWorks.cc,v $// Revision 1.1.2.6  2005/09/19 15:02:11  dgrisby// Updated vxWorks omnithread options. Thanks Dirk Siebnich.//// Revision 1.1.2.5  2005/07/06 12:25:55  dgrisby// Per thread data changes from April meant main thread's data was leaked.//// Revision 1.1.2.4  2005/04/25 18:16:24  dgrisby// Always release per thread data in the thread it belongs to.//// Revision 1.1.2.3  2004/04/30 15:01:25  dgrisby// Fix to dummy thread on vxWorks. Thanks Gary Block.//// Revision 1.1.2.2  2003/11/05 15:42:39  dgrisby// vxWorks omnithread fixes from Jochen Gern.//// Revision 1.2  2003/11/05 11:05:38  gernjo// In omni_condition, removed task synchronization via the waiters_ variable. Instead, in signal() re-take the semaphore after signaling. Changed stack size to 60000 due to enhanced stack requirements of release code.//// Revision 1.1.1.1  2003/10/20 10:15:50  gernjo// Original distribution//// Revision 1.1.2.1  2003/02/17 02:03:11  dgrisby// vxWorks port. (Thanks Michael Sturm / Acterna Eningen GmbH).//// Revision 1.1.1.1  2002/11/19 14:58:04  sokcevti// OmniOrb4.0.0 VxWorks port//// Revision 1.4  2002/10/15 07:54:09  kuttlest// change semaphore from SEM_FIFO to SEM_PRIO// ---//// Revision 1.3  2002/07/05 07:38:52  engeln// made priority redefinable on load time by defining int variables// 	omni_thread_prio_low = 220;// 	omni_thread_prio_normal = 110;// 	omni_thread_prio_high = 55;// the default priority is prio_normal.// The normal priority default has been increased from 200 to 110 and the//     high priority from 100 to 55.// ---//// Revision 1.2  2002/06/14 12:44:57  engeln// replaced possibly unsafe wakeup procedure in broadcast.// ---//// Revision 1.1.1.1  2002/04/02 10:09:34  sokcevti// omniORB4 initial realease//// Revision 1.0	2001/10/23 14:22:45	sokcevti// Initial Version 4.00// ---//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Include files//////////////////////////////////////////////////////////////////////////////#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <time.h>#include <omnithread.h>#include <sysLib.h>#include <assert.h>		// assert#include <intLib.h>		// intContext//////////////////////////////////////////////////////////////////////////////// Local defines//////////////////////////////////////////////////////////////////////////////#define ERRNO(x) (((x) != 0) ? (errno) : 0)#define THROW_ERRORS(x) { if((x) != OK) throw omni_thread_fatal(errno); }#define OMNI_THREAD_ID	0x7F7155AAl#define OMNI_STACK_SIZE 60000l#ifdef _DEBUG	#include <fstream>	#define DBG_TRACE(X) X#else // _DEBUG	#define DBG_TRACE(X)#endif // _DEBUG#define DBG_ASSERT(X)#define DBG_THROW(X) Xint omni_thread_prio_low = 220;int omni_thread_prio_normal = 110;int omni_thread_prio_high = 55;/////////////////////////////////////////////////////////////////////////////// Mutex/////////////////////////////////////////////////////////////////////////////omni_mutex::omni_mutex(void):m_bConstructed(false){	mutexID = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE);	DBG_ASSERT(assert(mutexID != NULL));	if(mutexID==NULL)	{		DBG_TRACE(cout<<"Exception: omni_mutex::omni_mutex()  tid: "<<(int)taskIdSelf()<<endl);		DBG_THROW(throw omni_thread_fatal(-1));	}	m_bConstructed = true;}omni_mutex::~omni_mutex(void){	m_bConstructed = false;	STATUS status = semDelete(mutexID);	DBG_ASSERT(assert(status == OK));	if(status != OK)	{		DBG_TRACE(cout<<"Exception: omni_mutex::~omni_mutex()  mutexID: "<<(int)mutexID<<" tid: "<<(int)taskIdSelf()<<endl);		DBG_THROW(throw omni_thread_fatal(errno));	}}/*void omni_mutex::lock(void){	DBG_ASSERT(assert(!intContext()));		// not in ISR context	DBG_ASSERT(assert(m_bConstructed));	STATUS status = semTake(mutexID, WAIT_FOREVER);	DBG_ASSERT(assert(status == OK));	if(status != OK)	{		DBG_TRACE(cout<<"Exception: omni_mutex::lock()  mutexID: "<<(int)mutexID<<" tid: "<<(int)taskIdSelf()<<endl);		DBG_THROW(throw omni_thread_fatal(errno));	}}void omni_mutex::unlock(void){	DBG_ASSERT(assert(m_bConstructed));	STATUS status = semGive(mutexID);	DBG_ASSERT(assert(status == OK));	if(status != OK)	{		DBG_TRACE(cout<<"Exception: omni_mutex::unlock()  mutexID: "<<(int)mutexID<<" tid: "<<(int)taskIdSelf()<<endl);		DBG_THROW(throw omni_thread_fatal(errno));	}}*//////////////////////////////////////////////////////////////////////////////// Condition variable/////////////////////////////////////////////////////////////////////////////omni_condition::omni_condition(omni_mutex* m) : mutex(m){	DBG_TRACE(cout<<"omni_condition::omni_condition  mutexID: "<<(int)mutex->mutexID<<" tid:"<<(int)taskIdSelf()<<endl);	sema_ = semCCreate(SEM_Q_PRIORITY, 0);	if(sema_ == NULL)	{		DBG_TRACE(cout<<"Exception: omni_condition::omni_condition()  tid: "<<(int)taskIdSelf()<<endl);		DBG_THROW(throw omni_thread_fatal(errno));	}}omni_condition::~omni_condition(void){	STATUS status = semDelete(sema_);	DBG_ASSERT(assert(status == OK));	if(status != OK)	{		DBG_TRACE(cout<<"Exception: omni_condition::~omni_condition"<<endl);		DBG_THROW(throw omni_thread_fatal(errno));	}}void omni_condition::wait(void){	STATUS status = OK;	taskLock();	// disable task switch until semTake				// else a broadcast may not wakeup				// this waiting thread	mutex->unlock();		// release mutex	status = semTake(sema_, WAIT_FOREVER);		// wait at semaphore for a signal or broadcast	taskUnlock();		// reenable task switch	DBG_ASSERT(assert(status == OK));	if(status != OK)	{		DBG_TRACE(cout<<"Exception: omni_condition::wait"<<endl);		DBG_THROW(throw omni_thread_fatal(errno));	}	mutex->lock();		// get owner of mutex before return}// The time given is absolute. Return 0 is timeoutint omni_condition::timedwait(unsigned long secs, unsigned long nanosecs){	STATUS result = OK;	timespec now;	unsigned long timeout;	int ticks;	clock_gettime(CLOCK_REALTIME, &now);	if(((unsigned long)secs <= (unsigned long)now.tv_sec) &&		(((unsigned long)secs < (unsigned long)now.tv_sec) ||		(nanosecs < (unsigned long)now.tv_nsec)))		timeout = 0;	else		timeout = (secs-now.tv_sec) * 1000 + (nanosecs-now.tv_nsec) / 1000000l;	// disable task lock to have an atomic unlock+semTake	taskLock();	// We keep the lock held just long enough to increment the count	// of waiters by one.	mutex->unlock();	// Wait to be awakened by a signal() or broadcast().	ticks = (timeout * sysClkRateGet()) / 1000L;	result = semTake(sema_, ticks);	// reenable task rescheduling	taskUnlock();	// We must always regain the <external_mutex>, even when errors	// occur because that's the guarantee that we give to our callers.	mutex->lock();	if(result!= OK) // timeout		return 0;	return 1;}void omni_condition::signal(void){	DBG_TRACE(cout<<"omni_condition::signal          mutexID: "<<(int)mutex->mutexID<<" tid:"<<(int)taskIdSelf()<<endl);	STATUS status = semGive(sema_);	DBG_ASSERT(assert(status == OK));	if(status != OK)	{		DBG_TRACE(cout<<"Exception: omni_condition::signal"<<endl);		DBG_THROW(throw omni_thread_fatal(errno));	}        // take unread message if no thread was waiting    semTake(sema_, NO_WAIT);}void omni_condition::broadcast(void){	DBG_TRACE(cout<<"omni_condition::broadcast       mutexID: "<<(int)mutex->mutexID<<" tid:"<<(int)taskIdSelf()<<endl);	// Wake up all the waiters.	STATUS status = semFlush(sema_);	DBG_ASSERT(assert(status == OK));	if(status != OK)	{		DBG_TRACE(cout<<"omni_condition::broadcast1! - thread:"<<omni_thread::self()->id()<<" SemID:"<<(int)sema_<<" errno:"<<errno<<endl);		DBG_THROW(throw omni_thread_fatal(errno));	}}/////////////////////////////////////////////////////////////////////////////// Counting semaphore/////////////////////////////////////////////////////////////////////////////omni_semaphore::omni_semaphore(unsigned int initial){	DBG_ASSERT(assert(0 <= (int)initial));		// POSIX expects only unsigned init values	semID = semCCreate(SEM_Q_PRIORITY, (int)initial);	DBG_ASSERT(assert(semID!=NULL));	if(semID==NULL)	{		DBG_TRACE(cout<<"Exception: omni_semaphore::omni_semaphore"<<endl);		DBG_THROW(throw omni_thread_fatal(-1));	}}omni_semaphore::~omni_semaphore(void){	STATUS status = semDelete(semID);	DBG_ASSERT(assert(status == OK));	if(status != OK)	{		DBG_TRACE(cout<<"Exception: omni_semaphore::~omni_semaphore"<<endl);		DBG_THROW(throw omni_thread_fatal(errno));	}}void omni_semaphore::wait(void){	DBG_ASSERT(assert(!intContext()));		// no wait in ISR	STATUS status = semTake(semID, WAIT_FOREVER);	DBG_ASSERT(assert(status == OK));	if(status != OK)	{		DBG_TRACE(cout<<"Exception: omni_semaphore::wait"<<endl);		DBG_THROW(throw omni_thread_fatal(errno));	}}int omni_semaphore::trywait(void){	STATUS status = semTake(semID, NO_WAIT);	DBG_ASSERT(assert(status == OK));	if(status != OK)	{		if(errno == S_objLib_OBJ_UNAVAILABLE)		{			return 0;		}		else		{			DBG_ASSERT(assert(false));			DBG_TRACE(cout<<"Exception: omni_semaphore::trywait"<<endl);			DBG_THROW(throw omni_thread_fatal(errno));		}	}	return 1;}void omni_semaphore::post(void){	STATUS status = semGive(semID);	DBG_ASSERT(assert(status == OK));	if(status != OK)	{		DBG_TRACE(cout<<"Exception: omni_semaphore::post"<<endl);		DBG_THROW(throw omni_thread_fatal(errno));	}}/////////////////////////////////////////////////////////////////////////////// Thread///////////////////////////////////////////////////////////////////////////////// static variables//omni_mutex* omni_thread::next_id_mutex = 0;int omni_thread::next_id = 0;// omniORB requires a larger stack size than the default (21120) on OSF/1static size_t stack_size = OMNI_STACK_SIZE;//// Initialisation function (gets called before any user code).//static int& count() {  static int the_count = 0;  return the_count;}omni_thread::init_t::init_t(void){	// Only do it once however many objects get created.	if(count()++ != 0)		return;	attach();}omni_thread::init_t::~init_t(void){    if (--count() != 0) return;    omni_thread* self = omni_thread::self();    if (!self) return;    taskTcb(taskIdSelf())->spare1 = 0;    delete self;    delete next_id_mutex;}//// Wrapper for thread creation.//extern "C" void omni_thread_wrapper(void* ptr){	omni_thread* me = (omni_thread*)ptr;	DBG_TRACE(cout<<"omni_thread_wrapper: thread "<<me->id()<<" started\n");	//	// We can now tweaked the task info since the tcb exist now	//	me->mutex.lock();	// To ensure that start has had time to finish	taskTcb(me->tid)->spare1 = OMNI_THREAD_ID;	taskTcb(me->tid)->spare2 = (int)ptr;	me->mutex.unlock();	//	// Now invoke the thread function with the given argument.	//	if(me->fn_void != NULL)	{		(*me->fn_void)(me->thread_arg);		omni_thread::exit();	}	if(me->fn_ret != NULL)	{		void* return_value = (*me->fn_ret)(me->thread_arg);		omni_thread::exit(return_value);	}	if(me->detached)	{		me->run(me->thread_arg);		omni_thread::exit();	}	else	{		void* return_value = me->run_undetached(me->thread_arg);		omni_thread::exit(return_value);	}}//// Special functions for VxWorks only//void omni_thread::attach(void){	DBG_TRACE(cout<<"omni_thread_attach: VxWorks mapping thread initialising\n");	int _tid = taskIdSelf();	// Check the task is not already attached	if(taskTcb(_tid)->spare1 == OMNI_THREAD_ID)		return;	// Create the mutex required to lock the threads debugging id (create before the thread!!!)	if(next_id_mutex == 0)		next_id_mutex = new omni_mutex;	// Create a thread object for THIS running process	omni_thread* t = new omni_thread;	// Lock its mutex straigh away!

⌨️ 快捷键说明

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