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

📄 sem.c

📁 xenomai 很好的linux实时补丁
💻 C
字号:
/* * Copyright (C) 2001,2002 IDEALX (http://www.idealx.com/). * Written by Julien Pinon <jpinon@idealx.com>. * Copyright (C) 2003 Philippe Gerum <rpm@xenomai.org>. * * Xenomai is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Xenomai is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Xenomai; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "vrtx/task.h"#include "vrtx/sem.h"static xnqueue_t vrtxsemq;static int sem_destroy_internal(vrtxsem_t *sem);void vrtxsem_init (void) {    initq(&vrtxsemq);}void vrtxsem_cleanup (void) {    xnholder_t *holder;    while ((holder = getheadq(&vrtxsemq)) != NULL)	sem_destroy_internal(link2vrtxsem(holder));}static int sem_destroy_internal (vrtxsem_t *sem){    spl_t s;    int rc;    xnlock_get_irqsave(&nklock,s);    removeq(&vrtxsemq,&sem->link);    vrtx_release_id(sem->semid);    rc = xnsynch_destroy(&sem->synchbase);    vrtx_mark_deleted(sem);    xnlock_put_irqrestore(&nklock,s);    xnfree(sem);    return rc;}int sc_screate (unsigned initval, int opt, int *perr){    int bflags = 0, semid;    vrtxsem_t *sem;    spl_t s;    xnpod_check_context(XNPOD_THREAD_CONTEXT);    if ((opt != 1) && (opt != 0))	{	*perr = ER_IIP;	return 0;	}    sem = (vrtxsem_t *)xnmalloc(sizeof(*sem));    if (!sem)	{	*perr = ER_NOCB;	return 0;	}    semid = vrtx_alloc_id(sem);    if (semid < 0)	{	*perr = ER_NOCB;	xnfree(sem);	return 0;	}    if (opt == 0)	bflags = XNSYNCH_PRIO;    else	bflags = XNSYNCH_FIFO;    xnsynch_init(&sem->synchbase,bflags|XNSYNCH_DREORD);    inith(&sem->link);    sem->semid = semid;    sem->magic = VRTX_SEM_MAGIC;    sem->count = initval;    xnlock_get_irqsave(&nklock,s);    appendq(&vrtxsemq,&sem->link);    xnlock_put_irqrestore(&nklock,s);    *perr = RET_OK;    return semid;}void sc_sdelete(int semid, int opt, int *errp){    vrtxsem_t *sem;    spl_t s;    if ((opt != 0) && (opt != 1))	{	*errp = ER_IIP;	return;	}    xnlock_get_irqsave(&nklock,s);    sem = (vrtxsem_t *)vrtx_find_object_by_id(semid);    if (sem == NULL)	{	xnlock_put_irqrestore(&nklock,s);	*errp = ER_ID;	return;	}    *errp = RET_OK;    if (opt == 0 && xnsynch_nsleepers(&sem->synchbase) > 0)	{	xnlock_put_irqrestore(&nklock,s);	*errp = ER_PND;	return;	}    /* forcing delete or no task pending */    if (sem_destroy_internal(sem) == XNSYNCH_RESCHED)	xnpod_schedule();    xnlock_put_irqrestore(&nklock,s);}    void sc_spend(int semid, long timeout, int *errp){    vrtxsem_t *sem;    vrtxtask_t *task;    spl_t s;    xnpod_check_context(XNPOD_THREAD_CONTEXT);    xnlock_get_irqsave(&nklock,s);    sem = (vrtxsem_t *)vrtx_find_object_by_id(semid);    if (sem == NULL)	{	xnlock_put_irqrestore(&nklock,s);	*errp = ER_ID;	return;	}    *errp = RET_OK;    if (sem->count > 0)	sem->count--;    else	{	task = vrtx_current_task();	task->vrtxtcb.TCBSTAT = TBSSEMA;	if (timeout)	    task->vrtxtcb.TCBSTAT |= TBSDELAY;	xnsynch_sleep_on(&sem->synchbase,timeout);	if (xnthread_test_flags(&task->threadbase, XNRMID))	    *errp = ER_DEL; /* Semaphore deleted while pending. */	else if (xnthread_test_flags(&task->threadbase, XNTIMEO))	    *errp = ER_TMO; /* Timeout.*/	}    xnlock_put_irqrestore(&nklock,s);}void sc_saccept(int semid, int *errp){    vrtxsem_t *sem;    spl_t s;    xnlock_get_irqsave(&nklock,s);    sem = (vrtxsem_t *)vrtx_find_object_by_id(semid);    if (sem == NULL)	{	xnlock_put_irqrestore(&nklock,s);	*errp = ER_ID;	return;	}    if (sem->count > 0)	{	sem->count--;	}    else	{	*errp = ER_NMP;	}    xnlock_put_irqrestore(&nklock,s);}void sc_spost(int semid, int *errp){    xnthread_t *waiter;    vrtxsem_t *sem;    spl_t s;    xnlock_get_irqsave(&nklock,s);    sem = (vrtxsem_t *)vrtx_find_object_by_id(semid);    if (sem == NULL)	{	xnlock_put_irqrestore(&nklock,s);	*errp = ER_ID;	return;	}    *errp = RET_OK;    waiter = xnsynch_wakeup_one_sleeper(&sem->synchbase);    if (waiter)	{	xnpod_schedule();	}    else	{	if (sem->count == MAX_SEM_VALUE)	    {	    *errp = ER_OVF;	    }	else	    {	    sem->count++;	    }	}    xnlock_put_irqrestore(&nklock,s);}int sc_sinquiry (int semid, int *errp){    vrtxsem_t *sem;    int count;    spl_t s;    xnlock_get_irqsave(&nklock,s);    sem = (vrtxsem_t *)vrtx_find_object_by_id(semid);    if (sem == NULL)	{	*errp = ER_ID;	count = 0;	}    else	count = sem->count;    xnlock_put_irqrestore(&nklock,s);    *errp = RET_OK;        return count;}/* * IMPLEMENTATION NOTES: * * - Code executing on behalf of interrupt context is currently * allowed to scan the global vrtx semaphore queue (vrtxsemq). */

⌨️ 快捷键说明

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