OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [ecos-2.0/] [packages/] [kernel/] [v2_0/] [tests/] [mqueue1.cxx] - Rev 1773

Go to most recent revision | Compare with Previous | Blame | View Log

/*========================================================================
//
//      mqueue1.cxx
//
//      Message queues tests
//
//========================================================================
//####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-12
// Purpose:       This file provides tests for eCos mqueues
// Description:   
// Usage:         
//
//####DESCRIPTIONEND####
//
//======================================================================
*/
 
/* CONFIGURATION */
 
#include <pkgconf/kernel.h>
 
/* INCLUDES */
 
#include <cyg/infra/cyg_type.h>      // common types and externC
#include <cyg/kernel/thread.hxx>     // Cyg_Thread
#include <cyg/kernel/thread.inl>
// Specially avoid inlining here due to the way we abuse the mqueue
// implementation by making lots and lots of calls.
#define CYGPRI_KERNEL_SYNCH_MQUEUE_INLINE
#include <cyg/kernel/mqueue.hxx>     // Mqueue Header
#include <cyg/kernel/sema.hxx>       // semaphores
#include <cyg/infra/testcase.h>      // test API
 
// use the common kernel test magic to define 2 threads
#define NTHREADS 2
#include "testaux.hxx"
 
/* GLOBALS */
 
static char mempool[500];
static size_t storedmempoollen;
Cyg_Mqueue *mq;
static Cyg_Binary_Semaphore t0sem, t1sem;
static int calledback;
 
 
/* FUNCTIONS */
 
static int
my_memcmp(const void *m1, const void *m2, size_t n)
{
    char *s1 = (char *)m1;
    char *s2 = (char *)m2;
 
    while (n--) {
        if (*s1 != *s2)
            return *s1 - *s2;
        s1++;
        s2++;
    }
    return 0;
} // my_memcmp()
 
static void *
my_alloc( size_t len )
{
    if ( len > sizeof(mempool) )
        return NULL;
 
    storedmempoollen = len;
    return &mempool[0];
}
 
static void
my_free( void *ptr, size_t len )
{
    CYG_TEST_PASS_FAIL( (ptr == &mempool[0]) && (len == storedmempoollen), 
                        "Freed pool correctly");
    mq = NULL; // invalidate
}
 
static void
callback(Cyg_Mqueue &mq, CYG_ADDRWORD data)
{
    calledback += (int)data;
}
 
//************************************************************************
//************************************************************************
 
static void
t0( CYG_ADDRWORD data )
{
    Cyg_Mqueue::qerr_t err;
    char buf[35];
    size_t len;
    unsigned int prio;
    bool b;
 
    Cyg_Mqueue the_mq(4, 32, &my_alloc, &my_free, &err );
    CYG_TEST_PASS_FAIL( Cyg_Mqueue::OK == err,
                        "Create queue" );
    mq = &the_mq;
 
//------------------------------------------------------------------------
 
    err = mq->put( "Peter piper picked", sizeof("Peter piper picked"),
                   5, true );
    CYG_TEST_PASS_FAIL( Cyg_Mqueue::OK == err, "Simple (put)");
 
    t1sem.post();
 
//------------------------------------------------------------------------
 
    t0sem.wait();
 
    err = mq->get( buf, &len, &prio, true );
    b = (err == Cyg_Mqueue::OK);
    if (b)
        b = (len == sizeof("a peck of"));
    if (b)
        b = (prio == 100);
    if (b)
        b = (0 == 
             my_memcmp(buf, "a peck of", sizeof("a peck of"))
            );
    CYG_TEST_PASS_FAIL( b, "Blocking get");
 
//------------------------------------------------------------------------
 
    t0sem.wait();
 
    CYG_TEST_PASS_FAIL( 4 == mq->count(), "mq count" );
    err = mq->get( buf, &len, &prio, false );
    b = (err == Cyg_Mqueue::OK);
    if (b)
        b = (len == sizeof("pickled peppers"));
    if (b)
        b = (prio == 300);
    if (b)
        b = (0 == 
             my_memcmp(buf, "pickled peppers", sizeof("pickled peppers"))
            );
    if (b)
        b = (3 == mq->count());
    CYG_TEST_PASS_FAIL( b, "Prioritized (get 1)");
 
    err = mq->get( buf, &len, &prio, false );
    b = (err == Cyg_Mqueue::OK);
    if (b)
        b = (len == sizeof("."));
    if (b)
        b = (prio == 250);
    if (b)
        b = (0 == 
             my_memcmp(buf, ".", sizeof("."))
            );
    if (b)
        b = (2 == mq->count());
    CYG_TEST_PASS_FAIL( b, "Prioritized (get 2)");
 
    err = mq->get( buf, &len, &prio, false );
    b = (err == Cyg_Mqueue::OK);
    if (b)
        b = (len == 1);
    if (b)
        b = (prio == 225);
    if (b)
        b = (0 == 
             my_memcmp(buf, "", 1)
            );
    if (b)
        b = (1 == mq->count());
    CYG_TEST_PASS_FAIL( b, "Prioritized (get 3)");
 
    err = mq->get( buf, &len, &prio, false );
    b = (err == Cyg_Mqueue::OK);
    if (b)
        b = (len == sizeof("If Peter"));
    if (b)
        b = (prio == 200);
    if (b)
        b = (0 == 
             my_memcmp(buf, "If Peter", sizeof("If Peter"))
            );
    if (b)
        b = (0 == mq->count());
    CYG_TEST_PASS_FAIL( b, "Prioritized (get 4)");
 
//------------------------------------------------------------------------
 
    err = mq->get( buf, &len, &prio, false );
 
    CYG_TEST_PASS_FAIL( Cyg_Mqueue::WOULDBLOCK == err,
                        "Non-blocking get of empty queue" );
 
//------------------------------------------------------------------------
 
    Cyg_Mqueue::callback_fn_t oldcallback;
 
    oldcallback = mq->setnotify( &callback, (CYG_ADDRWORD) 42 );
 
    err = mq->put( "If Peter", sizeof("If Peter"),
                   200, false );
    CYG_TEST_PASS_FAIL( Cyg_Mqueue::OK == err,
                        "Prioritized (put in empty queue)");
    CYG_TEST_PASS_FAIL( 42 == calledback, "callback" );
    CYG_TEST_PASS_FAIL( NULL == oldcallback, "oldcallback" );
 
    err = mq->get( buf, &len, &prio, false );
    b = (err == Cyg_Mqueue::OK);
    if (b)
        b = (len == sizeof("If Peter"));
    if (b)
        b = (prio == 200);
    if (b)
        b = (0 == 
             my_memcmp(buf, "If Peter", sizeof("If Peter"))
            );
    CYG_TEST_PASS_FAIL( b, "Prioritized (get 2)");
 
    t1sem.post();
 
    err = mq->get( buf, &len, &prio, true );
    b = (err == Cyg_Mqueue::OK);
    if (b)
        b = (len == 32);
    if (b)
        b = (42 == calledback);
    if (b)
        b = (prio == 250);
    if (b)
        b = (0 == 
             my_memcmp(buf, "12345678901234567890123456789012", 32)
            );
    CYG_TEST_PASS_FAIL( b, "callback (blocked wait)");
 
//------------------------------------------------------------------------
 
    t1sem.post();
    t0sem.wait();
 
} // t0()
 
 
//************************************************************************
//************************************************************************
 
 
static void
t1( CYG_ADDRWORD data )
{
    Cyg_Mqueue::qerr_t err;
    char buf[35];
    size_t len;
    unsigned int prio;
    bool b;
 
//------------------------------------------------------------------------
 
    // wait till t0 says we can go
    t1sem.wait();
 
    err = mq->get( buf, &len, &prio, true );
    b = (err == Cyg_Mqueue::OK);
    if (b)
        b = (len == sizeof("Peter piper picked"));
    if (b)
        b = (prio == 5);
    if (b)
        b = (0 == 
             my_memcmp(buf, "Peter piper picked", sizeof("Peter piper picked"))
            );
 
    CYG_TEST_PASS_FAIL( b, "Simple");
 
//------------------------------------------------------------------------
 
    t0sem.post();         // t0 should run straight away
    Cyg_Thread::yield();  // but just in case we have a funny sched
 
    // by now t0 is blocked in mq->get
 
    err = mq->put( "a peck of", sizeof("a peck of"),
                   100, false );
    CYG_TEST_PASS_FAIL( Cyg_Mqueue::OK == err, "Block (put in empty queue)");
 
//------------------------------------------------------------------------
 
    err = mq->put( "If Peter", sizeof("If Peter"),
                   200, false );
    CYG_TEST_PASS_FAIL( Cyg_Mqueue::OK == err,
                        "Prioritized (put in empty queue)");
 
    err = mq->put( "pickled peppers", sizeof("pickled peppers"),
                   300, false );
    CYG_TEST_PASS_FAIL( Cyg_Mqueue::OK == err,
                        "Prioritized (put in queue w/1)");
 
    err = mq->put( ".", sizeof("."), 250, false );
    CYG_TEST_PASS_FAIL( Cyg_Mqueue::OK == err,
                        "Prioritized (put in queue w/2)");
 
    err = mq->put( "", 1, 225, false );
    CYG_TEST_PASS_FAIL( Cyg_Mqueue::OK == err,
                        "Prioritized (put in queue w/3)");
 
    err = mq->put( "foobar", 6, 1, false );
    CYG_TEST_PASS_FAIL( Cyg_Mqueue::WOULDBLOCK == err,
                        "Prioritized (full queue)");
 
    t0sem.post();
 
//------------------------------------------------------------------------
 
    t1sem.wait();
    Cyg_Thread::yield();  // but just in case we have a funny sched
 
    err = mq->put( "12345678901234567890123456789012xxxx", 32,
                   250, false );
    CYG_TEST_PASS_FAIL( Cyg_Mqueue::OK == err,
                        "callback (put in queue)");
 
//------------------------------------------------------------------------
 
    t1sem.wait();
 
    // Create an oversized queue
    {
        Cyg_Mqueue huge_mq(99999, 99999, &my_alloc, &my_free, &err );
        CYG_TEST_PASS_FAIL( Cyg_Mqueue::NOMEM == err,
                            "Oversized queue rejected" );
        // and it now gets destructed - but that shouldn't call free
        // to be called
    }
 
//------------------------------------------------------------------------
 
    t0sem.post();         // t0 should run straight away
    Cyg_Thread::yield();  // but just in case we have a funny sched
 
    // check that mq was destroyed when t0 dropped off the end
    CYG_TEST_PASS_FAIL( NULL == mq, "queue destroyed correctly" );
 
    CYG_TEST_EXIT("kernel mqueue test 1");
 
} // t1()
 
 
//************************************************************************
//************************************************************************
 
externC void
cyg_user_start(void)
{
#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
    cyg_hal_invoke_constructors();
#endif
    CYG_TEST_INIT();
 
    CYG_TEST_INFO( "Starting kernel mqueue test 1" );
    new_thread( t0, 0);
    new_thread( t1, 1);
 
#ifdef CYGIMP_THREAD_PRIORITY
    thread[0]->set_priority( 4 );
    thread[1]->set_priority( 5 ); // make sure the threads execute as intended
#endif
} // cyg_user_start()
 
//------------------------------------------------------------------------
 
 
/* EOF mqueue1.cxx */
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.