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

📄 vxworks.cc

📁 gnuradio软件无线电源程序.现在的手机多基于软件无线电
💻 CC
📖 第 1 页 / 共 2 页
字号:
//// 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!	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;    }	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		0,									 // Option		stack_size,						 // Stack size		(FUNCPTR)omni_thread_wrapper, // Priority		(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->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()  {    _dummy = 1;    _state = STATE_RUNNING;	// Adjust data members of this instance	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(tid)->spare2 = (int)this;	taskTcb(tid)->spare1 = OMNI_THREAD_ID;   }  inline ~omni_thread_dummy()  {	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 + -