mydef.h
#include <semaphore.h>
#include <errno.h>
#ifdef Solaris
#include <thread.h>
#include <synch.h>
#endif
#ifdef Linux
#include <pthread.h>
#endif
#define MY_ERROR(thread,func) \
{\
printf("Error in thread\"%s\",func=\"%s\",errno=%d\n",thread,func,errno);\
}
#define MY_ERROR2(thread,func,rt) \
{\
printf("Error in thread\"%s\",func=\"%s\",return=%d,errno=%d\n",thread,func,rt,errno);\
}
typedef struct param_tag{
#ifdef Linux
sem_t *sema1_p;
sem_t *sema2_p;
#else
sema_t *sema1_p;
sema_t *sema2_p;
#endif
}param_t;
extern void * t1(void * p);
extern void * t2(void * p);
extern void * t3(void * p);
extern void * t4(void * p);
extern void * t5(void * p);
extern void * myhandle(int sig);
#ifdef Linux
extern sem_t sema1;
extern sem_t sema2;
#else
extern sema_t sema1;
extern sema_t sema2;
#endif
mytest.c
/** main thread
*
* init semaphore
* start thread 1
* start thread 2
* start thread 3
*
**/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <signal.h>
#include "mydef.h"
#ifdef Linux
sem_t sema1;
sem_t sema2;
#else
sema_t sema1;
sema_t sema2;
#endif
/** test deadlock
*
* init semaphore
* start thread 1
* start thread 2
* start thread 3
*
**/
int test_dlock()
{
#ifdef Linux
pthread_t threadid;
#else
thread_t threadid;
#endif
param_t param;
int rc;
#ifdef Linux
rc = sem_init(&sema1,0,1);
rc = sem_init(&sema2,0,1);
#else
rc = sema_init(&sema1,1,USYNC_THREAD,NULL);
rc = sema_init(&sema2,1,USYNC_THREAD,NULL);
#endif
if( rc != 0 ) {
MY_ERROR("main","sem_init")
return 0;
}
param.sema1_p = &sema1;
param.sema2_p = &sema2;
#ifdef Linux
rc = pthread_create( &threadid, NULL, t1, (void *)¶m);
if( rc != 0 ) {
MY_ERROR("t1","pthread_create")
return 0;
}
rc = pthread_create( &threadid, NULL, t2, (void *)¶m);
rc = pthread_create( &threadid, NULL, t3, (void *)¶m);
#else
rc = thr_create(NULL,0,t1, (void *)¶m,THR_BOUND,&threadid);
if( rc != 0 ) {
MY_ERROR("t1","thr_create")
return 0;
}
rc = thr_create(NULL,0,t2, (void *)¶m,THR_BOUND,&threadid);
rc = thr_create(NULL,0,t3, (void *)¶m,THR_BOUND,&threadid);
#endif
sleep(5);
}
/** test EINTR
*
* init semaphore
* start thread 4
* start thread 5
*
**/
int test_intr()
{
#ifdef Linux
pthread_t threadid;
#else
thread_t threadid;
#endif
param_t param;
int rc;
#ifdef Linux
rc = sem_init(&sema1,0,1);
rc = sem_init(&sema2,0,1);
#else
rc = sema_init(&sema1,1,USYNC_THREAD,NULL);
rc = sema_init(&sema2,1,USYNC_THREAD,NULL);
#endif
if( rc != 0 ) {
MY_ERROR("main","sem_init")
return 0;
}
signal(SIGSYS,myhandle);
param.sema1_p = &sema1;
param.sema2_p = &sema2;
#ifdef Linux
rc = pthread_create( &threadid, NULL, t4, (void *)¶m);
if( rc != 0 ) {
MY_ERROR("t4","pthread_create")
return 0;
}
rc = pthread_create( &threadid, NULL, t5, (void *)¶m);
#else
rc = thr_create(NULL,0,t4, (void *)¶m,THR_BOUND,&threadid);
if( rc != 0 ) {
MY_ERROR("t4","thr_create")
return 0;
}
rc = thr_create(NULL,0,t5, (void *)¶m,THR_BOUND,&threadid);
#endif
sleep(100);
return 0;
}
/** test EINTR single thread
*
* init semaphore
* t4()
*
**/
int test_intr_single()
{
param_t param;
int rc;
#ifdef Linux
rc = sem_init(&sema1,0,1);
#else
rc = sema_init(&sema1,1,USYNC_THREAD,NULL);
#endif
if( rc != 0 ) {
MY_ERROR("main","sem_init")
return 0;
}
param.sema1_p = &sema1;
param.sema2_p = NULL;
t4(¶m);
return 0;
}
int main()
{
test_intr_single();
}
t1.c
/** thread 1
*
* sem_wait(lock1)
* sleep(1)
* sem_wait(lock2)
* deadLock with t2 !!!
*
*
**/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include "mydef.h"
extern void * t1(void * p)
{
#ifdef Linux
sem_t *sema1_p;
sem_t *sema2_p;
#else
sema_t *sema1_p;
sema_t *sema2_p;
#endif
param_t *param_p = p;
int rc;
int val;
sema1_p = param_p->sema1_p;
sema2_p = param_p->sema2_p;
#ifdef Linux
rc = sem_wait(sema1_p);
#else
rc = sema_wait(sema1_p);
#endif
if( rc != 0 ) {
MY_ERROR("t1","sema_wait(sema1)")
return 0;
}
printf("thread \"t1\" get \"sema1\" OK.\n");
#ifdef Linux
rc = sem_getvalue(sema1_p, &val);
printf("thread \"t1\" value of \"sema1\" is %d.\n", val);
#endif
sleep(1);
#ifdef Linux
rc = sem_getvalue(sema2_p, &val);
printf("thread \"t1\" value of \"sema2\" is %d.\n", val);
#endif
printf("thread \"t1\" waiting for \"sema2\" ...\n");
#ifdef Linux
rc = sem_wait(sema2_p);
#else
rc = sema_wait(sema2_p);
#endif
if( rc != 0 ) {
MY_ERROR("t1","sema_wait(sema2)")
return 0;
}
printf("thread \"t1\" get \"sema2\" OK.\n");
return 0;
}
t2.c
/** thread 2
*
* sem_wait(lock2)
* sleep(1)
* sem_wait(lock1)
* deadLock with t1 !!!
*
*
**/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include "mydef.h"
extern void * t2(void * p)
{
#ifdef Linux
sem_t *sema1_p;
sem_t *sema2_p;
#else
sema_t *sema1_p;
sema_t *sema2_p;
#endif
param_t *param_p = p;
int rc;
int val;
sema1_p = param_p->sema1_p;
sema2_p = param_p->sema2_p;
#ifdef Linux
rc = sem_wait(sema2_p);
#else
rc = sema_wait(sema2_p);
#endif
if( rc != 0 ) {
MY_ERROR("t2","sema_wait(sema2)")
return 0;
}
printf("thread \"t2\" get \"sema2\" OK.\n");
#ifdef Linux
rc = sem_getvalue(sema2_p, &val);
printf("thread \"t2\" value of \"sema2\" is %d.\n", val);
#endif
sleep(1);
#ifdef Linux
rc = sem_getvalue(sema1_p, &val);
printf("thread \"t2\" value of \"sema1\" is %d.\n", val);
#endif
printf("thread \"t2\" waiting for \"sema1\" ...\n");
#ifdef Linux
rc = sem_wait(sema1_p);
#else
rc = sema_wait(sema1_p);
#endif
if( rc != 0 ) {
MY_ERROR("t2","sema_wait(sema1)")
return 0;
}
printf("thread \"t2\" get \"sema1\" OK.\n");
return 0;
}
t3.c
/** thread 3
*
* sleep(3)
* sem_trywait(lock1)
* deteck deadLock between t1 and t2
*
**/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include "mydef.h"
extern void * t3(void * p)
{
#ifdef Linux
sem_t *sema1_p;
sem_t *sema2_p;
#else
sema_t *sema1_p;
sema_t *sema2_p;
#endif
param_t *param_p = p;
int rc;
int val;
sema1_p = param_p->sema1_p;
sema2_p = param_p->sema2_p;
sleep(3);
errno = -1;
#ifdef Linux
rc = sem_trywait(sema1_p);
if( rc == -1 ) {
switch(errno)
{
case EBUSY:
printf("thread \"t3\" can't get \"sema1\" : EBUSY.\n");
break;
case EAGAIN:
printf("thread \"t3\" can't get \"sema1\" : EAGAIN.\n");
break;
case EDEADLK:
printf("thread \"t3\" can't get \"sema1\" : EDEADLK.\n");
break;
case EINTR:
printf("thread \"t3\" can't get \"sema1\" : EINTR.\n");
break;
default:
MY_ERROR2("t3","sema_trywait(sema1)",rc)
}
return 0;
}
if( rc != 0 ) {// for solaris librt.so
switch(rc)
{
case EBUSY:
printf("thread \"t3\" can't get \"sema1\" : EBUSY.\n");
break;
case EAGAIN:
printf("thread \"t3\" can't get \"sema1\" : EAGAIN.\n");
break;
case EDEADLK:
printf("thread \"t3\" can't get \"sema1\" : EDEADLK.\n");
break;
case EINTR:
printf("thread \"t3\" can't get \"sema1\" : EINTR.\n");
break;
default:
MY_ERROR2("t3","sema_trywait(sema1)",rc)
}
return 0;
}
#else
rc = sema_trywait(sema1_p);
if( rc != 0 ) {
switch(rc)
{
case EBUSY:
printf("thread \"t3\" can't get \"sema1\" : EBUSY.\n");
break;
case EAGAIN:
printf("thread \"t3\" can't get \"sema1\" : EAGAIN.\n");
break;
case EDEADLK:
printf("thread \"t3\" can't get \"sema1\" : EDEADLK.\n");
break;
case EINTR:
printf("thread \"t3\" can't get \"sema1\" : EINTR.\n");
break;
default:
MY_ERROR("t3","sema_trywait(sema1)")
}
return 0;
}
#endif
printf("thread \"t3\" get \"sema1\" OK.\n");
return 0;
}
t4.c
/** thread 4
*
* loop: usleep(100000);sem_trywait(sema1);sem_post(sema1);
* deteck EINTR in sem_trywait()
*
**/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include "mydef.h"
extern void * t4(void * p)
{
#ifdef Linux
sem_t *sema1_p;
sem_t *sema2_p;
#else
sema_t *sema1_p;
sema_t *sema2_p;
#endif
param_t *param_p = p;
int rc;
int val;
sema1_p = param_p->sema1_p;
sema2_p = param_p->sema2_p;
while(1)
{
usleep(100000);
errno = -1;
#ifdef Linux
//rc = sem_getvalue(sema1_p, &val);
//printf("thread \"t4\" value of \"sema1\" is %d.\n", val);
rc = sem_trywait(sema1_p);
//rc = sem_wait(sema1_p);
if( rc == -1 ) {
switch(errno)
{
case EBUSY:
printf("thread \"t4\" can't get \"sema1\" : EBUSY.\n");
break;
case EAGAIN:
printf("thread \"t4\" can't get \"sema1\" : EAGAIN.\n");
break;
case EDEADLK:
printf("thread \"t4\" can't get \"sema1\" : EDEADLK.\n");
break;
case EINTR:
printf("thread \"t4\" can't get \"sema1\" : EINTR.\n");
break;
default:
MY_ERROR2("t4","sema_trywait(sema1)",rc)
}
}
#else
rc = sema_trywait(sema1_p);
if( rc != 0 ) {
switch(rc)
{
case EBUSY:
printf("thread \"t4\" can't get \"sema1\" : EBUSY.\n");
break;
case EAGAIN:
printf("thread \"t4\" can't get \"sema1\" : EAGAIN.\n");
break;
case EDEADLK:
printf("thread \"t4\" can't get \"sema1\" : EDEADLK.\n");
break;
case EINTR:
printf("thread \"t4\" can't get \"sema1\" : EINTR.\n");
break;
default:
MY_ERROR("t4","sema_trywait(sema1)")
}
}
#endif
#ifdef Linux
rc = sem_post(sema1_p);
if( rc == -1 ) {
switch(errno)
{
case EBUSY:
printf("thread \"t4\" can't post \"sema1\" : EBUSY.\n");
break;
case EAGAIN:
printf("thread \"t4\" can't post \"sema1\" : EAGAIN.\n");
break;
case EDEADLK:
printf("thread \"t4\" can't post \"sema1\" : EDEADLK.\n");
break;
case EINTR:
printf("thread \"t4\" can't post \"sema1\" : EINTR.\n");
break;
default:
MY_ERROR2("t4","sem_post(sema1)",rc)
}
}
#else
rc = sema_post(sema1_p);
if( rc != 0 ) {
switch(rc)
{
case EBUSY:
printf("thread \"t4\" can't post \"sema1\" : EBUSY.\n");
break;
case EAGAIN:
printf("thread \"t4\" can't post \"sema1\" : EAGAIN.\n");
break;
case EDEADLK:
printf("thread \"t4\" can't post \"sema1\" : EDEADLK.\n");
break;
case EINTR:
printf("thread \"t4\" can't post \"sema1\" : EINTR.\n");
break;
default:
MY_ERROR("t4","sema_post(sema1)")
}
}
#endif
}
return 0;
}
t5.c
/** thread 5
*
* loop: usleep(50000);raise(signum);
*
* try EINTR in sem_trywait()
*
**/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <signal.h>
#include "mydef.h"
extern void * t5(void * p)
{
while(1)
{
usleep(50000);
raise(SIGSYS);
}
return 0;
}
extern void * myhandle(int sig)
{
return 0;
}
cmp_linux.sh
#!/bin/sh
cc -c -DLinux t1.c
cc -c -DLinux t2.c
cc -c -DLinux t3.c
cc -c -DLinux t4.c
cc -c -DLinux t5.c
cc -c -DLinux mytest.c
cc -o mytest t1.o t2.o t3.o t4.o t5.o mytest.o -lpthread
cmp_sol.sh
#!/bin/sh
cc -c -DSolaris t1.c
cc -c -DSolaris t2.c
cc -c -DSolaris t3.c
cc -c -DSolaris t4.c
cc -c -DSolaris t5.c
cc -c -DSolaris mytest.c
cc -o mytest t1.o t2.o t3.o t4.o t5.o mytest.o -lpthread