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

📄 vxworks.cc

📁 编译工具
💻 CC
📖 第 1 页 / 共 2 页
字号:
	omni_mutex_lock l(t->mutex);	// Adjust data members of this instance	t->_state = STATE_RUNNING;	t->tid = taskIdSelf();	// Set the thread values so it can be recongnised as a omni_thread	// Set the id last can possibly prevent race condition	taskTcb(t->tid)->spare2 = (int)t;	taskTcb(t->tid)->spare1 = OMNI_THREAD_ID;	// Create the running_mutex at this stage, but leave it empty. We are not running	//	in the task context HERE, so taking it would be disastrous.	t->running_cond = new omni_condition(&t->mutex);}void omni_thread::detach(void){	DBG_TRACE(cout<<"omni_thread_detach: VxWorks detaching thread mapping\n");	int _tid = taskIdSelf();	// Check the task has a OMNI_THREAD attached	if(taskTcb(_tid)->spare1 != OMNI_THREAD_ID)		return;	// Invalidate the id NOW !	taskTcb(_tid)->spare1 = 0;	// Even if NULL, it is safe to delete the thread	omni_thread* t = (omni_thread*)taskTcb(_tid)->spare2;	// Fininsh cleaning the tcb structure	taskTcb(_tid)->spare2 = 0;	delete t;}//// Constructors for omni_thread - set up the thread object but don't// start it running.//// construct a detached thread running a given function.omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri){	common_constructor(arg, pri, 1);	fn_void = fn;	fn_ret = NULL;}// construct an undetached thread running a given function.omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri){	common_constructor(arg, pri, 0);	fn_void = NULL;	fn_ret = fn;}// construct a thread which will run either run() or run_undetached().omni_thread::omni_thread(void* arg, priority_t pri){	common_constructor(arg, pri, 1);	fn_void = NULL;	fn_ret = NULL;}// common part of all constructors.void omni_thread::common_constructor(void* arg, priority_t pri, int det){	_state = STATE_NEW;	_priority = pri;	// Set the debugging id	next_id_mutex->lock();	_id = next_id++;	next_id_mutex->unlock();	// Note : tid can only be setup when the task is up and running	tid = 0;	thread_arg = arg;	detached = det;		// may be altered in start_undetached()    _dummy       = 0;    _values      = 0;    _value_alloc = 0;}//// Destructor for omni_thread.//omni_thread::~omni_thread(void){    DBG_TRACE(cout<<"omni_thread::~omni_thread for thread "<<id()<<endl);    if (_values) {        for (key_t i=0; i < _value_alloc; i++) {          if (_values[i]) {              delete _values[i];          }        }      delete [] _values;    }    // glblock -- added this to prevent problem with unitialized running_cond    if(running_cond)      {        delete running_cond;      }}//// Start the thread//void omni_thread::start(void){	omni_mutex_lock l(mutex);	DBG_ASSERT(assert(_state == STATE_NEW));	if(_state != STATE_NEW)		DBG_THROW(throw omni_thread_invalid());	// Allocate memory for the task. (The returned id cannot be trusted by the task)	tid = taskSpawn(		NULL,				// Task name		vxworks_priority(_priority),	// Priority		VX_FP_TASK | VX_NO_STACK_FILL,	// Option		stack_size,			// Stack size		(FUNCPTR)omni_thread_wrapper,	// Entry point		(int)this,			// First argument is this		0,0,0,0,0,0,0,0,0		// Remaining unused args		);	DBG_ASSERT(assert(tid!=ERROR));	if(tid==ERROR)		DBG_THROW(throw omni_thread_invalid());	_state = STATE_RUNNING;	// Create the running_mutex at this stage, but leave it empty. We are not running	//	in the task context HERE, so taking it would be disastrous.	running_cond = new omni_condition(&mutex);}//// Start a thread which will run the member function run_undetached().//void omni_thread::start_undetached(void){	DBG_ASSERT(assert(!((fn_void != NULL) || (fn_ret != NULL))));	if((fn_void != NULL) || (fn_ret != NULL))		DBG_THROW(throw omni_thread_invalid());	detached = 0;	start();}//// join - Wait for the task to complete before returning to the calling process//void omni_thread::join(void** status){	mutex.lock();	if((_state != STATE_RUNNING) && (_state != STATE_TERMINATED))	{		mutex.unlock();		DBG_ASSERT(assert(false));		DBG_THROW(throw omni_thread_invalid());	}	mutex.unlock();	DBG_ASSERT(assert(this != self()));	if(this == self())		DBG_THROW(throw omni_thread_invalid());	DBG_ASSERT(assert(!detached));	if(detached)		DBG_THROW(throw omni_thread_invalid());	mutex.lock();	running_cond->wait();	mutex.unlock();	if(status)		*status = return_val;	delete this;}//// Change this thread's priority.//void omni_thread::set_priority(priority_t pri){	omni_mutex_lock l(mutex);	DBG_ASSERT(assert(_state == STATE_RUNNING));	if(_state != STATE_RUNNING)	{		DBG_THROW(throw omni_thread_invalid());	}	_priority = pri;	if(taskPrioritySet(tid, vxworks_priority(pri))==ERROR)	{		DBG_ASSERT(assert(false));		DBG_THROW(throw omni_thread_fatal(errno));	}}//// create - construct a new thread object and start it running.	Returns thread// object if successful, null pointer if not.//// detached version (the entry point is a void)omni_thread* omni_thread::create(void (*fn)(void*), void* arg, priority_t pri){	omni_thread* t = new omni_thread(fn, arg, pri);	t->start();	return t;}// undetached version (the entry point is a void*)omni_thread* omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri){	omni_thread* t = new omni_thread(fn, arg, pri);	t->start();	return t;}//// exit() _must_ lock the mutex even in the case of a detached thread.	This is// because a thread may run to completion before the thread that created it has// had a chance to get out of start().	By locking the mutex we ensure that the// creating thread must have reached the end of start() before we delete the// thread object.	Of course, once the call to start() returns, the user can// still incorrectly refer to the thread object, but that's their problem.//void omni_thread::exit(void* return_value){	omni_thread* me = self();	if(me)	{		me->mutex.lock();		me->return_val = return_value;		me->_state = STATE_TERMINATED;		me->running_cond->signal();		me->mutex.unlock();		DBG_TRACE(cout<<"omni_thread::exit: thread "<<me->id()<<" detached "<<me->detached<<" return value "<<(int)return_value<<endl);		if (me->_values) {		  for (key_t i=0; i < me->_value_alloc; i++) {		    if (me->_values[i]) {		      delete me->_values[i];		    }		  }		  delete [] me->_values;		  me->_values = 0;		}		if(me->detached)			delete me;	}	else		DBG_TRACE(cout<<"omni_thread::exit: called with a non-omnithread. Exit quietly."<<endl);	taskDelete(taskIdSelf());}omni_thread* omni_thread::self(void){	if(taskTcb(taskIdSelf())->spare1 != OMNI_THREAD_ID)		return NULL;	return (omni_thread*)taskTcb(taskIdSelf())->spare2;}void omni_thread::yield(void){	taskDelay(NO_WAIT);}void omni_thread::sleep(unsigned long secs, unsigned long nanosecs){	int tps = sysClkRateGet();	// Convert to us to avoid overflow in the multiplication	//	tps should always be less than 1000 !	nanosecs /= 1000;	taskDelay(secs*tps + (nanosecs*tps)/1000000l);}void omni_thread::get_time( unsigned long* abs_sec,							unsigned long* abs_nsec,							unsigned long rel_sec,							unsigned long rel_nsec){	timespec abs;	clock_gettime(CLOCK_REALTIME, &abs);	abs.tv_nsec += rel_nsec;	abs.tv_sec += rel_sec + abs.tv_nsec / 1000000000;	abs.tv_nsec = abs.tv_nsec % 1000000000;	*abs_sec = abs.tv_sec;	*abs_nsec = abs.tv_nsec;}int omni_thread::vxworks_priority(priority_t pri){	switch (pri)	{	case PRIORITY_LOW:		return omni_thread_prio_low;	case PRIORITY_NORMAL:		return omni_thread_prio_normal;	case PRIORITY_HIGH:		return omni_thread_prio_high;	}	DBG_ASSERT(assert(false));	DBG_THROW(throw omni_thread_invalid());}void omni_thread::stacksize(unsigned long sz){	stack_size = sz;}unsigned long omni_thread::stacksize(){	return stack_size;}void omni_thread::show(void){	omni_thread *pThread;	int s1, s2;	int tid = taskIdSelf();	printf("TaskId is %.8x\n", tid);	s1 = taskTcb(tid)->spare1;	if(s1 != OMNI_THREAD_ID)	{		printf("Spare 1 is %.8x, and not recongnized\n", s1);		return;	}	else	{		printf("Spare 1 indicate an omni_thread.\n");	}	s2 = taskTcb(tid)->spare2;	if(s2 == 0)	{		printf("Spare 2 is NULL! - No thread object attached !!\n");		return;	}	else	{		printf("Thread object at %.8x\n", s2);	}	pThread = (omni_thread *)s2;	state_t status = pThread->_state;	printf("	| Thread status is ");	switch (status)	{	case STATE_NEW:		printf("NEW\n");		break;	case STATE_RUNNING:		printf("STATE_RUNNING\n"); break;	case STATE_TERMINATED:		printf("TERMINATED\n");	break;	default:		printf("Illegal (=%.8x)\n", (unsigned int)status);		return;	}	if(pThread->tid != tid)	{		printf("	| Task ID in thread object is different!! (=%.8x)\n", pThread->tid);		return;	}	else	{		printf("	| Task ID in thread consistent\n");	}	printf("\n");}//// Dummy thread//class omni_thread_dummy : public omni_thread {public:  inline omni_thread_dummy() : omni_thread()  {    // glblock -- added this to prevent problem with unitialized    // running_cond the dummy thread never uses this and we dont want    // the destructor to delete it.  vxWorks compiler seems to not set    // unitialized vars to NULL.    running_cond = NULL;    _dummy = 1;    _state = STATE_RUNNING;    // Adjust data members of this instance    tid = taskIdSelf();    DBG_TRACE(cout<<"created dummy "<<(void*)tid<<endl);    // Set the thread values so it can be recongnised as a omni_thread    // Set the id last can possibly prevent race condition    taskTcb(tid)->spare2 = (int)this;    taskTcb(tid)->spare1 = OMNI_THREAD_ID;  }  inline ~omni_thread_dummy()  {    DBG_TRACE(cout<<"omni thread dummy destructor " <<endl);    taskTcb(taskIdSelf())->spare1 = 0;  }};omni_thread*omni_thread::create_dummy(){  if (omni_thread::self())    throw omni_thread_invalid();  return new omni_thread_dummy;}voidomni_thread::release_dummy(){  omni_thread* self = omni_thread::self();  if (!self || !self->_dummy)    throw omni_thread_invalid();  omni_thread_dummy* dummy = (omni_thread_dummy*)self;  delete dummy;}#define INSIDE_THREAD_IMPL_CC#include "threaddata.cc"#undef INSIDE_THREAD_IMPL_CC

⌨️ 快捷键说明

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