/* ** Copyright (C) 2004-2007 by Carnegie Mellon University. ** ** @OPENSOURCE_HEADER_START@ ** ** Use of the SILK system and related source code is subject to the terms ** of the following licenses: ** ** GNU Public License (GPL) Rights pursuant to Version 2, June 1991 ** Government Purpose License Rights (GPLR) pursuant to DFARS 252.225-7013 ** ** NO WARRANTY ** ** ANY INFORMATION, MATERIALS, SERVICES, INTELLECTUAL PROPERTY OR OTHER ** PROPERTY OR RIGHTS GRANTED OR PROVIDED BY CARNEGIE MELLON UNIVERSITY ** PURSUANT TO THIS LICENSE (HEREINAFTER THE "DELIVERABLES") ARE ON AN ** "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY ** KIND, EITHER EXPRESS OR IMPLIED AS TO ANY MATTER INCLUDING, BUT NOT ** LIMITED TO, WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE, ** MERCHANTABILITY, INFORMATIONAL CONTENT, NONINFRINGEMENT, OR ERROR-FREE ** OPERATION. CARNEGIE MELLON UNIVERSITY SHALL NOT BE LIABLE FOR INDIRECT, ** SPECIAL OR CONSEQUENTIAL DAMAGES, SUCH AS LOSS OF PROFITS OR INABILITY ** TO USE SAID INTELLECTUAL PROPERTY, UNDER THIS LICENSE, REGARDLESS OF ** WHETHER SUCH PARTY WAS AWARE OF THE POSSIBILITY OF SUCH DAMAGES. ** LICENSEE AGREES THAT IT WILL NOT MAKE ANY WARRANTY ON BEHALF OF ** CARNEGIE MELLON UNIVERSITY, EXPRESS OR IMPLIED, TO ANY PERSON ** CONCERNING THE APPLICATION OF OR THE RESULTS TO BE OBTAINED WITH THE ** DELIVERABLES UNDER THIS LICENSE. ** ** Licensee hereby agrees to defend, indemnify, and hold harmless Carnegie ** Mellon University, its trustees, officers, employees, and agents from ** all claims or demands made against them (and any related losses, ** expenses, or attorney's fees) arising out of, or relating to Licensee's ** and/or its sub licensees' negligent use or willful misuse of or ** negligent conduct or willful misconduct regarding the Software, ** facilities, or other rights or assistance granted by Carnegie Mellon ** University under this License, including, but not limited to, any ** claims of product liability, personal injury, death, damage to ** property, or violation of any laws or regulations. ** ** Carnegie Mellon University Software Engineering Institute authored ** documents are sponsored by the U.S. Department of Defense under ** Contract F19628-00-C-0003. Carnegie Mellon University retains ** copyrights in all material produced under this contract. The U.S. ** Government retains a non-exclusive, royalty-free license to publish or ** reproduce these documents, or allow others to do so, for U.S. ** Government purposes only pursuant to the copyright license under the ** contract clause at 252.227.7013. ** ** @OPENSOURCE_HEADER_END@ */ /* ** simple test code for skdeque library ** */ #include "silk.h" RCSIDENT("$SiLK: skdeque-test.c 6904 2007-04-14 13:00:08Z mthomas $"); #include "utils.h" #include "skdeque.h" #include "sklog.h" #define SKTHREAD_DEBUG_MUTEX 1 #include "skthread.h" static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t conda = PTHREAD_COND_INITIALIZER; static pthread_cond_t condb = PTHREAD_COND_INITIALIZER; static pthread_cond_t waitc = PTHREAD_COND_INITIALIZER; static int waita = 0; static int waitb = 0; static skDeque_t da, db, dc; static char *xa = "a"; static char *xb = "b"; static char *xc = "c"; static char *xx = "x"; static char *xy = "y"; static char *xz = "z"; #define DEBUG_PRINT(x) DEBUGMSG("<%s:%d> " x, skthread_name(), skthread_id()); #define SLEEP(x) \ do { \ DEBUGMSG("<%s:%d> Sleeping %d seconds", skthread_name(), \ skthread_id(), x); \ sleep(x); \ DEBUGMSG("<%s:%d> Finished sleeping", skthread_name(), \ skthread_id()); \ } while (0) static void starta() { MUTEX_LOCK(&mutex); { waita = 0; DEBUG_PRINT("C Broadcast A"); MUTEX_BROADCAST(&conda); } MUTEX_UNLOCK(&mutex); } static void startb() { MUTEX_LOCK(&mutex); { waitb = 0; DEBUG_PRINT("C Broadcast B"); MUTEX_BROADCAST(&condb); } MUTEX_UNLOCK(&mutex); } static void holda() { MUTEX_LOCK(&mutex); waita = 1; DEBUG_PRINT("A Broadcast C"); MUTEX_BROADCAST(&waitc); while (waita) { DEBUG_PRINT("A Waiting"); MUTEX_WAIT(&conda, &mutex); } DEBUG_PRINT("A Continuing"); MUTEX_UNLOCK(&mutex); } static void holdb() { MUTEX_LOCK(&mutex); waitb = 1; DEBUG_PRINT("B Broadcast C"); MUTEX_BROADCAST(&waitc); while (waitb) { DEBUG_PRINT("B Waiting"); MUTEX_WAIT(&condb, &mutex); } DEBUG_PRINT("B Continuing"); MUTEX_UNLOCK(&mutex); } static void meet() { MUTEX_LOCK(&mutex); while (!(waita && waitb)) { DEBUG_PRINT("C Waiting"); MUTEX_WAIT(&waitc, &mutex); } DEBUG_PRINT("C Continuing"); MUTEX_UNLOCK(&mutex); } static void *thread_a(void *UNUSED(dummy)) { skDQErr_t err; char *v; holda(); /* test 1 */ err = skDequePopFront(da, (void **)&v); assert(err == SKDQ_SUCCESS); assert(v == xa); holda(); /* test 2 */ err = skDequePopFront(da, (void **)&v); assert(err == SKDQ_SUCCESS); assert(v == xa); holda(); /* test 3 */ err = skDequePopBack(da, (void **)&v); assert(err == SKDQ_SUCCESS); assert(v == xa); holda(); return NULL; } static void *thread_b(void *UNUSED(dummy)) { skDQErr_t err; char *v; holdb(); /* Test 3 */ err = skDequePopBack(da, (void **)&v); assert(err == SKDQ_SUCCESS); assert(v == xb); holdb(); return NULL; } static void *thread_c(void *UNUSED(dummy)) { skDQErr_t err; meet(); INFOMSG("**** Test 1 ****"); err = skDequePushFront(da, xa); assert(err == SKDQ_SUCCESS); starta(); meet(); INFOMSG("**** Test 2 ****"); starta(); SLEEP(1); err = skDequePushFront(da, xa); assert(err == SKDQ_SUCCESS); meet(); INFOMSG("**** Test 3 ****"); starta(); SLEEP(1); startb(); SLEEP(1); err = skDequePushFront(da, xa); assert(err == SKDQ_SUCCESS); err = skDequePushFront(da, xb); assert(err == SKDQ_SUCCESS); meet(); /* End */ starta(); startb(); return NULL; } int main(int UNUSED(argc), char UNUSED(**argv)) { skDQErr_t err; pthread_t a, b, c; int rv; skAppRegister("skdeque-test"); skthread_init("main"); rv = sklogSetup(0); assert(rv == 0); rv = sklogSetDestination("stderr"); assert(rv == 0); rv = sklogOpen(); assert(rv == 0); rv = sklogSetLevel("debug"); assert(rv == 0); rv = sklogEnableThreadedLogging(); assert(rv == 0); da = skDequeCreate(); db = skDequeCreate(); dc = skDequeCreate(); char *v; /* Single threaded tests */ err = skDequePushFront(da, xa); assert(err == SKDQ_SUCCESS); err = skDequePushFront(db, xb); assert(err == SKDQ_SUCCESS); err = skDequePushFront(dc, xc); assert(err == SKDQ_SUCCESS); err = skDequePushFront(da, xx); assert(err == SKDQ_SUCCESS); err = skDequePushFront(db, xy); assert(err == SKDQ_SUCCESS); err = skDequePushFront(dc, xz); assert(err == SKDQ_SUCCESS); err = skDequePushBack(da, xa); assert(err == SKDQ_SUCCESS); err = skDequePushBack(db, xb); assert(err == SKDQ_SUCCESS); err = skDequePushBack(dc, xc); assert(err == SKDQ_SUCCESS); err = skDequePushBack(da, xx); assert(err == SKDQ_SUCCESS); err = skDequePushBack(db, xy); assert(err == SKDQ_SUCCESS); err = skDequePushBack(dc, xz); assert(err == SKDQ_SUCCESS); err = skDequePopFront(da, (void **)&v); assert(err == SKDQ_SUCCESS); assert(v == xx); err = skDequePopFront(da, (void **)&v); assert(err == SKDQ_SUCCESS); assert(v == xa); err = skDequePopFront(da, (void **)&v); assert(err == SKDQ_SUCCESS); assert(v == xa); err = skDequePopFront(da, (void **)&v); assert(err == SKDQ_SUCCESS); assert(v == xx); assert(skDequeStatus(da) == SKDQ_EMPTY); err = skDequePopBack(db, (void **)&v); assert(err == SKDQ_SUCCESS); assert(v == xy); err = skDequePopBack(db, (void **)&v); assert(err == SKDQ_SUCCESS); assert(v == xb); err = skDequePopBack(db, (void **)&v); assert(err == SKDQ_SUCCESS); assert(v == xb); err = skDequePopBack(db, (void **)&v); assert(err == SKDQ_SUCCESS); assert(v == xy); err = skDequePopFrontNB(dc, (void **)&v); assert(err == SKDQ_SUCCESS); assert(v == xz); err = skDequePopBackNB(dc, (void **)&v); assert(err == SKDQ_SUCCESS); assert(v == xz); err = skDequePopFrontNB(dc, (void **)&v); assert(err == SKDQ_SUCCESS); assert(v == xc); err = skDequePopBackNB(dc, (void **)&v); assert(err == SKDQ_SUCCESS); assert(v == xc); err = skDequePopBackNB(dc, (void **)&v); assert(err == SKDQ_EMPTY); /* Multi-threaded tests */ rv = skthread_create("a", &a, thread_a, NULL); assert(rv == 0); rv = skthread_create("b", &b, thread_b, NULL); assert(rv == 0); rv = skthread_create("c", &c, thread_c, NULL); assert(rv == 0); rv = pthread_join(a, NULL); assert(rv == 0); rv = pthread_join(b, NULL); assert(rv == 0); rv = pthread_join(c, NULL); assert(rv == 0); sklogClose(); sklogTeardown(); return 0; } /* ** Local Variables: ** mode:c ** indent-tabs-mode:nil ** c-basic-offset:4 ** End: */