| #include <stdio.h> |
| #include <pthread.h> |
| #include <stdlib.h> |
| #define MANY 1000 |
| #define LEVEL 100 |
| typedef struct { |
| pthread_mutex_t m[MANY]; |
| pthread_mutex_t d; |
| } Level; |
| |
| static Level level[LEVEL]; |
| |
| static int stat_mutex_init = 0; |
| static int stat_mutex_lock = 0; |
| static int stat_mutex_unlock = 0; |
| static int stat_mutex_destroy = 0; |
| |
| /* t2t.c : test program for the laog data structure performance testing |
| and "shaking" : it creates, locks/unlocks and destroy mutex. |
| |
| USAGE: t2t [many] [level] [loops] |
| many (default 100) : how many locks are created/locked/unlocked at a certain level. |
| level (default 1) : how many levels of "nested locks" are done |
| loops : how many times these locks are created and destroyed and locked/unlocked) */ |
| #define check if (ret != 0) printf("error %d at line %d\n", ret, __LINE__) |
| int doit(int argc, char*argv[]) |
| { |
| int l, i; |
| int ret; |
| |
| int clo_many = 100; |
| int clo_level = 1; |
| |
| if (argc >= 2) clo_many = atoi(argv[1]); |
| if (argc >= 3) clo_level = atoi(argv[2]); |
| |
| if (clo_many > MANY) { |
| printf("error argv[1] (many arg) %d > max MANY %d\n", clo_many, MANY); |
| exit(1); |
| } |
| |
| if (clo_level > LEVEL) { |
| printf("error argv[2] (level arg) %d > max LEVEL %d\n", clo_level, LEVEL); |
| exit(1); |
| } |
| |
| printf ("many %d level %d total_locks: %d\n", |
| clo_many, clo_level, |
| clo_many * clo_level + clo_level * (clo_level == 1 ? 0 : 1)); |
| |
| for (l = 0; l < clo_level; l++) { |
| printf ("init level %d\n", l); |
| for (i = 0; i < clo_many; i++) { |
| ret = pthread_mutex_init (&level[l].m[i], NULL); |
| check; |
| stat_mutex_init++; |
| } |
| if (clo_level > 1) { |
| ret = pthread_mutex_init (&level[l].d, NULL); |
| check; |
| stat_mutex_init++; |
| } |
| } |
| |
| for (l = 0; l < clo_level; l++) { |
| printf ("locking level %d\n", l); |
| for (i = 0; i < clo_many; i++) { |
| ret = pthread_mutex_lock (&level[l].m[i]); |
| check; |
| stat_mutex_lock++; |
| } |
| if (clo_level > 1) { |
| ret = pthread_mutex_lock (&level[l].d); |
| check; |
| stat_mutex_lock++; |
| } |
| } |
| |
| for (l = 0; l < clo_level; l++) { |
| printf ("unlocking level %d\n", l); |
| for (i = 0; i < clo_many; i++) { |
| ret = pthread_mutex_unlock (&level[l].m[i]); |
| check; |
| stat_mutex_unlock++; |
| } |
| if (clo_level > 1) { |
| ret = pthread_mutex_unlock (&level[l].d); |
| stat_mutex_unlock++; |
| check; |
| } |
| } |
| |
| for (l = 0; l < clo_level; l++) { |
| printf ("deleting level %d\n", l); |
| if (clo_level > 1) { |
| ret = pthread_mutex_destroy (&level[l].d); |
| /// this tests the influence of the deletion in another order. |
| check; |
| stat_mutex_destroy++; |
| } |
| for (i = 0; i < clo_many; i++) { |
| ret = pthread_mutex_destroy (&level[l].m[i]); |
| check; |
| stat_mutex_destroy++; |
| } |
| } |
| return 0; |
| } |
| |
| int main(int argc, char*argv[]) |
| { |
| int loops = 1; |
| int i; |
| if (argc >= 4) loops = atoi(argv[3]); |
| |
| printf ("loops %d\n", loops); |
| for (i = 0; i < loops; i++) |
| doit(argc, argv); |
| |
| printf ("stats: init %d lock %d unlock %d destroy %d\n", |
| stat_mutex_init, stat_mutex_lock, |
| stat_mutex_unlock, stat_mutex_destroy); |
| return 0; |
| } |
| |