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

📄 rvthread_.c

📁 h.248协议源码
💻 C
字号:
#if (0)
************************************************************************
Filename   : 
Description:
************************************************************************
                Copyright (c) 1999 RADVision Inc.
************************************************************************
NOTICE:
This document contains information that is proprietary to RADVision LTD.
No part of this publication may be reproduced in any form whatsoever 
without written prior approval by RADVision LTD..

RADVision LTD. reserves the right to revise this publication and make 
changes without obligation to notify any person of such revisions or 
changes.
************************************************************************
************************************************************************
$Revision:$
$Date:$
$Author: S. Cipolli$
************************************************************************
#endif

#include <assert.h>
#include <string.h>
#include "rvthread_.h"
#include "rvmem.h"

#if defined(RV_OS_OSE)
#include <ose.h>
#endif

#if defined(RV_THREAD_NUCLEUS)
#include <target.h>
#include <tc_defs.h>
#endif

/* OS dependent thread interface */
/* Very minimal implementation. */

#if defined(RV_THREAD_WIN32)

static DWORD rvCurrentThreadKey = (~0);

/* WIN32 interface */
static unsigned __stdcall rvThreadWrapper(void* data) {
	RvThread_* t = (RvThread_*)data;

	/* Set thread's priority */
	SetThreadPriority(t->handle, t->priority);

	/* Set the "current" thread local variable */
	TlsSetValue(rvCurrentThreadKey, t);

	t->func(t, t->data);

	/* Mark and signal thread completion */
	t->state = RV_THREAD_STATE_DEAD;
	rvSemPost_(&t->sync);

    CloseHandle(t->handle);
	_endthreadex(0);

    return 0;
}

RvThread_* rvThreadConstruct_(RvThread_* t, const char* name, int priority, 
  size_t stackSize, RvThread_MainCB func, void* data) {

	/* Construct synchronization semaphore */
	rvSemConstruct_(&t->sync, 0);

	/* If the thread local variable has not been allocated ... */
	if (rvCurrentThreadKey == (~0))
		rvCurrentThreadKey = TlsAlloc();

	strncpy(t->name, name, 32);
	t->state = RV_THREAD_STATE_UNBORN;
	t->data = data;
	t->func = func;
	t->stackSize = stackSize;
	t->stack = 0;
	t->priority = (priority > 15) ? 15 : priority < (-15) ? (-15) : priority;
	
	return t;
}

void rvThreadDestruct_(RvThread_* t) {
	rvThreadJoin_(t);
	rvSemDestruct_(&t->sync);
}

void rvThreadStart_(RvThread_* t) {
	/* 
	 * Note: Assumption is that rvThreadStart does not need
	 * to be thread safe. I.e. two threads won't try to start
	 * a thread at the same time.
	 */

	/* Only start "unborn" threads */
	if (t->state == RV_THREAD_STATE_UNBORN) {
		t->state = RV_THREAD_STATE_ALIVE;
		t->handle = (HANDLE)_beginthreadex(NULL, t->stackSize, rvThreadWrapper, t, CREATE_SUSPENDED ,(unsigned *)&t->id);
        if(t->handle != 0)
            ResumeThread(t->handle);

	}
}
RvThread_* rvThreadCurrent_() {
	return (RvThread_*)TlsGetValue(rvCurrentThreadKey);
}
void rvThreadSleep_(unsigned int ms) {
	Sleep(ms);
}

#elif defined(RV_THREAD_POSIX)

static pthread_key_t rvCurrentThreadKey = 0;

/* Solaris interface */
#if defined(__cplusplus)
extern "C" void* rvThreadWrapper(void*);
#endif

void* rvThreadWrapper(void* data) {
	RvThread_* t = (RvThread_*)data;

	t->id = rvThreadIdCurrent();

	/* Set the "current" thread local variable */
	pthread_setspecific(rvCurrentThreadKey, t);

	t->func(t, t->data);

	/* Mark and signal thread completion */
	t->state = RV_THREAD_STATE_DEAD;
	rvSemPost_(&t->sync);

	return 0;
}

RvThread_* rvThreadConstruct_(RvThread_* t, const char* name, int priority, 
  size_t stackSize, void (*func)(RvThread_*, void*), void* data) {

	rvSemConstruct_(&t->sync, 0);

	strncpy(t->name, name, 32);
	t->state = RV_THREAD_STATE_UNBORN;
	t->data = data;
	t->func = func;
	t->stackSize = stackSize;
	t->stack = 0;
	t->priority = priority;

	if (rvCurrentThreadKey == 0)
	  pthread_key_create(&rvCurrentThreadKey, 0);

	return t;
}

void rvThreadDestruct_(RvThread_* t) {
	rvThreadJoin_(t);
	rvSemDestruct_(&t->sync);
}

void rvThreadStart_(RvThread_* t) {
	/* 
	 * Note: Assumption is that rvThreadStart does not need
	 * to be thread safe. i.e. two threads won't try to start
	 * the same thread at the same time.
	 */

	/* Only start "unborn" threads */
	if (t->state == RV_THREAD_STATE_UNBORN) {
		struct sched_param sp;
		pthread_attr_t attr;
		int r;

		pthread_attr_init(&attr);
		pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
#if defined(RV_OS_OSE)
		pthread_attr_setstacksize(&attr, t->stackSize);
#endif
		pthread_attr_getschedparam(&attr, &sp);
		sp.sched_priority = t->priority;
		pthread_attr_setschedparam(&attr, &sp);

		t->state = RV_THREAD_STATE_ALIVE;
		r = pthread_create(&t->id, &attr, rvThreadWrapper, t);
		assert(r == 0);
		pthread_attr_destroy(&attr);
	}
}

RvThread_* rvThreadCurrent_() {
  return (RvThread_*)pthread_getspecific(rvCurrentThreadKey);
}

void rvThreadSleep_(unsigned int ms) {
#if defined(RV_OS_OSE)
/* OSE doesn't have the POSIX nanosleep call but does have a ms delay */
	delay(ms);
#else
/* For systems that have standard POSIX nanosleep call */
	struct timespec timeout0;
	struct timespec timeout1;
	struct timespec* tmp;
	struct timespec* t0 = &timeout0;
	struct timespec* t1 = &timeout1;

	t0->tv_sec = ms / 1000;
	t0->tv_nsec = (ms % 1000) * (1000 * 1000);

	/* This bizarre logic is necessary to prevent signals from	*/
	/* stopping the sleep from completing.						*/
	while ((nanosleep(t0, t1) == (-1)) && (errno == EINTR)) {
		tmp = t0;
		t0 = t1;
		t1 = tmp;
	}
#endif
}

#elif defined(RV_THREAD_VXWORKS)
#include <time.h>
#include <sysLib.h>
#include <taskLib.h>
#include <taskVarLib.h>

static RvThread_* rvCurrentThread;

static int rvThreadWrapper(int a0, int a1, int a2, int a3, int a4, 
  int a5, int a6, int a7, int a8, int a9) {
	RvThread_* t = (RvThread_*)a0;

	t->id = rvThreadIdCurrent();

	/* Set the "current" thread local variable */
	rvCurrentThread = t;
	taskVarAdd(t->id, (int*)&rvCurrentThread);

	t->func(t, t->data);

	/* Mark and signal thread completion */
	t->state = RV_THREAD_STATE_DEAD;
	rvSemPost_(&t->sync);

	return 0;
}

RvThread_* rvThreadConstruct_(RvThread_* t, const char* name, int priority, 
  size_t stackSize, void (*func)(RvThread_*, void*), void* data) {
	rvSemConstruct_(&t->sync, 0);

	strncpy(t->name, name, 32);
	t->state = RV_THREAD_STATE_UNBORN;
	t->data = data;
	t->func = func;
	t->stackSize = stackSize;
	t->stack = 0;
	t->priority = ((priority < 0) ? 0 : ((priority > 255) ? 255 : priority));
	t->id = 0;

	return t;
}

void rvThreadDestruct_(RvThread_* t) {
	rvThreadJoin_(t);
	rvSemDestruct_(&t->sync);
}

void rvThreadStart_(RvThread_* t) {
	/* 
	 * Note: Assumption is that rvThreadStart does not need
	 * to be thread safe. i.e. two threads won't try to start
	 * the same thread at the same time.
	 */
	
	/* Only start "unborn" threads */
	if (t->state == RV_THREAD_STATE_UNBORN) {
		t->state = RV_THREAD_STATE_ALIVE;
		t->id = taskSpawn(t->name, t->priority, 0, t->stackSize, 
			(FUNCPTR)rvThreadWrapper, (int)t, 
			0, 0, 0, 0, 0, 0, 0, 0, 0);
		assert(t->id != ERROR);
	}
}

RvThread_* rvThreadCurrent_() {
	return rvCurrentThread;
}

void rvThreadSleep_(unsigned int ms) {
	taskDelay(((((int)ms * sysClkRateGet()) - 1) / 1000) + 1 );

}
#elif defined(RV_THREAD_PSOS)
#include <stdio.h>		/* Needed by <assert.h>... weird */
#include <time.h>
#include <psos.h>

/* Software register used to hold thread pointer; use any in range [0-7] */
#define RV_PSOS_TASKREG		7

static void rvThreadWrapper(int a0, int a1, int a2, int a3) {
	RvThread_* t = (RvThread_*)a0;

	t->id = rvThreadIdCurrent();

	/* Set the "current" thread local variable */
	t_setreg(t->id, RV_PSOS_TASKREG, (unsigned long)t);

	t->func(t, t->data);

	/* Mark and signal thread completion */
	t->state = RV_THREAD_STATE_DEAD;
	rvSemPost_(&t->sync);

	fclose(0);
	close_f(0);
	close(0);
	free(-1);
	t_delete(0);
}

RvThread_* rvThreadConstruct_(RvThread_* t, const char* name, 
  int priority, size_t stackSize, void (*func)(RvThread_*, void*), 
  void* data) {
	unsigned long r;

	rvSemConstruct_(&t->sync, 0);

	strncpy(t->name, name, 32);
	t->state = RV_THREAD_STATE_UNBORN;
	t->data = data;
	t->func = func;
	t->stackSize = stackSize;
	t->stack = 0;
	t->priority = ((priority < 1) ? 1 : ((priority > 239) ? 239 : priority)); 

	r = t_create("rv", (unsigned long)t->priority, t->stackSize, 0, 
	  T_LOCAL, &(t->id));
	assert(r == 0);

	return t;
}

void rvThreadDestruct_(RvThread_* t) {
	rvThreadJoin_(t);
	rvSemDestruct_(&t->sync);
	t_delete(t->id);
}

void rvThreadStart_(RvThread_* t) {
	/* 
	 * Note: Assumption is that rvThreadStart does not need
	 * to be thread safe. i.e. two threads won't try to start
	 * the same thread at the same time.
	 */

	/* Only start "unborn" threads */
	if (t->state == RV_THREAD_STATE_UNBORN) {
		unsigned long r;
		unsigned long args[4];
		args[0] = (unsigned long)t;
		args[1] = 0;
		args[2] = 0; 
		args[3] = 0;
		t->state = RV_THREAD_STATE_ALIVE;
		r = t_start(t->id, (T_PREEMPT|T_NOTSLICE|T_SUPV|T_ISR), 
		  rvThreadWrapper, args);
		assert(r == 0);
	}
}

RvThread_* rvThreadCurrent_() {
	unsigned long t;
	t_getreg(0, RV_PSOS_TASKREG, &t);
	return (RvThread_*)t;
}

extern pSOS_CT PsosCfg;
void rvThreadSleep_(unsigned int ms) {
	tm_wkafter(((((int)ms * PsosCfg.kc_ticks2sec) - 1) / 1000) + 1 );
}

/* Used internally by other kernel components only */
RvThreadId rvThreadIdCurrent(void) {
	RvThreadId current;
	t_ident(0, 0, &current);
	return current;
}

#elif defined(RV_THREAD_NUCLEUS)

static void rvThreadWrapper(UNSIGNED argc, void *argv) {
	RvThread_* t = (RvThread_*)argv;
	TC_TCB *tcptr;

	t->id = NU_Current_Task_Pointer();

	/* set up thread specific pointer  TC_TCB != NU_TASK when not compiling debug */
	tcptr = (TC_TCB *)t->id;
	tcptr->tc_app_reserved_1 = (UNSIGNED)t;

	t->func(t, t->data);

	/* Mark and signal thread completion */
	t->state = RV_THREAD_STATE_DEAD;
	rvSemPost_(&t->sync);
}

RvThread_* rvThreadConstruct_(RvThread_* t, const char* name, int priority, 
							  size_t stackSize, void (*func)(RvThread_*, void*), void* data) {
	rvSemConstruct_(&t->sync, 0);

	strncpy(t->name, name, 32);
	t->state = RV_THREAD_STATE_UNBORN;
	t->data = data;
	t->func = func;
	t->stackSize = stackSize;
	t->stack = rvMemAlloc(stackSize);
	t->priority = (priority > 255) ? 255 : (priority < 0) ? 0 : priority;

	return t;
}

void rvThreadDestruct_(RvThread_* t) {
	rvThreadJoin_(t);
	NU_Terminate_Task(&t->handle);
	NU_Delete_Task(&t->handle);
	rvMemFree(t->stack);
	rvSemDestruct_(&t->sync);
}

void rvThreadStart_(RvThread_* t) {
	/* 
	 * Note: Assumption is that rvThreadStart does not need
	 * to be thread safe. i.e. two threads won't try to start
	 * the same thread at the same time.
	 */
	int status;

	/* Only start "unborn" threads */
	if (t->state == RV_THREAD_STATE_UNBORN) {
		t->state = RV_THREAD_STATE_ALIVE;
		t->id = &(t->handle);
		status = NU_Create_Task(&t->handle, t->name, rvThreadWrapper, 0, t,
								t->stack, t->stackSize, (OPTION)t->priority, 0, NU_PREEMPT, NU_START);
		assert(status == NU_SUCCESS);
	}
}

RvThread_* rvThreadCurrent_() {
	TC_TCB *task; /* TC_TCB != when not compiling in DEBUG */

	task = (TC_TCB *)NU_Current_Task_Pointer();
	return (RvThread_ *)task->tc_app_reserved_1;
}

void rvThreadSleep_(unsigned int ms) {
	NU_Sleep(((((int)ms * TICKS_PER_SECOND) - 1) / 1000) + 1 );

}
#else
#error Unknown kernel implementation
#endif

const char* rvThreadName_(RvThread_* t) {
	return (const char*)(t ? t->name : "User Thread");
}

RvBool rvThreadJoin_(RvThread_* t) {
	if (rvThreadIdCurrent() == t->id) 
		return rvFalse;
	if (t->state != RV_THREAD_STATE_UNBORN) {
		rvSemWait_(&t->sync);
		rvSemPost_(&t->sync);
	}
	return rvTrue;
}

⌨️ 快捷键说明

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