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

📄 mqueue.inl

📁 ecos实时嵌入式操作系统
💻 INL
📖 第 1 页 / 共 2 页
字号:
#ifndef CYGONCE_KERNEL_MQUEUE_INL#define CYGONCE_KERNEL_MQUEUE_INL/*========================================================================////      mqueue.inl////      Message queues implementation////========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.//// eCos 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 or (at your option) any later version.//// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):     jlarmour// Contributors:  // Date:          2000-05-09// Purpose:       This file provides the implementation for eCos message//                queues// Description:   This differs from the message boxes also supported//                by eCos primarily because the requirements of message//                queues are driven by POSIX semantics. POSIX semantics are//                more dynamic and therefore heavyweight than Mboxes,//                including prioritization, and variable sized queues and//                message lengths// Usage:         Do not include this file directly - instead//                #include <cyg/kernel/mqueue.hxx>////####DESCRIPTIONEND####////======================================================================*//* CONFIGURATION */#include <pkgconf/system.h>#include <pkgconf/kernel.h>          // Configuration header/* INCLUDES */#include <stddef.h>                  // size_t, NULL#include <cyg/infra/cyg_type.h>      // Types#include <cyg/kernel/mqueue.hxx>     // Header for this file, just in case#include <cyg/infra/cyg_ass.h>       // Assertion support#include <cyg/infra/cyg_trac.h>      // Tracing support#include <cyg/kernel/sched.hxx>      // scheduler#include <cyg/kernel/sched.inl>      // scheduler inlines#include <cyg/kernel/sema.hxx>       // Cyg_Counting_Semaphore#ifdef CYGPKG_ISOINFRA# include <string.h>                 // memcpy#elseexternC void * memcpy( void *, const void *, size_t );#endif// NOTE:// An alternative implementation based on mutexes and condition variables// rather than semaphores/scheduler locking was considered. But it was// not thought quite as good because it isn't driver safe. You would// also have to manage explicitly what counting semaphores do for you// intrinsically. Also with the mutex approach, the message queue would// be locked the whole time a new entry was being filled in, or copied out//// It also makes the non-blocking case properly non-blocking rather than// still being able to block while waiting for a mutex protecting// the message queue internal structures/* INLINE FUNCTIONS */#ifndef CYGPRI_KERNEL_SYNCH_MQUEUE_INLINE# define CYGPRI_KERNEL_SYNCH_MQUEUE_INLINE inline#endif//------------------------------------------------------------------------CYGPRI_KERNEL_SYNCH_MQUEUE_INLINE cyg_boolCyg_Mqueue::check_this( cyg_assert_class_zeal zeal ) const{    if (zeal != cyg_none) {        CYG_CHECK_DATA_PTRC(this);  // extreme paranoia#ifdef CYGDBG_USE_ASSERTS        if ( qlen <= 0 || msgsize <= 0 )            return false;#endif        if ( queuespacesize < sizeof(struct qentry)+1 )            return false;        CYG_CHECK_DATA_PTRC(queuespace);        CYG_CHECK_FUNC_PTRC(free_fn);        // prevent pre-emption through this. Not so bad since        // this is only a diagnostic function        Cyg_Scheduler::lock();        if (NULL != q)            CYG_CHECK_DATA_PTRC(q);        if (NULL != freelist)            CYG_CHECK_DATA_PTRC(freelist);        if (NULL != callback)            CYG_CHECK_FUNC_PTRC(callback);        // check each queue entry        long msgs=0, busymsgs=0;        unsigned int oldprio=0;        struct qentry *qtmp;        if ( NULL != q )            oldprio = q->priority;        for ( qtmp=q; NULL != qtmp; qtmp=qtmp->next ) {            if ( NULL != qtmp->next )                CYG_CHECK_DATA_PTRC( qtmp->next );            // queue should be priority ordered            if ( qtmp->priority > oldprio )                goto fail;            oldprio = qtmp->priority;            #ifdef CYGDBG_USE_ASSERTS            // valid length            if ( !qtmp->busy )                if ( qtmp->buflen > msgsize )                    goto fail;#endif            if ( qtmp->busy )                busymsgs++;            else                msgs++;        } // for                long freemsgs=0;                // check that number of used and unused messages == q length        for ( qtmp=freelist; NULL != qtmp; qtmp=qtmp->next ) {            if ( NULL != qtmp->next )                CYG_CHECK_DATA_PTRC( qtmp->next );            if ( qtmp->busy )                busymsgs++;            else                freemsgs++;        }#ifdef CYGDBG_USE_ASSERTS        // and sum of all messages should be the total q length        if ( qlen != (msgs+freemsgs+busymsgs) )            goto fail;#endif        Cyg_Scheduler::unlock();    }    return true; // object OK fail:    Cyg_Scheduler::unlock();    return false; // object fubar'd}//------------------------------------------------------------------------CYGPRI_KERNEL_SYNCH_MQUEUE_INLINECyg_Mqueue::Cyg_Mqueue( long maxmsgs, long maxmsgsize,                        qalloc_fn_t qalloc, qfree_fn_t qfree, qerr_t *err )    : putsem(maxmsgs), getsem(0){    CYG_REPORT_FUNCTION();    CYG_REPORT_FUNCARG5( "maxmsgs=%ld, maxmsgsize=%ld, qalloc=%08x, "                         "qfree=%08x, &err=%08x", maxmsgs, maxmsgsize,                         qalloc, qfree, err);    CYG_PRECONDITIONC( (maxmsgs > 0) && (maxmsgsize > 0) );    CYG_CHECK_DATA_PTRC( err );    CYG_CHECK_FUNC_PTRC( qalloc );    CYG_CHECK_FUNC_PTRC( qfree );    // mem to allocate for entire queue size. Also wants to be rounded    // up so that the structs are aligned.    const long addralign = sizeof(void *) - 1;    long entrysize = (sizeof(struct qentry) + maxmsgsize + addralign)       & ~addralign;    queuespacesize = entrysize * maxmsgs;    queuespace = qalloc( queuespacesize );    if (NULL == queuespace) {        *err=NOMEM;        CYG_REPORT_RETURN();        return;    }    // link up freelist    long i;    struct qentry *qtmp;    for ( i=0, qtmp=(struct qentry *)queuespace;          i<maxmsgs-1;          i++, qtmp=qtmp->next ) {        qtmp->busy = false;        qtmp->next = (struct qentry *)((char *)qtmp + entrysize);    } // for    freelist   = (struct qentry *)queuespace;    // set the last entry in the chain to the start to make the list circular    qtmp->next = NULL;    qtmp->busy = false;    callback   = NULL;    q          = NULL;    free_fn    = qfree;#ifdef CYGDBG_USE_ASSERTS    qlen       = maxmsgs;    msgsize    = maxmsgsize;#endif    *err = OK;    // object should be valid now    CYG_ASSERT_THISC();    CYG_REPORT_RETURN();}//------------------------------------------------------------------------CYGPRI_KERNEL_SYNCH_MQUEUE_INLINECyg_Mqueue::~Cyg_Mqueue(){    CYG_REPORT_FUNCTION();    if ( NULL != queuespace ) {        // object should be valid if queuespace was successfully allocated        CYG_ASSERT_THISC();        free_fn( queuespace, queuespacesize );    }#ifdef CYGDBG_USE_ASSERTS    qlen = msgsize = 0; // deliberately make it fail check_this() if used#endif    CYG_REPORT_RETURN();}//------------------------------------------------------------------------

⌨️ 快捷键说明

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