#include
#include
#include
#include
#include
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t waite_recv = PTHREAD_COND_INITIALIZER;
static pthread_cond_t waite_send = PTHREAD_COND_INITIALIZER;
static volatile int message = 0;
static volatile int sem_counts = 0;
static volatile int mut_counts = 0;
#define DO_COUNTS 90000000
int get_sem_counts(){
return sem_counts;
}
int get_mut_counts(){
return mut_counts;
}
void reset_mut_counts(){
mut_counts = 0;
}
#define CHECK_ROUTE( x ) do{\
int __ret__ = x;\
if( 0 != __ret__ ){\
printf("[%s:%d]:%d-%d(%s)\n",__FUNCTION__,__LINE__,__ret__,errno,strerror(errno));\
return NULL;\
}\
}while(0)
static void* recv_thread(void* arg) {
int i = 0;
for (;i < DO_COUNTS/100; ++i) {
CHECK_ROUTE(pthread_mutex_lock(&mutex));
/*
* be care this wait may be excute after
* broadcast or signal
* in that way U may be lost one condtion
* at least even may be dead lock here
* so we must introduce a var to test
* whether ok.
*/
for(; 0 == message;)
{
CHECK_ROUTE(pthread_cond_wait(&waite_send, &mutex));
}
--message;
CHECK_ROUTE(pthread_cond_signal(&waite_recv));
CHECK_ROUTE(pthread_mutex_unlock(&mutex));
++mut_counts;
}
return NULL;
}
static void* send_thread(void* arg) {
int i = 0;
for (;i < DO_COUNTS/100; ++i) {
CHECK_ROUTE(pthread_mutex_lock(&mutex));
++message;
/**
* be care this route may be no using when
* there're no any thread waite this conition
* so must changed this usage
*/
CHECK_ROUTE(pthread_cond_signal(&waite_send));
CHECK_ROUTE(pthread_cond_wait(&waite_recv, &mutex));
CHECK_ROUTE(pthread_mutex_unlock(&mutex));
}
return NULL;
}
/*
* this test could work but ....
*/
void* test_mutex_for_semphone(){
pthread_t recver,sender;
int i,k;
void *r = &i,*s = &k;
message = 0;
CHECK_ROUTE(pthread_mutex_init(&mutex,NULL));
CHECK_ROUTE(pthread_cond_init(&waite_recv,NULL));
CHECK_ROUTE(pthread_cond_init(&waite_send,NULL));
CHECK_ROUTE(pthread_create(&recver,NULL,recv_thread,NULL));
CHECK_ROUTE(pthread_create(&sender,NULL,send_thread,NULL));
CHECK_ROUTE(pthread_join(recver,&r));
CHECK_ROUTE(pthread_join(sender,&s));
CHECK_ROUTE(pthread_cond_destroy(&waite_recv));
CHECK_ROUTE(pthread_cond_destroy(&waite_send));
CHECK_ROUTE(pthread_mutex_destroy(&mutex));
assert(message == 0);
}
#include
static sem_t send_sem;
static sem_t recv_sem;
void* sem_send_thread(void* arg){
int i = 0;
for(; i < DO_COUNTS/100; ++i){
++message;
CHECK_ROUTE(sem_post(&send_sem));
CHECK_ROUTE(sem_wait(&recv_sem));
}
return NULL;
}
void* sem_recv_thread(){
int i = 0;
for(; i < DO_COUNTS/100; ++i){
CHECK_ROUTE(sem_wait(&send_sem));
--message;
++mut_counts;
CHECK_ROUTE(sem_post(&recv_sem));
++sem_counts;
}
return NULL;
}
void* test_emphone(){
pthread_t recver,sender;
int i,k;
void *r = &i,*s = &k;
message = 0;
CHECK_ROUTE(sem_init(&send_sem,0,0));
CHECK_ROUTE(sem_init(&recv_sem,0,0));
CHECK_ROUTE(pthread_create(&recver,NULL,sem_recv_thread,NULL));
CHECK_ROUTE(pthread_create(&sender,NULL,sem_send_thread,NULL));
CHECK_ROUTE(pthread_join(recver,&r));
CHECK_ROUTE(pthread_join(sender,&s));
CHECK_ROUTE(sem_destroy(&send_sem));
CHECK_ROUTE(sem_destroy(&recv_sem));
assert(message == 0);
}
/*
*
* using sem as a mutex to metex var operation
* no any other process
*
*/
static sem_t sem_mutex;
static void* sem_mutex_recv_thread(void* arg){
int i = 0;
for(; i < DO_COUNTS ; ++i){
CHECK_ROUTE(sem_wait(&sem_mutex));
--message;
++mut_counts;
CHECK_ROUTE(sem_post(&sem_mutex));
}
}
static void* sem_mutex_send_thread(void* arg){
int i = 0;
for(; i < DO_COUNTS ; ++i){
CHECK_ROUTE(sem_wait(&sem_mutex));
++message;
CHECK_ROUTE(sem_post(&sem_mutex));
}
}
void* test_sem_for_mutex(){
pthread_t recver,sender;
int i,k;
void *r = &i,*s = &k;
message = 0;
CHECK_ROUTE(sem_init(&sem_mutex,0,1));
CHECK_ROUTE(pthread_create(&recver,NULL,sem_mutex_recv_thread,NULL));
CHECK_ROUTE(pthread_create(&sender,NULL,sem_mutex_send_thread,NULL));
CHECK_ROUTE(pthread_join(recver,&r));
CHECK_ROUTE(pthread_join(sender,&s));
CHECK_ROUTE(sem_destroy(&sem_mutex));
assert(message == 0);
}
/*
*
* only test for mutex var operation
* no any other process
*
*/
static void* mutex_recv_thread(void* arg){
int i = 0;
for(; i < DO_COUNTS ; ++i){
CHECK_ROUTE(pthread_mutex_lock(&mutex));
--message;
++mut_counts;
CHECK_ROUTE(pthread_mutex_unlock(&mutex));
}
}
static void* mutex_send_thread(void* arg){
int i = 0;
for(; i < DO_COUNTS ; ++i){
CHECK_ROUTE(pthread_mutex_lock(&mutex));
++message;
CHECK_ROUTE(pthread_mutex_unlock(&mutex));
}
}
void* test_mutex(){
pthread_t recver,sender;
int i,k;
void *r = &i,*s = &k;
message = 0;
CHECK_ROUTE(pthread_mutex_init(&mutex,NULL));
CHECK_ROUTE(pthread_create(&recver,NULL,mutex_recv_thread,NULL));
CHECK_ROUTE(pthread_create(&sender,NULL,mutex_send_thread,NULL));
CHECK_ROUTE(pthread_join(recver,&r));
CHECK_ROUTE(pthread_join(sender,&s));
CHECK_ROUTE(pthread_mutex_destroy(&mutex));
assert(message == 0);
}
static sem_t sem_sig;
static void* sem_sig_send(void* arg) {
int i = 0;
for (; i < DO_COUNTS; ++i) {
/*
* ++ operation is not automic operation
* so after following opeation the message
* value not make sure
* in this case
*/
++message;++mut_counts;
CHECK_ROUTE(sem_post(&sem_sig));
}
return NULL;
}
static void* sem_sig_recv(void* arg){
int i = 0,k = 0;
for (; i < DO_COUNTS; ++i) {
CHECK_ROUTE(sem_wait(&sem_sig));
/*
* this operation not safe maybe dirty read and wirte
*/
--message;
}
}
void* test_sem_for_sig(){
pthread_t recver,sender;
int i,k;
void *r = &i,*s = &k;
CHECK_ROUTE(sem_init(&sem_sig,0,0));
message = 0;
CHECK_ROUTE(pthread_create(&recver,NULL,sem_sig_send,NULL));
CHECK_ROUTE(pthread_create(&sender,NULL,sem_sig_recv,NULL));
CHECK_ROUTE(pthread_join(recver,&r));
CHECK_ROUTE(pthread_join(sender,&s));
CHECK_ROUTE(sem_destroy(&sem_sig));
}
static pthread_mutex_t guard;
static sem_t wait_object;
static void* mix_send(void* arg) {
int i = 0;
for (; i < DO_COUNTS; ++i) {
pthread_mutex_lock(&guard);
++message;++mut_counts;
pthread_mutex_unlock(&guard);
CHECK_ROUTE(sem_post(&wait_object));
}
return NULL;
}
static void* mix_recv(void* arg){
int i = 0,k = 0;
for (; i < DO_COUNTS; ++i) {
CHECK_ROUTE(sem_wait(&wait_object));
pthread_mutex_lock(&guard);
--message;
pthread_mutex_unlock(&guard);
}
return NULL;
}
#include
void* test_mix(){
pthread_t recver,sender;
int i,k;
void *r = &i,*s = &k;
CHECK_ROUTE(sem_init(&wait_object,0,0));
CHECK_ROUTE(pthread_mutex_init(&guard,NULL));
message = 0;
CHECK_ROUTE(pthread_create(&recver,NULL,mix_send,NULL));
CHECK_ROUTE(pthread_create(&sender,NULL,mix_recv,NULL));
CHECK_ROUTE(pthread_join(recver,&r));
CHECK_ROUTE(pthread_join(sender,&s));
CHECK_ROUTE(sem_destroy(&wait_object));
CHECK_ROUTE(pthread_mutex_unlock(&guard));
assert(message == 0);
}
#include
/*
*
*/
void find_id_number(const char* tail_xx);
void* test_mutex_for_semphone();
void* test_emphone();
void* test_mutex();
void* test_sem_for_mutex();
void* test_sem_for_sig();
void* test_sem_mix();
int get_sem_counts();
int get_mut_counts();
void reset_mut_counts();
static void test_time(){
time_t now = time(NULL);
int i = 0,interval = time(NULL) - now;
for (; interval < 10; ++i) {
test_emphone();
interval = time(NULL) - now;
}
printf("10 sec sem done %d:%d:%d\n", i,interval,get_sem_counts());
reset_mut_counts();
now = time(NULL);
interval = time(NULL) - now;
for (i = 0; interval < 10; ++i) {
test_mutex_for_semphone();
interval = time(NULL) - now;
}
printf("10 sec mutex done %d:%d:%d\n", i,interval,get_mut_counts());
reset_mut_counts();
now = time(NULL);
interval = time(NULL) - now;
for (i = 0; interval < 10; ++i) {
test_sem_for_mutex();
interval = time(NULL) - now;
}
printf("10 sec sem_for_mutex done %d:%d:%d\n", i,interval,get_mut_counts());
reset_mut_counts();
now = time(NULL);
interval = time(NULL) - now;
for (i = 0; interval < 10; ++i) {
test_mutex();
interval = time(NULL) - now;
}
printf("10 sec only mutex done %d:%d:%d\n", i,interval,get_mut_counts());
reset_mut_counts();
now = time(NULL);
interval = time(NULL) - now;
for (i = 0; interval < 10; ++i) {
test_sem_for_sig();
interval = time(NULL) - now;
}
printf("10 sec only sem done %d:%d:%d\n", i,interval,get_mut_counts());
reset_mut_counts();
now = time(NULL);
interval = time(NULL) - now;
for (i = 0; interval < 10; ++i) {
test_mix();
interval = time(NULL) - now;
}
printf("10 sec mix done %d:%d:%d\n", i,interval,get_mut_counts());
}
int main(int argc, char** argv) {
test_time();
return (EXIT_SUCCESS);
}
10 sec sem done 1:25:900000
10 sec mutex done 1:37:900000
10 sec sem_for_mutex done 1:25:90000000
10 sec only mutex done 1:14:90000000
10 sec only sem done 1:50:90000000
10 sec mix done 1:25:90000000