| #include <stdio.h> | 
 | #include <stdlib.h> | 
 | #include <time.h> | 
 | #include <pthread.h> | 
 | #include <thread.h> | 
 | #include <spinlock.h> | 
 | #include <mutex.h> | 
 | #include <cond.h> | 
 | #include <rwlock.h> | 
 | #include <misc.h> | 
 |  | 
 | #define MAX_THREAD 1000 | 
 | #define N_THREAD 40 | 
 |  | 
 | int checkAbort = 0; | 
 |  | 
 | #define checkResults(string, val) {             \ | 
 |  if (val) {                                     \ | 
 |    printf("%d: Failed with %d at %s", GetCurrentThreadId(), val, string); \ | 
 |    if ( checkAbort )exit(1);                    \ | 
 |  }                                              \ | 
 | } | 
 | #define checkResultsL(string, val) {             \ | 
 |  if (val) {                                     \ | 
 |    printf("Failed with %d at %s", val, string); \ | 
 |  }                                              \ | 
 | } | 
 | #define checkResultsAlt(string, val, alt) {					\ | 
 |  if (val && !(val==alt)) {									\ | 
 |    printf("Failed with %d (%d) at %s", val, alt, string);	\ | 
 |    if ( checkAbort )exit(1);								\ | 
 |  }															\ | 
 | } | 
 |  | 
 | typedef struct { | 
 |     int id; | 
 | } parm; | 
 |  | 
 | struct timespec *starttimer(struct timespec *ts, DWORD ms) | 
 | { | 
 |     struct timeval    tp; | 
 |     /* Convert from timeval to timespec */ | 
 |     gettimeofday(&tp, NULL); | 
 |     ts->tv_sec  = tp.tv_sec; | 
 |     ts->tv_nsec = tp.tv_usec * 1000; | 
 |     ts->tv_sec += ms  / 1000; | 
 |     printf("starttimer, %d s=%ld\n",ms, ts->tv_sec); | 
 |     return ts; | 
 | } | 
 |  | 
 |  | 
 | void *hello(void *arg) | 
 | { | 
 |     parm *p=(parm *)arg; | 
 |     printf("Hello from node %d\n", p->id); | 
 |     pthread_exit(NULL); | 
 |     printf("Not reached from node %d\n", p->id); | 
 |      pthread_exit(NULL); | 
 |     return (NULL); | 
 | } | 
 |  | 
 | pthread_rwlock_t       rwlock; | 
 | char testType[100]; | 
 |  | 
 | /*================================================================================*/ | 
 | #define SPINLOCK_NTHREADS                50 | 
 | pthread_spinlock_t      spinlock; | 
 | int                     SLsharedData=0; | 
 | int                     SLsharedData2=0; | 
 |  | 
 | void *spinlock_threadfunc(void *parm) | 
 | { | 
 |    int   rc, d; | 
 |    int tid = pthread_self(); | 
 |    printf("Thread %d: Entered\n", tid); | 
 |    rc = pthread_spin_lock(&spinlock); | 
 |    d= SLsharedData; | 
 |    checkResults("pthread_spin_lock()\n", rc); | 
 |    /********** Critical Section *******************/ | 
 |    printf("Thread %d: Start critical section, holding lock\n", | 
 |           tid); | 
 |    /* Access to shared data goes here */ | 
 |    ++SLsharedData; --SLsharedData2; | 
 |    Sleep(50); | 
 |    printf("Thread %d: End critical section, release lock\n", | 
 |           tid); | 
 |    d -= (SLsharedData-1); | 
 |    /********** Critical Section *******************/ | 
 |    rc = pthread_spin_unlock(&spinlock); | 
 |    checkResults("pthread_spinlock_unlock()\n", rc); | 
 |    if (d) { | 
 |         printf("FAILED Thread %d: check SLsharedData=%d instead of 0\n", tid, d); | 
 |         exit(1); | 
 |    } | 
 |    return NULL; | 
 | } | 
 |   | 
 | int spinlock_main(void) | 
 | { | 
 |     pthread_t             thread[SPINLOCK_NTHREADS]; | 
 |     int                   rc=0; | 
 |     int                   i; | 
 |  | 
 |     printf("Enter Testcase - spinlock_main %s\n",testType); | 
 |     rc = pthread_spin_init(&spinlock, PTHREAD_PROCESS_SHARED); | 
 |     printf("Spinlock inited\n"); | 
 |     checkResults("pthread_spin_init()\n", rc); | 
 |  | 
 |     printf("Hold Spinlock to prevent access to shared data\n"); | 
 |     rc = pthread_spin_lock(&spinlock); | 
 |     printf("Unlock Spinlock to prevent access to shared data\n"); | 
 |     checkResults("pthread_spin_lock()\n", rc); | 
 |     rc = pthread_spin_unlock(&spinlock); | 
 |     checkResults("pthread_spin_unlock()\n",rc); | 
 |     printf("Hold Spinlock to prevent access to shared data 2\n"); | 
 |     rc = pthread_spin_lock(&spinlock); | 
 |     checkResults("pthread_spin_lock() 2\n", rc); | 
 |  | 
 |     printf("Create/start threads\n"); | 
 |     for (i=0; i<SPINLOCK_NTHREADS; ++i) { | 
 |         rc = pthread_create(&thread[i], NULL, spinlock_threadfunc, NULL); | 
 |         checkResults("pthread_create()\n", rc); | 
 |     } | 
 |  | 
 |     printf("Wait a bit until we are 'done' with the shared data\n"); | 
 |     Sleep(3000); | 
 |     printf("Unlock shared data\n"); | 
 |     rc = pthread_spin_unlock(&spinlock); | 
 |     checkResults("pthread_spin_lock()\n",rc); | 
 |  | 
 |     printf("Wait for the threads to complete, and release their resources\n"); | 
 |     for (i=0; i <SPINLOCK_NTHREADS; ++i) { | 
 |         rc = pthread_join(thread[i], NULL); | 
 |         checkResults("pthread_join()\n", rc); | 
 |     } | 
 |  | 
 |     printf("Clean up, data: %d %d\n",SLsharedData,SLsharedData2); | 
 |     rc = pthread_spin_destroy(&spinlock); | 
 |     printf("Main completed\n"); | 
 |     return 0; | 
 | } | 
 | /*================================================================================*/ | 
 | #define MUTEX_NTHREADS              5 | 
 | #define MUTEX_LOOPCNT				0 | 
 | pthread_mutex_t         mutex; | 
 | int                     sharedData=0; | 
 | int                     sharedData2=0; | 
 | int						mwait=30000; | 
 | int						init =0, destr=0; | 
 |  | 
 | void *mutex_threadfunc(void *parm) | 
 | { | 
 |    int   rc; | 
 |    int d; | 
 |    int tid = 0; | 
 |    printf("----------------------------\n"); | 
 |    //Sleep(1000); | 
 |     //mutex_print(&mutex,"Lock T A"); | 
 |     mutex_print(&mutex,"Lock T"); | 
 |    printf("----------------------------\n"); | 
 |    //Sleep(1000); | 
 |    //printf("Thread %d: Entered\n", tid); | 
 |  | 
 | rc = pthread_mutex_lock(&mutex); | 
 |    //mutex_print(&mutex,"Locked T"); | 
 |    d= sharedData; | 
 |    checkResults("pthread_mutex_lock()\n", rc); | 
 |    /********** Critical Section *******************/ | 
 |    printf("Thread %d: Start critical section, holding lock\n", | 
 |           tid); | 
 |    /* Access to shared data goes here */ | 
 |    ++sharedData; | 
 |    Sleep(500); | 
 |     --sharedData2; | 
 |    printf("Thread %d: End critical section, release lock\n", | 
 |           tid); | 
 |    d -= (sharedData-1); | 
 |    /********** Critical Section *******************/ | 
 |    //mutex_print(&mutex,"UnLock T"); | 
 |    rc = pthread_mutex_unlock(&mutex); | 
 |    //mutex_print(&mutex,"UnLocked T"); | 
 |    checkResults("pthread_mutex_unlock()\n", rc); | 
 |    if (d) { | 
 |         printf("FAILED Thread %d: check sharedData=%d instead of 0\n", tid, d); | 
 |         exit(1); | 
 |    } | 
 |  | 
 |  | 
 |  | 
 |    return NULL; | 
 | } | 
 |   | 
 | void *mutex_threadfunc_raced(void *parm) | 
 | { | 
 |    int   rc, rc1, i,j=0,x=0; | 
 |    int d; | 
 |    int rn; | 
 |    int tid = pthread_self(); | 
 |    struct timespec   ts; | 
 |  | 
 |    //printf("Thread %d: Entered\n", tid); | 
 |    while(1) { | 
 |        mutex_print(&mutex,"A pthread_mutex_lock"); | 
 |        //rc = pthread_mutex_timedlock(&mutex,starttimer(&ts, 8000 )); | 
 |        rc = pthread_mutex_lock(&mutex); | 
 |        mutex_print(&mutex,"B pthread_mutex_lock"); | 
 |        if (rc == ETIMEDOUT) { | 
 |            printf("FAILED Thread %d: pthread_mutex_timedlock ETIMEDOUT\n", tid); | 
 |            continue; | 
 |        } | 
 |        checkResults("pthread_mutex_timedlock()\n", rc); | 
 |        d= sharedData; | 
 |        /********** Critical Section *******************/ | 
 |        /* Access to shared data goes here */ | 
 |         ++sharedData; | 
 |         Sleep(100); | 
 |         --sharedData2; | 
 |        d -= (sharedData-1); | 
 |        /********** Critical Section *******************/ | 
 |        mutex_print(&mutex,"A pthread_mutex_unlock 0"); | 
 |        rc = pthread_mutex_unlock(&mutex); | 
 |  | 
 |        mutex_print(&mutex,"B pthread_mutex_unlock 0"); | 
 |         if(rc) { | 
 |             mutex_print(&mutex,"cant unlock 0"); | 
 |         } | 
 |        checkResults("pthread_mutex_unlock()\n", rc); | 
 |        if (d) { | 
 |             printf("FAILED Thread %d: check sharedData=%d instead of 0\n", tid, d); | 
 |             exit(1); | 
 |        } | 
 |        i = 0; | 
 |        mutex_print(&mutex, "A pthread_mutex_destroy 0"); | 
 |        rc=0;//rc = pthread_mutex_destroy(&mutex); | 
 |        mutex_print(&mutex,"B pthread_mutex_destroy 0"); | 
 |         if(rc) { | 
 |             mutex_print(&mutex,"cant destroy 0"); | 
 |             //break; | 
 |         } else { | 
 |             destr ++; | 
 |             mutex_print(&mutex,"destroyed 0"); | 
 |         } | 
 |         checkResultsAlt("pthread_mutex_destroy()\n", rc, EBUSY); | 
 |         do { | 
 |             mutex_print(&mutex,"A pthread_mutex_timedlock()"); | 
 |             //rc1 = pthread_mutex_lock(&mutex); | 
 |             rc1 = pthread_mutex_timedlock(&mutex,starttimer(&ts, 4000 )); | 
 |             mutex_print(&mutex,"B pthread_mutex_timedlock()"); | 
 |             //checkResults("pthread_mutex_lock() destroy\n", rc1); | 
 |             if(rc1) { | 
 |                 mutex_print(&mutex,"cant lock"); | 
 |                 break; | 
 |             } | 
 |             mutex_print(&mutex,"A pthread_mutex_unlock() 1"); | 
 |             rc1 = pthread_mutex_unlock(&mutex); | 
 |             mutex_print(&mutex,"B pthread_mutex_unlock() 1"); | 
 |             if(rc1) { | 
 |                 mutex_print(&mutex,"cant unlock"); | 
 |                 break; | 
 |             } | 
 |             //checkResults("pthread_mutex_unlock() destroy\n", rc1); | 
 |             mutex_print(&mutex, "A pthread_mutex_destroy 1"); | 
 |             rc=0;//rc = pthread_mutex_destroy(&mutex); | 
 |             mutex_print(&mutex, "B pthread_mutex_destroy 1"); | 
 |             if(rc) { | 
 |                 mutex_print(&mutex,"cant destroy"); | 
 |                 break; | 
 |             } else { | 
 |                 destr ++; | 
 |                 mutex_print(&mutex,"destroyed"); | 
 |             } | 
 |             checkResultsAlt("pthread_mutex_destroy() 2\n", rc, EBUSY); | 
 |             i ++; | 
 |        } while(rc == EBUSY); | 
 |         if(i)printf("Thread %d: destroy attempts: %d success: %d\n", tid,i,x); | 
 |         mutex_print(&mutex, "A pthread_mutex_init"); | 
 |         rc =0; //rc = pthread_mutex_init(&mutex,NULL); | 
 |         mutex_print(&mutex, "B pthread_mutex_init"); | 
 |         if(rc) { | 
 |             mutex_print(&mutex,"cant init"); | 
 |             break; | 
 |         } else { | 
 |             init ++; | 
 |             mutex_print(&mutex,"re-inited"); | 
 |         } | 
 |         checkResults("pthread_mutex_init()\n", rc); | 
 |  | 
 |        j++; | 
 |        if (j>MUTEX_LOOPCNT) { | 
 |             printf("Thread %d: Leaving\n", tid); | 
 |             break; | 
 |        } | 
 |    } | 
 |    return NULL; | 
 | } | 
 |   | 
 | static volatile LONG _tid=0; | 
 | void *mutex_threadfunc_timed(void *parm) | 
 | { | 
 |    int   rc; | 
 |    int d,e; | 
 |    int tid = pthread_self(); | 
 |    struct timespec   ts; | 
 |    printf("Thread %d: Entered\n", tid); | 
 |    mutex_print(&mutex,"Lock T"); | 
 |    if (rand() & 1) { | 
 |         rc = pthread_mutex_timedlock(&mutex,starttimer(&ts, 20000 )); | 
 |         checkResults("XX pthread_mutex_timedlock()\n", rc); | 
 |    } else { | 
 |         rc = pthread_mutex_lock(&mutex); | 
 |         checkResults("YY pthread_mutex_lock()\n", rc); | 
 |    } | 
 |    mutex_print(&mutex,"Locked T"); | 
 |    while (rc) { | 
 |         printf("%d: Lock failed with %d\n", tid, rc); | 
 |         rc = pthread_mutex_timedlock(&mutex,starttimer(&ts, 2000 )); | 
 |         mutex_print(&mutex,"Locked TR"); | 
 |    } | 
 |    /********** Critical Section *******************/ | 
 |    _tid = GetCurrentThreadId(); | 
 |    d= sharedData; | 
 |    printf("Thread %d: Start critical section, holding lock\n", | 
 |           tid); | 
 |    /* Access to shared data goes here */ | 
 |    ++sharedData; | 
 |    Sleep(100); | 
 |    if (_tid != tid) { | 
 |         printf("FAILED Thread %d: shared TID = %d\n", tid, _tid); | 
 |         mutex_print(&mutex,"Race cond"); | 
 |    } | 
 |    e = sharedData -1; | 
 |    --sharedData2; | 
 |    printf("Thread %d: End critical section, release lock\n", | 
 |           tid); | 
 |    d -= (e);  | 
 |    if (d) { | 
 |         printf("FAILED Thread %d: check sharedData=%d instead of 0\n", tid, d); | 
 |         mutex_print(&mutex,"Race cond"); | 
 |    } | 
 |    _tid = 0; | 
 |    /********** Critical Section *******************/ | 
 |    rc = pthread_mutex_unlock(&mutex); | 
 |    mutex_print(&mutex,"UnLocked T"); | 
 |    checkResults("pthread_mutex_unlock()\n", rc); | 
 |    return NULL; | 
 | } | 
 |   | 
 | /* PTHREAD_NORMAL_MUTEX_INITIALIZER deadlock handling thread 1 */ | 
 | void *mutex_threadfuncDL1(void *parm)  | 
 | { | 
 |    int   rc; | 
 |    int d; | 
 |    int tid = pthread_self(); | 
 |    printf("Thread %d: Entered, locking n1\n", tid); | 
 |    rc = pthread_mutex_lock(&mutex); | 
 |    checkResults("pthread_mutex_lock() 1\n", rc); | 
 |    printf("Thread %d: locked nr1\n", tid); | 
 |    Sleep(1000); | 
 |    printf("Thread %d: locking nr2 for a deadlock\n", tid); | 
 |    rc = pthread_mutex_lock(&mutex); | 
 |    checkResults("pthread_mutex_lock() 2\n", rc); | 
 |    printf("Thread %d: locked nr2 and externally unlocked\n", tid); | 
 |    /********** Critical Section *******************/ | 
 |    Sleep(2000); | 
 |    printf("Thread %d: Doing job\n", tid); | 
 |    Sleep(2000); | 
 |    printf("Thread %d: End critical section, release lock\n", tid); | 
 |    /********** Critical Section *******************/ | 
 |    rc = pthread_mutex_unlock(&mutex); | 
 |    checkResults("pthread_mutex_unlock()\n", rc); | 
 |    printf("Thread %d: leaving\n", tid); | 
 |    return NULL; | 
 | } | 
 |   | 
 | /* PTHREAD_NORMAL_MUTEX_INITIALIZER deadlock handling main thread */ | 
 | int mutex_main_DL(void) | 
 | { | 
 |    int   rc; | 
 |    int d; | 
 |    pthread_t thread; | 
 |    int tid = pthread_self(); | 
 |     rc = pthread_create(&thread, NULL, mutex_threadfuncDL1, NULL); | 
 |     checkResults("mutex_main_DL: pthread_create()\n", rc); | 
 |    printf("mutex_main_DL: wait for thread\n"); | 
 |    Sleep(3000); | 
 |    printf("mutex_main_DL: try ext release deadlock\n"); | 
 |  | 
 |    rc = pthread_mutex_unlock(&mutex); | 
 |    checkResults("pthread_mutex_unlock() ext\n", rc); | 
 |    printf("mutex_main_DL: unlocked 1\n"); | 
 |    Sleep(2000); | 
 |    //rc = pthread_mutex_unlock(&mutex); | 
 |    checkResults("pthread_mutex_unlock() ext 2\n", rc); | 
 |    printf("mutex_main_DL: unlocked 2\n"); | 
 |    Sleep(10000); | 
 |    printf("mutex_main_DL: bye!\n"); | 
 |  | 
 |    return 0; | 
 | } | 
 |   | 
 | int mutex_main_timed(void) | 
 | { | 
 |     pthread_t             thread[MUTEX_NTHREADS]; | 
 |     int                   rc=0; | 
 |     int                   i; | 
 |     struct timespec   ts; | 
 |  | 
 |     printf("Enter Testcase - mutex_main_timed %s\n",testType); | 
 |     mutex = PTHREAD_NORMAL_MUTEX_INITIALIZER; | 
 |     printf("Mutex inited\n"); | 
 |     rc = pthread_mutex_init (&mutex, NULL); | 
 |     checkResults("pthread_mutex_init()\n", rc); | 
 |        mutex_print(&mutex,"Locked 0"); | 
 |  | 
 |     printf("Hold Mutex to prevent access to shared data\n"); | 
 |       rc = pthread_mutex_lock(&mutex); | 
 |     //rc = pthread_mutex_timedlock(&mutex,starttimer(&ts, 30000 )); | 
 |        mutex_print(&mutex,"Locked 1"); | 
 |     printf("Mutex inited type=%d\n", ((mutex_t *)mutex)->type); | 
 |     printf("Unlock Mutex to prevent access to shared data\n"); | 
 |     checkResults("pthread_mutex_lock()\n", rc); | 
 |     rc = pthread_mutex_unlock(&mutex); | 
 |     checkResults("pthread_mutex_unlock()\n",rc); | 
 |     printf("Hold Mutex to prevent access to shared data 2\n"); | 
 |     mutex_print(&mutex,"Locked 2"); | 
 |     //rc = pthread_mutex_timedlock(&mutex,starttimer(&ts, 60000 )); | 
 |     rc = pthread_mutex_lock(&mutex); | 
 |     mutex_print(&mutex,"Locked 3"); | 
 |     checkResults("pthread_mutex_lock() 2\n", rc); | 
 |  | 
 |     printf("Create/start threads\n"); | 
 |     for (i=0; i<MUTEX_NTHREADS; ++i) { | 
 |         rc = pthread_create(&thread[i], NULL, mutex_threadfunc_timed, NULL); | 
 |         checkResults("pthread_create()\n", rc); | 
 |     } | 
 |  | 
 |     printf("Wait a bit until we are 'done' with the shared data\n"); | 
 |     Sleep(5000); | 
 |     printf("Unlock shared data\n"); | 
 |     rc = pthread_mutex_unlock(&mutex); | 
 |     checkResults("pthread_mutex_lock()\n",rc); | 
 |  | 
 |     printf("Wait for the threads to complete, and release their resources\n"); | 
 |     for (i=0; i <MUTEX_NTHREADS; ++i) { | 
 |         rc = pthread_join(thread[i], NULL); | 
 |         checkResults("pthread_join()\n", rc); | 
 |     } | 
 |  | 
 |     printf("Clean up, data: %d %d\n",sharedData,sharedData2); | 
 |     rc = pthread_mutex_destroy(&mutex); | 
 |     printf("Main completed\n"); | 
 |     return 0; | 
 | } | 
 |  | 
 | int mutex_main_raced(void) | 
 | { | 
 |     //pthread_t             thread[MUTEX_NTHREADS]; | 
 |     pthread_t             *thread; | 
 |     int                   rc=0; | 
 |     int                   i, f=0, F=0; | 
 |     struct timespec   ts; | 
 |  | 
 |     mutex_print_set(1); | 
 |     checkAbort = 0; | 
 |     thread = (pthread_t *)calloc(MUTEX_NTHREADS, sizeof(pthread_t)); | 
 |     printf("Enter Testcase - mutex_main_raced %s\n",testType); | 
 |     mutex = PTHREAD_NORMAL_MUTEX_INITIALIZER; | 
 |     printf("Mutex inited\n"); | 
 |  | 
 |     printf("Hold Mutex to prevent access to shared data\n"); | 
 |     //rc = pthread_mutex_timedlock(&mutex,starttimer(&ts, 3000000 )); | 
 |     rc = pthread_mutex_lock(&mutex); | 
 |     printf("Mutex inited type=%d\n", ((mutex_t *)mutex)->type); | 
 |     printf("Unlock Mutex to prevent access to shared data\n"); | 
 |     checkResults("pthread_mutex_timedlock()\n", rc); | 
 |     rc = pthread_mutex_unlock(&mutex); | 
 |     checkResults("pthread_mutex_unlock() 1\n",rc); | 
 |     printf("Hold Mutex to prevent access to shared data 2\n"); | 
 |     //rc = pthread_mutex_timedlock(&mutex,starttimer(&ts, 3000000 )); | 
 |     rc = pthread_mutex_lock(&mutex); | 
 |     checkResults("pthread_mutex_timedlock() 2\n", rc); | 
 |  | 
 |     rc = pthread_mutex_unlock(&mutex); | 
 |     checkResults("pthread_mutex_unlock() 2\n",rc); | 
 |     printf("Create/start threads\n"); | 
 |     Sleep(1000); | 
 |     for (i=0; i<MUTEX_NTHREADS; ++i) { | 
 |         rc = pthread_create(&thread[i], NULL, mutex_threadfunc_raced, NULL); | 
 |         checkResults("pthread_create()\n", rc); | 
 |     } | 
 |  | 
 |     printf("Wait a bit until we are 'done' with the shared data\n"); | 
 |     printf("Unlock shared data\n"); | 
 |     printf("Wait for the threads to complete, and release their resources\n"); | 
 |     Sleep(40000); | 
 |     printf("Done\n"); | 
 |     mutex_print(&mutex,"Done"); | 
 |     do { | 
 |         f = 0; | 
 |         for (i=0; i <MUTEX_NTHREADS; ++i) { | 
 |             if( thread[i] ) { | 
 |                 rc = pthread_join(thread[i], NULL); | 
 |                 if (rc) { | 
 |                     f++; | 
 |                     printf("_pthread_tryjoin failed: %d %d %d\n",i, rc,thread[i]); | 
 |                 } else { | 
 |                     thread[i] = 0; | 
 |                     printf("_pthread_tryjoin OK: %d\n",i); | 
 |                 } | 
 |             } | 
 |         } | 
 |         printf("Joins failed: %d destr: %d init: %d\n",f,destr,init); | 
 |         F += f; | 
 |         Sleep(1000); | 
 |     } while (0); | 
 |  | 
 |     printf("Joins total failed: %d destr: %d init: %d\n",F,destr,init); | 
 |     printf("Clean up, data: %d %d\n",sharedData,sharedData2); | 
 |     mutex_print(&mutex, "A Clean up"); | 
 |     rc = pthread_mutex_destroy(&mutex); | 
 |     mutex_print(&mutex, "B Clean up"); | 
 |     // Removed in r4392: printf("Main completed spincount = %d\n", _spin_lite_getsc(0)); | 
 |     // Removed in r4392: printf("Main completed spinlocks = %d\n", _spin_lite_getbsc(0)); | 
 |     // Removed in r4392: printf("Main completed Max spincount = %d\n", _spin_lite_getscMax(0)); | 
 |     // Removed in r4392: printf("Main completed Avg spincount/thread = %f\n", (float)((float)_spin_lite_getsc(0)/(float)MUTEX_NTHREADS)); | 
 |     return 0; | 
 | } | 
 |  | 
 |   | 
 | int mutex_main_static(void) | 
 | { | 
 |     pthread_t             thread[MUTEX_NTHREADS]; | 
 |     int                   rc=0; | 
 |     int                   i; | 
 |     struct timespec   ts; | 
 |  | 
 |     printf("mutex_main_static: Hold Mutex to prevent access to shared data o=%d\n",0); | 
 |     mutex_print(&mutex,"Lock"); | 
 |     rc = pthread_mutex_lock(&mutex); | 
 |     mutex_print(&mutex,"Locked"); | 
 |     printf("Mutex inited type=%d o=%d\n", ((mutex_t *)mutex)->type,GET_OWNER(((mutex_t *)mutex))); | 
 |     printf("Unlock Mutex to prevent access to shared data\n"); | 
 |     checkResults("pthread_mutex_lock()\n", rc); | 
 |     rc = pthread_mutex_unlock(&mutex); | 
 |     mutex_print(&mutex,"UnLocked"); | 
 |     printf("Unlocked Mutex to prevent access to shared data o=%d\n",GET_OWNER(((mutex_t *)mutex))); | 
 |     checkResults("pthread_mutex_unlock()\n",rc); | 
 |     printf("Hold Mutex to prevent access to shared data 2\n"); | 
 |     rc = pthread_mutex_lock(&mutex); | 
 |     checkResults("pthread_mutex_lock() 2\n", rc); | 
 |     mutex_print(&mutex,"Locked 2"); | 
 |     printf("Create/start threads\n"); | 
 |     for (i=0; i<MUTEX_NTHREADS; ++i) { | 
 |         rc = pthread_create(&thread[i], NULL, mutex_threadfunc, NULL); | 
 |         checkResults("pthread_create()\n", rc); | 
 |     } | 
 |  | 
 |     printf("Wait a bit until we are 'done' with the shared data\n"); | 
 |     Sleep(3000); | 
 |     printf("Unlock shared data\n"); | 
 |     rc = pthread_mutex_unlock(&mutex); | 
 |     mutex_print(&mutex,"UnLocked 2"); | 
 |     checkResults("pthread_mutex_unlock()\n",rc); | 
 |     return 0; | 
 | } | 
 | int mutex_main(void) | 
 | { | 
 |     pthread_t             *thread; | 
 |     int                   rc=0; | 
 |     int                   i; | 
 |  | 
 |     int tid = 0; | 
 |      mutex_print_set(1); | 
 |      thread = (pthread_t *)calloc(MUTEX_NTHREADS, sizeof(pthread_t)); | 
 |      printf("Main thread %d: Entered\n", tid); | 
 |     printf("Enter Testcase - mutex_main %s\n",testType); | 
 |     if (strcmp(testType,"static") == 0) { | 
 |         mutex = PTHREAD_DEFAULT_MUTEX_INITIALIZER; | 
 |         return mutex_main_static(); | 
 |     } else if (strcmp(testType,"staticN") == 0) { | 
 |         mutex = PTHREAD_NORMAL_MUTEX_INITIALIZER; | 
 |     } else if (strcmp(testType,"staticND") == 0) { | 
 |         mutex = PTHREAD_NORMAL_MUTEX_INITIALIZER; | 
 |         return mutex_main_DL(); | 
 |     } else if (strcmp(testType,"staticE") == 0) { | 
 |         mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER; | 
 |     } else if (strcmp(testType,"staticR") == 0) { | 
 |         mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; | 
 |     } else if (strcmp(testType,"timed") == 0) { | 
 |         mutex = PTHREAD_NORMAL_MUTEX_INITIALIZER; | 
 |         return mutex_main_timed(); | 
 |     } else if (strcmp(testType,"raced") == 0) { | 
 |         mutex = PTHREAD_NORMAL_MUTEX_INITIALIZER; | 
 |         return mutex_main_raced(); | 
 |     } else { | 
 |         rc = pthread_mutex_init(&mutex,NULL); | 
 |         printf("Mutex inited\n"); | 
 |         checkResults("pthread_mutex_init()\n", rc); | 
 |     } | 
 |  | 
 |     printf("Hold Mutex to prevent access to shared data o=%d\n",0); | 
 |     mutex_print(&mutex,"Lock"); | 
 |     rc = pthread_mutex_lock(&mutex); | 
 |     mutex_print(&mutex,"Locked"); | 
 |     printf("Mutex inited type=%d o=%d\n", ((mutex_t *)mutex)->type,GET_OWNER(((mutex_t *)mutex))); | 
 |     printf("Unlock Mutex to prevent access to shared data\n"); | 
 |     checkResults("pthread_mutex_lock()\n", rc); | 
 |     rc = pthread_mutex_unlock(&mutex); | 
 |     mutex_print(&mutex,"UnLocked"); | 
 |     printf("Unlocked Mutex to prevent access to shared data o=%d\n",GET_OWNER(((mutex_t *)mutex))); | 
 |     checkResults("pthread_mutex_unlock()\n",rc); | 
 |     printf("Hold Mutex to prevent access to shared data 2\n"); | 
 |     rc = pthread_mutex_lock(&mutex); | 
 |     checkResults("pthread_mutex_lock() 2\n", rc); | 
 |     mutex_print(&mutex,"Locked 2"); | 
 |     printf("Create/start threads\n"); | 
 |     for (i=0; i<MUTEX_NTHREADS; ++i) { | 
 |         rc = pthread_create(&thread[i], NULL, mutex_threadfunc, NULL); | 
 |         checkResults("pthread_create()\n", rc); | 
 |     } | 
 |  | 
 |     printf("Wait a bit until we are 'done' with the shared data\n"); | 
 |     Sleep(3000); | 
 |     printf("Unlock shared data\n"); | 
 |     rc = pthread_mutex_unlock(&mutex); | 
 |     mutex_print(&mutex,"UnLocked 2"); | 
 |     checkResults("pthread_mutex_unlock()\n",rc); | 
 |  | 
 |     printf("Wait for the threads to complete, and release their resources\n"); | 
 |     for (i=0; i <MUTEX_NTHREADS; ++i) { | 
 |         rc = pthread_join(thread[i], NULL); | 
 |         checkResults("pthread_join()\n", rc); | 
 |     } | 
 |  | 
 |     printf("Clean up, data: %d %d\n",sharedData,sharedData2); | 
 |     rc = pthread_mutex_destroy(&mutex); | 
 |     printf("Main completed\n"); | 
 |     Sleep(6000); | 
 |     return 0; | 
 | } | 
 | #if 1 | 
 | /*================================================================================*/ | 
 | #define COND_NTHREADS                3 | 
 | #define COND_WAIT_TIME_SECONDS       10 | 
 |  | 
 | int                 workToDo = 0; | 
 | int                 workLeave = 0; | 
 | pthread_cond_t      cond; | 
 | pthread_mutex_t     mutex; | 
 |  | 
 | void *condTimed_threadfunc(void *parm) | 
 | { | 
 |   int               tid; | 
 |   int               rc; | 
 |   struct timespec   ts; | 
 |   struct timeval    tp; | 
 |  | 
 |   rc = pthread_mutex_lock(&mutex); | 
 |   checkResults("pthread_mutex_lock()\n", rc); | 
 |   tid = pthread_self(); | 
 |  | 
 |   /* Usually worker threads will loop on these operations */ | 
 |   while (!workLeave) { | 
 |     rc =  gettimeofday(&tp, NULL); | 
 |     checkResults("gettimeofday()\n", rc); | 
 |  | 
 |     /* Convert from timeval to timespec */ | 
 |     ts.tv_sec  = tp.tv_sec; | 
 |     ts.tv_nsec = tp.tv_usec * 1000; | 
 |     ts.tv_sec += COND_WAIT_TIME_SECONDS; | 
 |  | 
 |     do { | 
 |       if (strcmp(testType,"notTimed") == 0) { | 
 |         printf("Thread %d blocked, notTimed\n", tid); | 
 |         rc = pthread_cond_wait(&cond, &mutex); | 
 |       } else { | 
 |         printf("Thread %d blocked and waiting\n", tid); | 
 |         rc = pthread_cond_timedwait(&cond, &mutex, starttimer(&ts, 6000 )); | 
 |       } | 
 |       /* If the wait timed out, in this example, the work is complete, and   */ | 
 |       /* the thread will end.                                                */ | 
 |       /* In reality, a timeout must be accompanied by some sort of checking  */ | 
 |       /* to see if the work is REALLY all complete. In the simple example    */ | 
 |       /* we'll just go belly up when we time out.                            */ | 
 |       printf("Thread %d unblocked\n", tid); | 
 |       if (rc == ETIMEDOUT) { | 
 |         printf("Wait %d timed out!\n", tid); | 
 |         rc = pthread_mutex_unlock(&mutex); | 
 |         checkResults("pthread_mutex_unlock() A\n", rc); | 
 |         printf("Exit %d\n", tid); | 
 |         pthread_exit(NULL); | 
 |       } | 
 |       checkResults("pthread_cond_timedwait()\n", rc); | 
 |     } while (!workLeave && !workToDo);  | 
 |     if (workToDo) { | 
 |         printf("Thread %d consumes work here\n", tid); | 
 |         Sleep(2000); | 
 |         workToDo = 0; | 
 |     } | 
 |   }  | 
 |   printf("Thread %d leaves here\n", tid); | 
 |   rc = pthread_mutex_unlock(&mutex); | 
 |   checkResults("pthread_mutex_unlock() B\n", rc); | 
 |   return NULL; | 
 | } | 
 |  | 
 | int condTimed_main() | 
 | { | 
 |   int                   rc=0; | 
 |   int                   i; | 
 |   pthread_t             threadid[COND_NTHREADS]; | 
 |   struct timespec   ts; | 
 |  | 
 |   printf("Enter Testcase - condTimed_main %s\n",testType); | 
 |  | 
 |   rc = pthread_mutex_init (&mutex, NULL); | 
 |   checkResults("pthread_mutex_init()\n", rc); | 
 |      | 
 |   rc = pthread_cond_init (&cond, NULL); | 
 |   checkResults("pthread_cond_init()\n", rc); | 
 |      | 
 |   rc = pthread_mutex_lock(&mutex); | 
 |   checkResults("pthread_mutex_lock()\n", rc); | 
 |  | 
 |   printf("Try steal a signal 1 (wait on own signal), should timeout\n"); | 
 |   rc = pthread_cond_broadcast(&cond); | 
 |   checkResults("pthread_cond_signal()\n", rc); | 
 |  | 
 |   rc = pthread_cond_timedwait(&cond, &mutex, starttimer(&ts, 3000 )); | 
 |   printf("rc=%d\n",rc); | 
 |   checkResults("pthread_cond_timedwait() Steal 1\n", rc - ETIMEDOUT); | 
 |   printf("Done, rc=%d\n",rc); | 
 |   rc = pthread_mutex_unlock(&mutex); | 
 |  | 
 |   printf("Create %d threads\n", COND_NTHREADS); | 
 |   for(i=0; i<COND_NTHREADS; ++i) { | 
 |     rc = pthread_create(&threadid[i], NULL, condTimed_threadfunc, NULL); | 
 |     checkResults("pthread_create()\n", rc); | 
 |   } | 
 |   Sleep(2000); | 
 |   printf("One work item to give to a thread\n"); | 
 |   workToDo = 1; | 
 |   rc = pthread_mutex_lock(&mutex); | 
 |   rc = pthread_cond_signal(&cond); | 
 |   checkResults("pthread_cond_signal()\n", rc); | 
 |   rc = pthread_mutex_unlock(&mutex); | 
 |   checkResults("pthread_mutex_unlock()\n", rc); | 
 |  | 
 |   Sleep(3001); | 
 |   rc = pthread_mutex_lock(&mutex); | 
 |   checkResults("pthread_mutex_lock() 2\n", rc); | 
 |   printf("One another work item to give to a thread\n"); | 
 |   workToDo = 1; | 
 |   rc = pthread_cond_signal(&cond); | 
 |   checkResults("pthread_cond_signal()\n", rc); | 
 |  | 
 |   rc = pthread_mutex_unlock(&mutex); | 
 |   checkResults("pthread_mutex_unlock()\n", rc); | 
 |  | 
 |   //Sleep(10000); | 
 |   printf("Broadcast leave to all threads, waiters=%d\n",((cond_t *)cond)->waiters_count_); | 
 |   workLeave = 1; | 
 |   rc = pthread_cond_broadcast(&cond); | 
 |    printf("Broadcast done, waiters=%d\n",((cond_t *)cond)->waiters_count_); | 
 |   checkResults("pthread_cond_broadcast()\n", rc); | 
 |   printf("Try steal a signal 2, should timeout\n"); | 
 |   rc = pthread_mutex_lock(&mutex); | 
 |   printf("pthread_mutex_lock, waiters=%d\n",((cond_t *)cond)->waiters_count_); | 
 |   rc = pthread_cond_timedwait(&cond, &mutex, starttimer(&ts, 3000 )); | 
 |   printf("pthread_cond_timedwait, waiters=%d\n",((cond_t *)cond)->waiters_count_); | 
 |   checkResults("pthread_cond_timedwait() Steal 2\n", rc - ETIMEDOUT); | 
 |   printf("Done, rc=%d\n",rc); | 
 |   rc = pthread_mutex_unlock(&mutex); | 
 |  | 
 |   printf("Wait for threads and cleanup\n"); | 
 |   for (i=0; i<COND_NTHREADS; ++i) { | 
 |     rc = pthread_join(threadid[i], NULL); | 
 |     checkResults("pthread_join()\n", rc); | 
 |   } | 
 |  | 
 |   printf("Exit, waiters=%d\n",((cond_t *)cond)->waiters_count_); | 
 |   pthread_cond_destroy(&cond); | 
 |   pthread_mutex_destroy(&mutex); | 
 |   printf("Main completed\n"); | 
 |   return 0; | 
 | } | 
 | #else | 
 | /*================================================================================*/ | 
 |  | 
 | #define COND_NTHREADS                3 | 
 | #define COND_WAIT_TIME_SECONDS       10 | 
 |  | 
 | int                 workToDo = 0; | 
 | int                 workLeave = 0; | 
 | pthread_cond_t      cond=PTHREAD_COND_INITIALIZER; | 
 | pthread_mutex_t     mutex=PTHREAD_MUTEX_INITIALIZER; | 
 |  | 
 | void *condTimed_threadfunc(void *parm) | 
 | { | 
 |   int               tid; | 
 |   int               rc; | 
 |   struct timespec   ts; | 
 |   struct timeval    tp; | 
 |  | 
 |   rc = pthread_mutex_lock(&mutex); | 
 |   checkResults("pthread_mutex_lock()\n", rc); | 
 |   tid = pthread_self(); | 
 |  | 
 |   /* Usually worker threads will loop on these operations */ | 
 |   printf("condTimed_threadfunc, wait %d secs\n", COND_WAIT_TIME_SECONDS); | 
 |   while (!workLeave) { | 
 |     rc =  gettimeofday(&tp, NULL); | 
 |     checkResults("gettimeofday()\n", rc); | 
 |  | 
 |     /* Convert from timeval to timespec */ | 
 |     ts.tv_sec  = tp.tv_sec; | 
 |     ts.tv_nsec = tp.tv_usec * 1000; | 
 |     ts.tv_sec += COND_WAIT_TIME_SECONDS; | 
 |  | 
 |     do { | 
 |       if (strcmp(testType,"notTimed") == 0) { | 
 |         printf("Thread %d blocked, notTimed\n", tid); | 
 |         rc = pthread_cond_wait(&cond, &mutex); | 
 |       } else { | 
 |         printf("Thread %d blocked\n", tid); | 
 |         rc = pthread_cond_timedwait(&cond, &mutex, starttimer(&ts, 3000 )); | 
 |       } | 
 |       /* If the wait timed out, in this example, the work is complete, and   */ | 
 |       /* the thread will end.                                                */ | 
 |       /* In reality, a timeout must be accompanied by some sort of checking  */ | 
 |       /* to see if the work is REALLY all complete. In the simple example    */ | 
 |       /* we'll just go belly up when we time out.                            */ | 
 |       printf("Thread %d unblocked\n", tid); | 
 |       if (rc == ETIMEDOUT) { | 
 |         printf("Wait %d timed out!\n", tid); | 
 |         rc = pthread_mutex_unlock(&mutex); | 
 |         checkResults("pthread_mutex_unlock() A\n", rc); | 
 |         printf("Exit %d\n", tid); | 
 |         pthread_exit(NULL); | 
 |       } | 
 |       checkResults("pthread_cond_timedwait()\n", rc); | 
 |     } while (!workLeave && !workToDo);  | 
 |     if (workToDo) { | 
 |         printf("Thread %d consumes work here\n", tid); | 
 |         Sleep(2000); | 
 |         workToDo = 0; | 
 |     } | 
 |   }  | 
 |   printf("Thread %d leaves here\n", tid); | 
 |   rc = pthread_mutex_unlock(&mutex); | 
 |   checkResults("pthread_mutex_unlock() B\n", rc); | 
 |   return NULL; | 
 | } | 
 |  | 
 | int condTimed_main() | 
 | { | 
 |   int                   rc=0; | 
 |   int                   i; | 
 |   pthread_t             threadid[COND_NTHREADS]; | 
 |   struct timespec   ts; | 
 |  | 
 |     printf("Enter Testcase - condTimed_main %s\n",testType); | 
 |  | 
 |     if (strcmp(testType,"static") == 0) { | 
 |         printf("cond + mutex static initialized\n"); | 
 |         strcpy(testType, "notTimed"); | 
 |     } else { | 
 |       rc = pthread_mutex_init (&mutex, NULL); | 
 |       checkResults("pthread_mutex_init()\n", rc); | 
 |      | 
 |       rc = pthread_cond_init (&cond, NULL); | 
 |       checkResults("pthread_cond_init()\n", rc); | 
 |         printf("cond + mutex normal initialized\n"); | 
 |     } | 
 |  | 
 |      | 
 |   rc = pthread_mutex_lock(&mutex); | 
 |   checkResults("pthread_mutex_lock()\n", rc); | 
 |     printf("Mutex locked \n"); | 
 |  | 
 |   printf("Try steal a signal 1, should timeout\n"); | 
 |    | 
 |   printf("Timed wait 1, waiters=%d\n",cond->waiters_count_); | 
 |   rc = pthread_cond_timedwait(&cond, &mutex, starttimer(&ts, 3000 )); | 
 |   printf("rc=%d\n",rc); | 
 |   checkResults("pthread_cond_timedwait() Steal 1\n", rc - ETIMEDOUT); | 
 |   printf("Done, rc=%d\n",rc); | 
 |   rc = pthread_mutex_unlock(&mutex); | 
 |  | 
 |   printf("Create %d threads\n", COND_NTHREADS); | 
 |   for(i=0; i<COND_NTHREADS; ++i) { | 
 |     rc = pthread_create(&threadid[i], NULL, condTimed_threadfunc, NULL); | 
 |     checkResults("pthread_create()\n", rc); | 
 |   } | 
 |   Sleep(2000); | 
 |   printf("One work item to give to a thread\n"); | 
 |   workToDo = 1; | 
 |   rc = pthread_mutex_lock(&mutex); | 
 |   printf("Mutex locked 2\n"); | 
 |   rc = pthread_cond_signal(&cond); | 
 |   checkResults("pthread_cond_signal()\n", rc); | 
 |   rc = pthread_mutex_unlock(&mutex); | 
 |   checkResults("pthread_mutex_unlock()\n", rc); | 
 |  | 
 |   //Sleep(1000); | 
 |   rc = pthread_mutex_lock(&mutex); | 
 |   checkResults("pthread_mutex_lock() 2\n", rc); | 
 |   printf("One another work item to give to a thread\n"); | 
 |   workToDo = 1; | 
 |   rc = pthread_cond_signal(&cond); | 
 |   checkResults("pthread_cond_signal()\n", rc); | 
 |  | 
 |   rc = pthread_mutex_unlock(&mutex); | 
 |   checkResults("pthread_mutex_unlock()\n", rc); | 
 |  | 
 |   //Sleep(1000); | 
 |   printf("Broadcast leave to all threads, waiters=%d\n",cond->waiters_count_); | 
 |   workLeave = 1; | 
 |   rc = pthread_cond_broadcast(&cond); | 
 |   //Sleep(1000); | 
 |   printf("Broadcast done, waiters=%d\n",cond->waiters_count_); | 
 |   checkResults("pthread_cond_broadcast()\n", rc); | 
 |   printf("Try steal a signal 2, should timeout\n"); | 
 |   rc = pthread_mutex_lock(&mutex); | 
 |   printf("Timed wait 2, waiters=%d\n",cond->waiters_count_); | 
 |   rc = pthread_cond_timedwait(&cond, &mutex, starttimer(&ts, 2000 )); | 
 |   checkResults("pthread_cond_timedwait() Steal 2\n", rc - ETIMEDOUT); | 
 |   printf("Done, rc=%d\n",rc); | 
 |   rc = pthread_mutex_unlock(&mutex); | 
 |  | 
 |   printf("Wait for threads and cleanup\n"); | 
 |   for (i=0; i<COND_NTHREADS; ++i) { | 
 |     rc = pthread_join(threadid[i], NULL); | 
 |     checkResults("pthread_join()\n", rc); | 
 |   } | 
 |  | 
 |   printf("Exit, waiters=%d\n",cond->waiters_count_); | 
 |   pthread_cond_destroy(&cond); | 
 |   pthread_mutex_destroy(&mutex); | 
 |   printf("Main completed\n"); | 
 |   return 0; | 
 | } | 
 |  | 
 | int cond_main() | 
 | { | 
 |   strcpy(testType, "notTimed"); | 
 |   return condTimed_main(); | 
 | } | 
 |  | 
 | int condStatic_main() | 
 | { | 
 |   strcpy(testType, "static"); | 
 |   return condTimed_main(); | 
 | } | 
 | #endif | 
 | /*================================================================================*/ | 
 | void *rwlockTimed_rdlockThread(void *arg) | 
 | { | 
 |   int             rc; | 
 |   int             count=0; | 
 |   struct timespec ts; | 
 |  unsigned long long ct1 = _pthread_time_in_ms(); | 
 |  | 
 |   printf("Entered thread, getting read lock with timeout\n"); | 
 |   Retry: | 
 |   rc = pthread_rwlock_timedrdlock(&rwlock, starttimer(&ts, 5000 )); | 
 |   if (rc != 0) { | 
 |     if (count >= 10) { | 
 |       printf("Retried too many times, failure!\n"); | 
 |       exit(EXIT_FAILURE); | 
 |     } | 
 |     ++count; | 
 |     printf("RETRY...rc=%d\n",rc); | 
 |     goto Retry; | 
 |   } | 
 |   checkResults("pthread_rwlock_timedrdlock() 1\n", rc); | 
 |  | 
 |   Sleep(2000); | 
 |  | 
 |   printf("unlock the read lock\n"); | 
 |   rc = pthread_rwlock_unlock(&rwlock); | 
 |   checkResults("pthread_rwlock_unlock()\n", rc); | 
 |  unsigned long long ct2 = _pthread_time_in_ms(); | 
 |  | 
 |   printf("Secondary thread complete, waited total: %ld\n",ct2-ct1); | 
 |   return NULL; | 
 | } | 
 |  | 
 | int rwlockTimed_main(void) | 
 | { | 
 |   int                   rc=0; | 
 |   pthread_t             thread; | 
 |  | 
 |   printf("Enter Testcase rwlockTimed_main\n"); | 
 |  | 
 |   printf("Main, initialize the read write lock\n"); | 
 |   //rc = pthread_rwlock_init(&rwlock, NULL); | 
 |   rwlock = PTHREAD_RWLOCK_INITIALIZER; | 
 |   printf("RWL %p\n",rwlock); | 
 |   checkResults("pthread_rwlock_init()\n", rc); | 
 |  | 
 |   printf("Main, get the write lock\n"); | 
 |   rc = pthread_rwlock_wrlock(&rwlock); | 
 |   checkResults("pthread_rwlock_wrlock()\n", rc); | 
 |  | 
 |   printf("Main, create the timed rd lock thread\n"); | 
 |   rc = pthread_create(&thread, NULL, rwlockTimed_rdlockThread, NULL); | 
 |   checkResults("pthread_create\n", rc); | 
 |  | 
 |   printf("Main, wait a bit holding the write lock\n"); | 
 |   Sleep(18000); | 
 |  | 
 |   printf("Main, Now unlock the write lock\n"); | 
 |   rc = pthread_rwlock_unlock(&rwlock); | 
 |   checkResults("pthread_rwlock_unlock()\n", rc); | 
 |  | 
 |   printf("Main, wait for the thread to end\n"); | 
 |   rc = pthread_join(thread, NULL); | 
 |   checkResults("pthread_join\n", rc); | 
 |  | 
 |   rc = pthread_rwlock_destroy(&rwlock); | 
 |   rwl_print(&rwlock,"destroyed?"); | 
 |   checkResults("pthread_rwlock_destroy()\n", rc); | 
 |   printf("Main completed\n"); | 
 |   return 0; | 
 | } | 
 |  | 
 |  | 
 | /*================================================================================*/ | 
 | volatile static int rwdata=0; | 
 |  | 
 | void *rwlock_rdlockThread(void *arg) | 
 | { | 
 |   int rc,i; | 
 |   struct timespec ts; | 
 |  | 
 |   printf("Entered thread, getting read lock\n"); | 
 |   //rc = pthread_rwlock_rdlock(&rwlock); | 
 |   rc = pthread_rwlock_timedrdlock(&rwlock, starttimer(&ts, 30000 )); | 
 |   checkResults("pthread_rwlock_rdlock()\n", rc); | 
 |   printf("got the rwlock read lock\n"); | 
 |  | 
 |   for (i=0; i<=200; i++) { | 
 |     Sleep(10); | 
 |     if (rwdata) { | 
 |         printf("RACE cond read %d\n", rwdata); | 
 |     } | 
 |   } | 
 |  | 
 |   printf("unlock the read lock\n"); | 
 |   rc = pthread_rwlock_unlock(&rwlock); | 
 |   checkResults("pthread_rwlock_unlock()\n", rc); | 
 |   printf("Secondary thread unlocked\n"); | 
 |   return NULL; | 
 | } | 
 |  | 
 | void *rwlock_wrlockThread(void *arg) | 
 | { | 
 |   int rc; | 
 |  | 
 |   printf("Entered thread, getting write lock\n"); | 
 |   rc = pthread_rwlock_wrlock(&rwlock); | 
 |   checkResults("pthread_rwlock_wrlock()\n", rc); | 
 |  | 
 |   rwdata ++; | 
 |   Sleep(5000); | 
 |   rwdata --; | 
 |  | 
 |   printf("Got the rwlock write lock, now unlock\n"); | 
 |   rc = pthread_rwlock_unlock(&rwlock); | 
 |   checkResults("pthread_rwlock_unlock()\n", rc); | 
 |   printf("Secondary thread unlocked\n"); | 
 |   return NULL; | 
 | } | 
 |  | 
 | int rwlock_main(void) | 
 | { | 
 |   int                   rc=0; | 
 |   pthread_t             thread, thread1; | 
 |  | 
 |   printf("Enter Testcase rwlock_main\n"); | 
 |  | 
 |   printf("Main, initialize the read write lock\n"); | 
 |   rc = pthread_rwlock_init(&rwlock, NULL); | 
 |   checkResults("pthread_rwlock_init()\n", rc); | 
 |  | 
 |   rwl_print(&rwlock, "Main, grab a read lock"); | 
 |   rc = pthread_rwlock_rdlock(&rwlock); | 
 |   rwl_print(&rwlock, "Main, grabbbed a read lock"); | 
 |   checkResults("pthread_rwlock_rdlock()\n",rc); | 
 |  | 
 | /* | 
 |   printf("Main, grab the same read lock again\n"); | 
 |   rc = pthread_rwlock_rdlock(&rwlock); | 
 |   checkResults("pthread_rwlock_rdlock() second\n", rc); | 
 | */ | 
 |  | 
 |   printf("Main, create the read lock thread\n"); | 
 |   rc = pthread_create(&thread, NULL, rwlock_rdlockThread, NULL); | 
 |   checkResults("pthread_create\n", rc); | 
 |  | 
 | /* | 
 |   printf("Main - unlock the first read lock\n"); | 
 |   rc = pthread_rwlock_unlock(&rwlock); | 
 |   checkResults("pthread_rwlock_unlock()\n", rc); | 
 | */ | 
 |  | 
 |   printf("Main, create the write lock thread\n"); | 
 |   rc = pthread_create(&thread1, NULL, rwlock_wrlockThread, NULL); | 
 |   checkResults("pthread_create\n", rc); | 
 |  | 
 |   printf("Main - unlock the read lock\n"); | 
 |   rc = pthread_rwlock_unlock(&rwlock); | 
 |   checkResults("pthread_rwlock_unlock()\n", rc); | 
 |  | 
 |   printf("Main, wait for the threads\n"); | 
 |   rc = pthread_join(thread, NULL); | 
 |   checkResults("pthread_join\n", rc); | 
 |  | 
 |   rc = pthread_join(thread1, NULL); | 
 |   checkResults("pthread_join\n", rc); | 
 |  | 
 |   rc = pthread_rwlock_destroy(&rwlock); | 
 |   checkResults("pthread_rwlock_destroy()\n", rc); | 
 |  | 
 |   printf("Main completed\n"); | 
 |   rwl_print(&rwlock, "Main completed"); | 
 |   return 0; | 
 | } | 
 |  | 
 | /*================================================================================*/ | 
 | #define BARRIER_NTHREADS 50 | 
 |  | 
 | #define BARRIER_ROUNDS 50 | 
 |  | 
 | static pthread_barrier_t barriers[BARRIER_NTHREADS]; | 
 |  | 
 | static pthread_mutex_t lock; | 
 | static int counters[BARRIER_NTHREADS]; | 
 | static int serial[BARRIER_NTHREADS]; | 
 |  | 
 |  | 
 |  | 
 | void *barrier_Thread(void *arg) | 
 | { | 
 |     void *result = NULL; | 
 |     int nr = (int)(uintptr_t)arg; | 
 |     int i; | 
 |  | 
 |     for (i = 0; i < BARRIER_ROUNDS; ++i) | 
 |     { | 
 |         int j; | 
 |         int retval; | 
 |  | 
 |         if (nr == 0) | 
 |         { | 
 |             memset (counters, '\0', sizeof (counters)); | 
 |             memset (serial, '\0', sizeof (serial)); | 
 |         } | 
 |  | 
 |         retval = pthread_barrier_wait (&barriers[BARRIER_NTHREADS - 1]); | 
 |         if (retval != 0 && retval != PTHREAD_BARRIER_SERIAL_THREAD) | 
 |         { | 
 |             printf ("thread %d failed to wait for all the others\n", nr); | 
 |             result = (void *) 1; | 
 |         } | 
 |  | 
 |         for (j = nr; j < BARRIER_NTHREADS; ++j) | 
 |         { | 
 |             /* Increment the counter for this round.  */ | 
 |             //printf ("Increment the counter for this round %d\n", j); | 
 |             pthread_mutex_lock (&lock); | 
 |             ++counters[j]; | 
 |             pthread_mutex_unlock (&lock); | 
 |             //printf ("Incremented the counter for this round %d\n", j); | 
 |  | 
 |             /* Wait for the rest.  */ | 
 |             retval = pthread_barrier_wait (&barriers[j]); | 
 |  | 
 |             /* Test the result.  */ | 
 |             if (nr == 0 && counters[j] != j + 1) | 
 |             { | 
 |                 printf ("barrier in round %d released but count is %d\n", | 
 |                         j, counters[j]); | 
 |                 result = (void *) 1; | 
 |             } | 
 |  | 
 |             if (retval != 0) | 
 |             { | 
 |                 if (retval != PTHREAD_BARRIER_SERIAL_THREAD) | 
 |                 { | 
 |                     printf ("thread %d in round %d has nonzero return value != PTHREAD_BARRIER_SERIAL_THREAD\n", | 
 |                             nr, j); | 
 |                     result = (void *) 1; | 
 |                 } | 
 |                 else | 
 |                 { | 
 |                     //printf ("pthread_mutex_lock %d\n", nr); | 
 |                     pthread_mutex_lock (&lock); | 
 |                     ++serial[j]; | 
 |                     pthread_mutex_unlock (&lock); | 
 |                 } | 
 |             } | 
 |  | 
 |             /* Wait for the rest again.  */ | 
 |             printf ("Wait for the rest again %d\n",j); | 
 |             retval = pthread_barrier_wait (&barriers[j]); | 
 |             /* the following printf can make bugs go away - timing dependend */ | 
 |             /* without this printf the test hangs here */ | 
 |             /* try USE_MUTEX_CriticalSection + USE_COND_Semaphore */ | 
 |             //printf ("Wait for the rest again continue %d\n",j); | 
 |      | 
 |             /* Now we can check whether exactly one thread was serializing.  */ | 
 |             if (nr == 0 && serial[j] != 1) | 
 |             { | 
 |                 printf ("not exactly one serial thread in round %d\n", j); | 
 |                 result = (void *) 1; | 
 |                 exit(1); | 
 |             } | 
 |         } | 
 |     } | 
 |  | 
 |     return result; | 
 | } | 
 |  | 
 | int barrier_main(void) | 
 | { | 
 |     int                   rc=0; | 
 |     pthread_t threads[BARRIER_NTHREADS]; | 
 |     int i; | 
 |     void *res; | 
 |     int result = 0; | 
 |  | 
 |  | 
 |     printf("Enter Testcase - barrier_main %s\n",testType); | 
 |  | 
 |     rc = pthread_mutex_init (&lock, NULL); | 
 |     checkResults("pthread_mutex_init()\n", rc); | 
 |  | 
 |     /* Initialized the barrier variables.  */ | 
 |     for (i = 0; i < BARRIER_NTHREADS; ++i) { | 
 |         if (pthread_barrier_init (&barriers[i], NULL, i + 1) != 0) | 
 |         { | 
 |             printf ("Failed to initialize barrier %d\n", i); | 
 |             exit (1); | 
 |         } | 
 |         printf ("initialized barrier %d\n", i); | 
 |     } | 
 |  | 
 |     /* Start the threads.  */ | 
 |     for (i = 0; i < BARRIER_NTHREADS; ++i) { | 
 |         if (pthread_create (&threads[i], NULL, barrier_Thread, (void *)(uintptr_t)i) != 0) | 
 |         { | 
 |             printf ("Failed to start thread %d\n", i); | 
 |             exit (1); | 
 |         } | 
 |         printf ("started thread %d\n", i); | 
 |     } | 
 |  | 
 |     /* And wait for them.  */ | 
 |     printf ("Wait for %d threads\n", i); | 
 |     for (i = 0; i < BARRIER_NTHREADS; ++i) { | 
 |         if (pthread_join (threads[i], &res) != 0 || res != NULL) | 
 |         { | 
 |             printf ("thread %d returned a failure\n", i); | 
 |             result = 1; | 
 |         } | 
 |     } | 
 |  | 
 |     printf ("Result: %d\n", result); | 
 |     if (result == 0) | 
 |         puts ("all OK"); | 
 |  | 
 |     return result; | 
 |  | 
 | } | 
 | /*================================================================================*/ | 
 | void thread(void) | 
 | { | 
 |     int i; | 
 |     parm *p; | 
 |     pthread_t *threads; | 
 |     pthread_attr_t pthread_custom_attr; | 
 |     int n = N_THREAD; | 
 |     n = N_THREAD; | 
 |     if ((n < 1) || (n > MAX_THREAD)) | 
 |     { | 
 |         printf ("The no of thread should between 1 and %d.\n",MAX_THREAD); | 
 |         exit(1); | 
 |     } | 
 |  | 
 |     threads=(pthread_t *)malloc(n*sizeof(*threads)); | 
 |     pthread_attr_init(&pthread_custom_attr); | 
 |  | 
 |     p=(parm *)malloc(sizeof(parm)*n); | 
 |     /* Start up thread */ | 
 |  | 
 |     for (i=0; i<n; i++) | 
 |     { | 
 |         p[i].id=i; | 
 |         pthread_create(&threads[i], &pthread_custom_attr, hello, (void *)(p+i)); | 
 |     } | 
 |  | 
 |     /* Synchronize the completion of each thread. */ | 
 |  | 
 |     for (i=0; i<n; i++) | 
 |     { | 
 |         pthread_join(threads[i],NULL); | 
 |     } | 
 |     free(p); | 
 |      pthread_exit(NULL); | 
 | } | 
 |  | 
 | int main(int argc, char * argv[]) { | 
 |     char name[100]; | 
 |  | 
 |     if (argc < 2) | 
 |     { | 
 |         printf ("Usage: %s <name> [type]\nwhere <name> is test name\n",argv[0]); | 
 |         printf ("test names are: thread, rwlock, rwlockTimed, cond, condTimed, condStatic, spinlock, barrier, mutex [static[N|R|E|ND]].\n"); | 
 |         exit(1); | 
 |     } | 
 |     strcpy(testType, "default"); | 
 |     if (argc == 3) | 
 |     { | 
 |         strcpy(testType, argv[2]); | 
 |     } | 
 |  | 
 |     strcpy(name, argv[1]);  | 
 |     printf ("Threads test: %s\n",name); | 
 |     printf ("P size: %d %d\n",SIZE_MAX>UINT_MAX,sizeof(struct timespec )); | 
 |     if (strcmp(name, "thread") == 0) thread(); | 
 |     else if (strcmp(name, "rwlock") == 0) rwlock_main(); | 
 |     else if (strcmp(name, "rwlockTimed") == 0) rwlockTimed_main(); | 
 |     //else if (strcmp(name, "cond") == 0) cond_main(); | 
 |     else if (strcmp(name, "condTimed") == 0) condTimed_main(); | 
 |     //else if (strcmp(name, "condStatic") == 0) condStatic_main(); | 
 |     else if (strcmp(name, "barrier") == 0) barrier_main(); | 
 |     else if (strcmp(name, "mutex") == 0) mutex_main(); | 
 |     else if (strcmp(name, "spinlock") == 0) spinlock_main(); | 
 |     else printf ("Unknown test name '%s'\n",name); | 
 |   | 
 |         return 0; | 
 | } |