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

📄 linuxwrapper.c

📁 stos Linux 源码示范程序。 可以移植到其他平台
💻 C
📖 第 1 页 / 共 4 页
字号:

#ifdef MODULE
#include <linux/kthread.h>
#include <linux/kernel.h>
#endif

#include "linuxwrapper.h"


/* ----------  Constants  ----------------*/

/* #define MESSAGE_QUEUE_DEBUG */
/* #define MESSAGE_QUEUE_FULL_DEBUG */
/* #define SEMAPHORE_DEBUG */


#ifdef MODULE
#define PrintTrace(x)		printk x

#else   /* MODULE */

#define PrintTrace(x)		printf x
#endif  /* MODULE */

#define TIME_NOW_CONSTRAINTS_ON_SECONDS   86400           /* Restraints number of seconds to last day (86400s in 1 day) */




/* ----------  Types & Variables  ----------------*/


/* Lockers */

#ifdef MODULE
#define LOCKER_INIT         SPIN_LOCK_UNLOCKED
typedef spinlock_t          locker_t;

#define locker_lock(x)      spin_lock(&x)
#define locker_unlock(x)    spin_unlock(&x)

#else

#define LOCKER_INIT         PTHREAD_MUTEX_INITIALIZER
typedef pthread_mutex_t     locker_t;

#define locker_lock(x)      pthread_mutex_lock(&x)
#define locker_unlock(x)    pthread_mutex_unlock(&x)
#endif



/* Semaphores */
typedef struct SemaphoreList_s
{
    struct SemaphoreList_s    * Next_p;
    semaphore_t               * Semaphore_p;
} SemaphoreList_t;

static SemaphoreList_t    * SemaphoreList_p = NULL;

static locker_t semaphore_mutex = LOCKER_INIT;


/* Messages */
#define QUEUE_NB_MAX  20

typedef struct MessageSend_s
{
    struct MessageSend_s  *	Next_p;
    void     			  *	Message_p;
} MessageSend_t;

typedef struct
{
	void 			  * Memory_p;
	BOOL 			  * Used_p;
	MessageSend_t	  *	Pending_p;
	size_t 				ElementSize;
	unsigned int 		NoElements;
} MessageElem_t;

typedef struct MessageQueueList_s
{
    struct MessageQueueList_s   * Next_p;
    message_queue_t             * MessageQueue_p;
    void                        * Memory_p;
} MessageQueueList_t;

#if defined(MESSAGE_QUEUE_DEBUG) || defined(MESSAGE_QUEUE_FULL_DEBUG)
#ifdef MODULE
#define PrintMessageQ_Debug(x)		printk x
#else
#define PrintMessageQ_Debug(x)		printf x
#endif

#ifdef MESSAGE_QUEUE_FULL_DEBUG
#ifdef MODULE
#define PrintMessageQ_FullDebug(x)  printk x
#else
#define PrintMessageQ_FullDebug(x)	printf x
#endif
#else
#define PrintMessageQ_FullDebug(x)
#endif

#else
#define PrintMessageQ_Debug(x)
#define PrintMessageQ_FullDebug(x)
#endif

static MessageElem_t	MessageArray[QUEUE_NB_MAX];
static BOOL   			MessageInitDone = FALSE;

static MessageQueueList_t    * MessageQueueList_p = NULL;

static locker_t message_mutex = LOCKER_INIT;



/* task_lock/task_unlock */
#if !defined(MODULE)
static pthread_mutex_t compat_mutex = PTHREAD_MUTEX_INITIALIZER;
#endif  /* !MODULE */


/* Clocks */
#if !defined(MODULE)
/* Stores ClockTicks per second to avoid reread it too many times */
static int ClkPerSec = 0;     /* Clock ticks per seconds (typically 15625) */
#endif  /* !MODULE */


/* Random number */
#ifdef MODULE
unsigned long x=0;
#endif

/* Interrupt locks like variables */
#ifdef MODULE
U32                 SpinIntFlagsIndex =0 ;
unsigned long       SpinIntFlagsTab[SPIN_LOCK_DEPTH_MAX];
spinlock_t          SpinIntLock = SPIN_LOCK_UNLOCKED;
#endif

#ifdef DEBUG_LOCK
IntLockVar_t        IntLockInVar[INT_LOCK_INDEX_MAX];
IntLockVar_t        IntLockOutVar[INT_LOCK_INDEX_MAX];
U32                 IntLockPrint = 0;
#if defined(MODULE)
U32                 IntLockInIndex = 0;
U32                 IntLockOutIndex = 0;
unsigned long       SpinIntFlags;
pid_t               SpinIntPid;
int                 IntLockI,IntLockJ;
int                 IntLockPrintSignal = 0;
#endif
#endif

/* ----------  Functions  ----------------*/

/* ******************************************** */
/* Input functions */
/* In order to be coherent after each call */
/* the terminal will return into blocking echoed state */
/* ******************************************** */

#if !defined(MODULE)
/*
 * STTBX_InputChar
 */
void STTBX_InputChar(char * result)
{
    struct termio term;

	/* unblocking the teminal */
    ioctl(0,TCGETA,(void *)&term);
    term.c_lflag &= ~ICANON;
    term.c_lflag &= ~ECHO;
    ioctl(0,TCSETAW,(void *)&term);

    /* getting the char */
	*result= (char) getchar();

	/* blocking the teminal */
    ioctl(0,TCGETA,(void *)&term);
    term.c_lflag |= ICANON;
    term.c_lflag |= ECHO;
    ioctl(0,TCSETAW,(void *)&term);

	return ;
}

/*
 * STTBX_InputPollChar
 */
BOOL STTBX_InputPollChar(char* buffer)
{
    int ret=FALSE, size;
    struct pollfd p;
    struct termio term, term_old;

    p.fd = 0;
    p.events = POLLIN;

    ioctl(0,TCGETA,(void *)&term);
    term_old = term;
    term.c_lflag &= ~ICANON;
    term.c_lflag &= ~ECHO;
    ioctl(0,TCSETAW,(void *)&term);

    ret = poll(&p, 1, 0);
    if (ret > 0) {
       if (p.revents == POLLIN) {
           size = read(0, buffer, 1);
           ret=TRUE;
       }
    }

    tcflush( 0, TCIOFLUSH);
    ioctl(0,TCSETAW,(void *)&term_old);

    return (ret);
}


/*
 * STTBX_InputStr
 */
int STTBX_InputStr( char* answer, int size )
{
    int result = 0;

    while (!result)                     /* NS# needed to mimic OS21 behaviour (null string not expected) */
    {
        if (fgets( answer, size, stdin))    /* NS# use fgets instead of sscanf -- more secure */
        {
            char *p = strstr( answer, "\n");

            if (p)
                *p = 0;                 /* NS# suppress first CRLF to mimic OS21 behaviour */
            result = strlen( answer);   /* NS# return strlen to conform to STTBX_InputStr API */
        }
    }

    return result;
}

#endif

/*
 * STTBX_Report_arg
 */
void STTBX_Report_arg( const STTBX_ReportLevel_t ReportLevel, const char *const Format_p, ...)
{
	va_list argument;
	char line[256];

    switch (ReportLevel)
    {
        case STTBX_REPORT_LEVEL_FATAL:
            snprintf( line, sizeof( line), "   Fatal> ");
            break;
            
        case STTBX_REPORT_LEVEL_ERROR:
            snprintf( line, sizeof( line), "   Error> ");
            break;
            
        case STTBX_REPORT_LEVEL_WARNING:
            snprintf( line, sizeof( line), " Warning> ");
            break;
            
        case STTBX_REPORT_LEVEL_ENTER_LEAVE_FN:
            snprintf( line, sizeof( line), "InOut Fn> ");
            break;
            
        case STTBX_REPORT_LEVEL_INFO:
            snprintf( line, sizeof( line), "    Info> ");
            break;
            
        case STTBX_REPORT_LEVEL_USER1:
            snprintf( line, sizeof( line), "   User1> ");
            break;
            
        case STTBX_REPORT_LEVEL_USER2:
            snprintf( line, sizeof( line), "   User2> ");
            break;
            
        default:
            snprintf( line, sizeof( line), "  ????? > ");
            break;
    }
    PrintTrace(( "%s", line));
    va_start( argument, Format_p);
    vsnprintf( line, sizeof( line), Format_p, argument);
    va_end( argument);
    PrintTrace(( "%s", line));
    PrintTrace(( "\n"));
}


/****************************************************/
/*                SEMAPHORES						*/
/****************************************************/
/* ************************************************** */
/*
 * semaphore_init_fifo
 */
/* ************************************************** */
int semaphore_init_fifo(semaphore_t *sem, int count)
{
#ifdef MODULE

	init_waitqueue_head(&(sem->wait_queue));
    atomic_set(&sem->Count, (1-count));

    return 0;

#else

	pthread_mutexattr_t		MutAttr;
	int						ret;

#ifdef SEMAPHORE_DEBUG
    PrintTrace(("sem_if:%x\n",(unsigned long) sem));
#endif

	pthread_mutexattr_init(&MutAttr);
    /* This is a WA to get much better response time (19000 us vs 90 us) */
    /* Should be : ret = pthread_mutexattr_settype(&MutAttr, PTHREAD_MUTEX_ADAPTIVE_NP);*/
    ret = pthread_mutexattr_settype(&MutAttr, PTHREAD_MUTEX_TIMED_NP);

	if (ret == 0)
    {
		ret = pthread_mutex_init(sem, &MutAttr);
	}

    if (ret == 0)
	{
		if (count == 0)
		{
			pthread_mutex_lock(sem);
		}
		else
		{
	        if (count <= 1)
	        {
	            pthread_mutex_unlock(sem);
                sched_yield();
            }
            else
            {
                ret = 0xFF;
            }
		}
	}

	pthread_mutexattr_destroy(&MutAttr);

	if (ret != 0)
	{
		PrintTrace(("semaphore_init_fifo creation problem 0x%x (%d)!!!!!\n\n", (U32)sem, ret));
	}

    return (ret == 0 ? 0 : -1);

#endif
}

/* ************************************************** */
/*
 * semaphore_init_fifo_timeout
 */
/* ************************************************** */
int semaphore_init_fifo_timeout(semaphore_t *sem, int count)
{
#ifdef MODULE

	init_waitqueue_head(&(sem->wait_queue));
    atomic_set(&sem->Count, (1-count));

    return 0;

#else
    
	pthread_mutexattr_t		MutAttr;
	int						ret;

#ifdef SEMAPHORE_DEBUG
    PrintTrace(("sem_ift:%x\n",(unsigned long) sem));
#endif

	pthread_mutexattr_init(&MutAttr);
	ret = pthread_mutexattr_settype(&MutAttr, PTHREAD_MUTEX_TIMED_NP);

	if (ret == 0)
	{
		ret = pthread_mutex_init(sem, &MutAttr);
    }

    if (ret == 0)
	{
		if (count == 0)
		{
			pthread_mutex_lock(sem);
		}
		else
		{
	        if (count <= 1)
	        {
	            pthread_mutex_unlock(sem);
                sched_yield();
            }
            else
            {
                ret = 0xFF;
            }
		}
	}

	pthread_mutexattr_destroy(&MutAttr);

	if (ret != 0)
	{
		PrintTrace(("semaphore_init_fifo_timeout creation problem 0x%x (%d)!!!!!\n\n", (U32) sem, ret));
	}

    return (ret == 0 ? 0 : -1);

#endif  /* MODULE */
}

/* ************************************************** */
/*
 * semaphore_init_priority
 *
 * The next function should ensure that sem_wait will place the thread at top priority
 * but is not the case in Linux. Putting it in kernel with waiting task ???
 */
/* ************************************************** */
int semaphore_init_priority(semaphore_t *sem, int count)
{
	/* Not managed yet, emulate it !!! */
	return (semaphore_init_fifo(sem, count) == 0 ? 0 : -1);
}



/* ************************************************** */
/*
 * semaphore_create_fifo
 */
/* ************************************************** */
semaphore_t * semaphore_create_fifo(int count)
{
    return( semaphore_create_fifo_timeout(count) );
}


/* ************************************************** */
/*
 * semaphore_create_fifo_timeout
 */
/* ************************************************** */
semaphore_t * semaphore_create_fifo_timeout(int count)
{
    
 
    SemaphoreList_t * Current_p;
    SemaphoreList_t * New_p;
    semaphore_t     * sem_p = NULL;

    if ((New_p = memory_allocate(NULL, sizeof(SemaphoreList_t))) != NULL)
    {
        if ((New_p->Semaphore_p = memory_allocate(NULL, sizeof(semaphore_t))) == NULL)
        {
            /* Memory allocation pb, deallocate list element */
            memory_deallocate(NULL, New_p);
            New_p = NULL;
        }
    }

    if (New_p != NULL)
    {
        /* At this stage, we know that all allocations have been correctly done */
        if (semaphore_init_fifo_timeout(New_p->Semaphore_p, count) == 0)
        {
	        New_p->Next_p = NULL;

            locker_lock(semaphore_mutex);
            Current_p = SemaphoreList_p;
	        if (Current_p != NULL)
		 	{
		 	 	while (Current_p->Next_p != NULL)
		 	   		Current_p = Current_p->Next_p;

		 	   	Current_p->Next_p = New_p;
		 	}
		 	else
		 	{
		 	  	SemaphoreList_p = New_p;
		 	}
            locker_unlock(semaphore_mutex);

            sem_p = New_p->Semaphore_p;
        }
        else
        {
            memory_deallocate(NULL, New_p->Semaphore_p);
            memory_deallocate(NULL, New_p);
		 	PrintTrace(("COMPAT: semaphore_create_fifo, semaphore init problem !!!\n"));
        }
    }
	else
	{
		PrintTrace(("COMPAT: semaphore_create_fifo, no memory !!!\n"));
	}

#ifdef SEMAPHORE_DEBUG
    PrintTrace(("sem_cfto:%x\n",(unsigned long) sem_p));
#endif
 
    /* NULL if Semaphore Creation Problem, sem pointer otherwise */
    return(sem_p);
}


/* ************************************************** */
/*
 * semaphore_create_priority
 *
 * The next function should ensure that sem_wait will place the thread at top priority
 * but is not the case in Linux. Putting it in kernel with waiting task ???
 */
/* ************************************************** */
semaphore_t * semaphore_create_priority(int count)
{
	/* Not managed yet, emulate it !!! */
	return ( semaphore_create_fifo_timeout(count) );
}

⌨️ 快捷键说明

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