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

📄 ixosalosthread.c

📁 intel IXP400系列cpu(2.3版)的库文件
💻 C
字号:
/** * @file IxOsalOsThread.c (linux) * * @brief OS-specific thread implementation. *  *  * @par * IXP400 SW Release version 2.3 *  * -- Copyright Notice -- *  * @par * Copyright (c) 2001-2005, Intel Corporation. * All rights reserved. *  * @par * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. Neither the name of the Intel Corporation nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. *  *  * @par * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *  *  * @par * -- End of Copyright Notice -- */#include "IxOsal.h"#include <linux/sched.h>#ifdef IX_OSAL_OS_LINUX_VERSION_2_6#include <linux/list.h>#include <linux/kthread.h>#endif /* IX_OSAL_OS_LINUX_VERSION_2_6 */struct IxOsalOsThreadData{   IxOsalVoidFnVoidPtr entryPoint;   void                *arg;};/* declaring mutexes */DECLARE_MUTEX (IxOsalThreadMutex);DECLARE_MUTEX (IxOsalThreadStopMutex);#ifndef IX_OSAL_OS_LINUX_VERSION_2_6   /* ! Linux-Kernel Version 2.6 */struct IxOsalOsThreadData thread_data;struct task_struct        *kill_task = NULL;#endif#ifdef IX_OSAL_OS_LINUX_VERSION_2_6   /* Linux Kernel Version 2.6 */struct IxOsalOsThreadInfo{    struct IxOsalOsThreadData data;    IxOsalThread              ptid;    struct list_head          list;};PRIVATE LIST_HEAD(threadList);static int thread_internal(void *data){    IxOsalVoidFnVoidPtr entryPoint = NULL;    struct IxOsalOsThreadInfo *threadInfo;    /*     * Search for the task entry point from the thread info list     */    down (&IxOsalThreadMutex);    list_for_each_entry(threadInfo, &threadList, list)    {        /*         * Check if the thread handler in the node matches this thread handler         */        if (current == (struct task_struct*)(threadInfo->ptid))        {            entryPoint = threadInfo->data.entryPoint;            /*             * Record found. Delete and free the threadInfo node, then break the             * loop.             */            list_del(&threadInfo->list);            ixOsalMemFree(threadInfo);            break;        }    }    up (&IxOsalThreadMutex);    if (entryPoint)    {        entryPoint(data);    }    return 0;}/* Thread attribute is ignored in Create */PUBLIC IX_STATUSixOsalThreadCreate (IxOsalThread * ptrTid,    IxOsalThreadAttr * threadAttr, IxOsalVoidFnVoidPtr entryPoint, void *arg){    struct IxOsalOsThreadInfo *threadInfo;    threadInfo = (struct IxOsalOsThreadInfo*) ixOsalMemAlloc(                        sizeof(struct IxOsalOsThreadInfo));    if (unlikely(NULL == threadInfo))    {        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,            IX_OSAL_LOG_DEV_STDOUT,            "ixOsalThreadCreate(): Failed to allocate memory for threadInfo\n",            0, 0, 0, 0, 0, 0);        return IX_FAIL;    }    threadInfo->data.entryPoint = entryPoint;    /*     * Create the thread with the given thread name, but do not start it     */    *ptrTid = kthread_create(thread_internal, arg, "%s",                (NULL != threadAttr && NULL != threadAttr->name)                ? threadAttr->name: "OSAL");    if (unlikely(NULL == *ptrTid))    {        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,            IX_OSAL_LOG_DEV_STDOUT,            "ixOsalThreadCreate(): fail to create kthread \n",            0, 0, 0, 0, 0, 0);        /*         * Thread create failed, so free the threadInfo node allocated earlier         */        ixOsalMemFree(threadInfo);        return IX_FAIL;    }    /*     * Save thread handler of the created thread in the threadInfo node     */    threadInfo->ptid = *ptrTid;    down (&IxOsalThreadMutex);    /*     * We assumes that threads will be started according to the creation     * order, hence we add latest thread on the tail.     */    list_add_tail(&threadInfo->list, &threadList);    up(&IxOsalThreadMutex);    return IX_SUCCESS;}PUBLIC IX_OSAL_INLINE BOOLixOsalThreadStopCheck(){    return (kthread_should_stop());}#ifndef __ixpTolapai /*  * Start the thread */PUBLIC IX_STATUSixOsalThreadStart (IxOsalThread * tId){    if (NULL == *tId)    {        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,            IX_OSAL_LOG_DEV_STDOUT,            "ixOsalThreadStart(): Invalid Thread ID!\n",            0, 0, 0, 0, 0, 0);	     return IX_FAIL;    }    	    wake_up_process(*tId);    return IX_SUCCESS;}	/* * Kill the kernel thread. This shall not be used if the thread function * implements do_exit() */PUBLIC IX_STATUSixOsalThreadKill (IxOsalThread * tid){    struct task_struct *task = (struct task_struct*)*tid;    /* Can't kill already defunc thread */    if (EXIT_DEAD == task->exit_state || EXIT_ZOMBIE == task->exit_state)    	return IX_FAIL;    if (-EINTR == kthread_stop(task))    {        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,            IX_OSAL_LOG_DEV_STDOUT,            "ixOsalThreadKill(): Failed to kill thread\n",            0, 0, 0, 0, 0, 0);	     return IX_FAIL;    }    return IX_SUCCESS;}#else /* __ixpTolapai */PUBLIC IX_STATUSixOsalThreadKill (IxOsalThread * tid){  kill_proc (*tid, SIGKILL, 1);  return IX_SUCCESS;}PUBLIC IX_STATUSixOsalThreadStart (IxOsalThread * tId){    if (NULL == *tId)    {        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,            IX_OSAL_LOG_DEV_STDOUT,            "ixOsalThreadStart(): Invalid Thread ID!\n",            0, 0, 0, 0, 0, 0);              return IX_FAIL;    }     wake_up_process(*tId);    return IX_SUCCESS;}#endif /* __ixpTolapai */#else  /* ! LINUX_VERSION_2_6 */PUBLIC IX_OSAL_INLINE BOOLixOsalThreadStopCheck(){    if (current == kill_task)    {    	kill_task = NULL;    	up(&IxOsalThreadStopMutex);	return TRUE;    }    return FALSE;}	static intthread_internal (void *unused){    IxOsalVoidFnVoidPtr entryPoint = thread_data.entryPoint;    void *arg = thread_data.arg;    static int seq = 0;    daemonize();    reparent_to_init ();    exit_files (current);    snprintf(current->comm, sizeof(current->comm), "IxOsal %d", ++seq);    up (&IxOsalThreadMutex);    entryPoint (arg);    return 0;}/* Thread attribute is ignored */PUBLIC IX_STATUSixOsalThreadCreate (IxOsalThread * ptrTid,    IxOsalThreadAttr * threadAttr, IxOsalVoidFnVoidPtr entryPoint, void *arg){    down (&IxOsalThreadMutex);    IxOsalOsThreadData.entryPoint = entryPoint;    IxOsalOsThreadData.arg = arg;    /*     * kernel_thread takes: int (*fn)(void *)  as the first input.     */    *ptrTid = kernel_thread (thread_internal, NULL, CLONE_SIGHAND);    if (*ptrTid < 0)    {        up (&IxOsalThreadMutex);        ixOsalLog (IX_OSAL_LOG_LVL_ERROR,            IX_OSAL_LOG_DEV_STDOUT,            "ixOsalThreadCreate(): fail to generate thread \n",            0, 0, 0, 0, 0, 0);        return IX_FAIL;    }    return IX_SUCCESS;}/*  * Start thread after given its thread handle */PUBLIC IX_STATUSixOsalThreadStart (IxOsalThread * tId){    /* Thread already started upon creation */    ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE,        IX_OSAL_LOG_DEV_STDOUT,        "ixOsalThreadStart(): not implemented in linux\n",        0, 0, 0, 0, 0, 0);    return IX_SUCCESS;}PUBLIC IX_STATUSixOsalThreadKill (IxOsalThread * tid){    down(&IxOsalThreadStopMutex);    kill_task = find_task_by_pid(*tid);    if (kill_task)    {	    wake_up_process(kill_task);	    return IX_SUCCESS;    }    ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDOUT,	"ixOsalThreadKill: Task %d was dead\n", *tid, 0, 0, 0, 0, 0);    /* Kill failed, remove the mutex */    up(&IxOsalThreadStopMutex);    return IX_FAIL;}#endif /* IX_OSAL_OS_LINUX_VERSION_2_6 */PUBLIC voidixOsalThreadExit (void){    ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE,        IX_OSAL_LOG_DEV_STDOUT,        "ixOsalThreadExit(): not implemented in linux\n",        0, 0, 0, 0, 0, 0);}#ifdef IX_OSAL_OS_LINUX_VERSION_2_6   /* Linux Kernel Version 2.6 */#ifndef __ixpTolapai/******************************************************************** * UINT32 priority - the value of priority can range from 0 to 39   * *                   with 0 being the highest priority.				* * 																	* * Any value for priority more than 39 will be silently rounded off * * to 39 in this implementation. Internally, the range is converted * * to the corresponding nice value that can range from -20 to 19.	* ********************************************************************/ PUBLIC IX_STATUSixOsalThreadPrioritySet (IxOsalOsThread * tid, UINT32 priority){    struct task_struct *pTask 	= 	(struct task_struct*)*tid;	if ( pTask == NULL )	{		ixOsalLog (IX_OSAL_LOG_LVL_ERROR,			IX_OSAL_LOG_DEV_STDERR,			"ixOsalThreadPrioritySet(): Task not found \n",			0, 0, 0, 0, 0, 0);		return IX_FAIL;	}		if (priority > 255)	{		ixOsalLog (IX_OSAL_LOG_LVL_ERROR,			IX_OSAL_LOG_DEV_STDERR,			"ixOsalThreadPrioritySet(): FAIL \n",			0, 0, 0, 0, 0, 0);		return IX_FAIL;	}		if (priority > 39) priority = 39;	if (priority < 0) priority = 0;		set_user_nice ( pTask, priority-20 ); // sending the nice equivalent of priority as the parameter	    ixOsalLog (IX_OSAL_LOG_LVL_MESSAGE,        IX_OSAL_LOG_DEV_STDOUT,        "ixOsalThreadPrioritySet(): Priority changed successfully \n",        0, 0, 0, 0, 0, 0);    return IX_SUCCESS;}#else /* __ixpTolapai */PUBLIC IX_STATUSixOsalThreadPrioritySet (IxOsalOsThread * tid, UINT32 priority){    ixOsalLog (IX_OSAL_LOG_LVL_WARNING,        IX_OSAL_LOG_DEV_STDOUT,        "ixOsalThreadPrioritySet(): not implemented in linux \n",        0, 0, 0, 0, 0, 0);    return IX_SUCCESS;}#endif /* __ixpTolapai */#endif /* Linux Kernel Version 2.6 */ PUBLIC IX_STATUSixOsalThreadSuspend (IxOsalThread * tId){    ixOsalLog (IX_OSAL_LOG_LVL_WARNING,        IX_OSAL_LOG_DEV_STDOUT,        "ixOsalThreadSuspend(): not implemented in linux \n",        0, 0, 0, 0, 0, 0);    return IX_SUCCESS;}PUBLIC IX_STATUSixOsalThreadResume (IxOsalThread * tId){    ixOsalLog (IX_OSAL_LOG_LVL_WARNING,        IX_OSAL_LOG_DEV_STDOUT,        "ixOsalThreadResume(): not implemented in linux \n",        0, 0, 0, 0, 0, 0);    return IX_SUCCESS;}#ifdef __ixpTolapai/* Newly Added OSAL Thread Functions -- for OSSL shim layer */ PUBLICIX_STATUS ixOsalThreadGetId(IxOsalThread *ptrTid){    *ptrTid = current->pid;     return IX_SUCCESS; } /* ixOsalThreadGetId */   PUBLICIX_STATUS ixOsalThreadSetPolicyAndPriority(            IxOsalThread          *tid,            UINT32                policy,            UINT32                priority){    IX_STATUS err = IX_SUCCESS;    struct task_struct *pTask;      lock_kernel();     pTask = find_task_by_pid(*tid);    if(pTask == 0)    {        err = IX_FAIL;        goto label_1;    }     pTask->policy = policy;    pTask->rt_priority = priority; label_1:    unlock_kernel();     return err; } /* ixOsalThreadSetPolicyAndPriority */#endif /* __ixpTolapai */  

⌨️ 快捷键说明

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