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

📄 mqueue.inl

📁 ecos实时嵌入式操作系统
💻 INL
📖 第 1 页 / 共 2 页
字号:
// put() copies len bytes of *buf into the queue at priority prioCYGPRI_KERNEL_SYNCH_MQUEUE_INLINE Cyg_Mqueue::qerr_tCyg_Mqueue::put( const char *buf, size_t len, unsigned int prio, bool block#ifdef CYGFUN_KERNEL_THREADS_TIMER                 , cyg_tick_count timeout#endif               ){    CYG_REPORT_FUNCTYPE( "err=%d");    CYG_REPORT_FUNCARG4( "buf=%08x, len=%ld, prio=%ud, block=%d",                         buf, len, prio, block==true );    CYG_CHECK_DATA_PTRC( buf );    CYG_ASSERT_THISC();    CYG_PRECONDITIONC( len <= (size_t)msgsize );    qerr_t err;    struct qentry *qtmp, *qent;    // wait till a freelist entry is available    if ( true == block ) {#ifdef CYGFUN_KERNEL_THREADS_TIMER        if ( timeout != 0) {	    if ( false == putsem.wait(timeout) ) {                err = TIMEOUT;                goto exit;            }        }        else#endif        if ( false == putsem.wait() ) {            err = INTR;            goto exit;        }    } else {         if ( false == putsem.trywait() ) {            err = WOULDBLOCK;            goto exit;        }    }    // prevent preemption when fiddling with important members    Cyg_Scheduler::lock();    CYG_ASSERT_THISC();    // get a queue entry from the freelist    // don't need to check the freelist - the semaphore tells us there's    // definitely a usable non-busy one there. It's just a question of    // locating it.    if (!freelist->busy) { // fast-track common case        qent     = freelist;        freelist = freelist->next;    } else {        for ( qtmp=freelist; !qtmp->next->busy; qtmp=qtmp->next )            CYG_EMPTY_STATEMENT; // skip through        qent       = qtmp->next;        qtmp->next = qent->next;    }                // now put it in place in q    if ( NULL == q ) {        q = qent;        q->next = NULL;    } else {        struct qentry **qentp;        // insert into queue according to prio        for ( qentp=&q; NULL != *qentp; qentp = &((*qentp)->next) ) {            if ((*qentp)->priority < prio)                break;        } // for        qent->next = *qentp;        *qentp = qent;    } // else        qent->priority = prio; // have to set this now so when the sched is                           // unlocked, other qent's can be added in the                           // right place    qent->busy = true; // let things know this entry should be ignored until                       // it's finished having its data copied    // unlock the scheduler, and potentially switch threads, but    // that's okay now. We don't want it locked for the expensive memcpy    Cyg_Scheduler::unlock();    qent->buflen   = len;    memcpy( qent->buf(), buf, len );    // make available now - setting non-atomically is alright if you think    // about it - the only thing that matters is that it's completed before    // the post()    qent->busy = false;    // if we have to notify someone, we only do it if no-one's already    // sitting waiting for a message to appear, AND if it's a transition    // from empty to non-empty    if ( callback != NULL && !getsem.waiting() && (0 == getsem.peek()) ) {        getsem.post();                callback( *this, callback_data );    } else        getsem.post();            err = OK; exit:    CYG_ASSERT_THISC();    CYG_REPORT_RETVAL(err);    return err;} // Cyg_Mqueue::put()//------------------------------------------------------------------------// get() returns the oldest highest priority message in the queue in *buf// and sets *prio to the priority (if prio is non-NULL) and *len to the// actual message sizeCYGPRI_KERNEL_SYNCH_MQUEUE_INLINE Cyg_Mqueue::qerr_tCyg_Mqueue::get( char *buf, size_t *len, unsigned int *prio, bool block#ifdef CYGFUN_KERNEL_THREADS_TIMER                 , cyg_tick_count timeout#endif               ){    CYG_REPORT_FUNCTYPE( "err=%d");    CYG_REPORT_FUNCARG4( "buf=%08x, len=%08x, prio=%08x, block=%d",                         buf, len, prio, block==true );    CYG_CHECK_DATA_PTRC( buf );    CYG_CHECK_DATA_PTRC( len );    if ( NULL != prio )        CYG_CHECK_DATA_PTRC( prio );    CYG_ASSERT_THISC();    qerr_t err;    struct qentry *qent;    // wait till a q entry is available    if ( true == block ) {#ifdef CYGFUN_KERNEL_THREADS_TIMER        if ( timeout != 0) {            if ( false == getsem.wait(timeout) ) {                err = TIMEOUT;                goto exit;            }        }        else#endif        if ( false == getsem.wait() ) {            err = INTR;            goto exit;        }    } else {         if ( false == getsem.trywait() ) {            err = WOULDBLOCK;            goto exit;        }    }    // prevent preemption when fiddling with important members        Cyg_Scheduler::lock();        // don't need to check the q - the semaphore tells us there's    // definitely a usable non-busy one there. It's just a question of    // locating it.        if ( !q->busy ) {   // fast-track the common case        qent       = q;        q          = qent->next;    } else {        struct qentry *qtmp;        for ( qtmp=q; !qtmp->next->busy; qtmp=qtmp->next )            CYG_EMPTY_STATEMENT; // skip through        qent = qtmp->next;        qtmp->next = qent->next;    } // else    // now stick at front of freelist, but marked busy    qent->next = freelist;    freelist   = qent;    qent->busy = true; // don't let it truly be part of the freelist just yet                       // till the data is copied out    // unlock the scheduler, and potentially switch threads, but    // that's okay now. We don't want it locked for the expensive memcpy    Cyg_Scheduler::unlock();    *len  = qent->buflen;    if ( NULL != prio )        *prio = qent->priority;    memcpy( buf, qent->buf(), *len );    // make available now - setting non-atomically is alright if you think    // about it - the only thing that matters is that it's completed before    // the post()    qent->busy = false;    putsem.post();    err = OK; exit:    CYG_ASSERT_THISC();    CYG_REPORT_RETVAL(err);    return err;    } // Cyg_Mqueue::get()//------------------------------------------------------------------------// count() returns the number of messages in the queueinline longCyg_Mqueue::count(){    CYG_REPORT_FUNCTYPE("curmsgs=%d");        long curmsgs = (long)getsem.peek();    CYG_REPORT_RETVAL(curmsgs);    return curmsgs;    } // Cyg_Mqueue::count()//------------------------------------------------------------------------// Supply a callback function to call (with the supplied data argument)// when the queue goes from empty to non-empty (unless someone's already// doing a get()). This returns the old callback_fn, and if olddata is// non-NULL sets it to the old data (yes, really!)CYGPRI_KERNEL_SYNCH_MQUEUE_INLINE Cyg_Mqueue::callback_fn_tCyg_Mqueue::setnotify( callback_fn_t callback_fn, CYG_ADDRWORD data,                       CYG_ADDRWORD *olddata){    CYG_REPORT_FUNCTYPE("old callback=%08x");    CYG_REPORT_FUNCARG3XV( callback_fn, data, olddata );    if ( NULL != callback_fn )        CYG_CHECK_FUNC_PTRC( callback_fn );    if (NULL != olddata)        CYG_CHECK_DATA_PTRC( olddata );    callback_fn_t oldfn;    // Need to prevent preemption for accessing common structures    // Just locking the scheduler has the least overhead    Cyg_Scheduler::lock();    oldfn = callback;    if (NULL != olddata)        *olddata = callback_data;    callback_data = data;    callback      = callback_fn;    Cyg_Scheduler::unlock();    CYG_REPORT_RETVAL(oldfn);    return oldfn;}//------------------------------------------------------------------------#endif /* CYGONCE_KERNEL_MQUEUE_INL multiple inclusion protection *//* EOF mqueue.inl */

⌨️ 快捷键说明

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