sewardj | 866c80c | 2011-10-22 19:29:51 +0000 | [diff] [blame^] | 1 | #include <stdio.h> |
| 2 | #include <pthread.h> |
| 3 | #include <stdlib.h> |
| 4 | #define MANY 1000 |
| 5 | #define LEVEL 100 |
| 6 | typedef struct { |
| 7 | pthread_mutex_t m[MANY]; |
| 8 | pthread_mutex_t d; |
| 9 | } Level; |
| 10 | |
| 11 | static Level level[LEVEL]; |
| 12 | |
| 13 | static int stat_mutex_init = 0; |
| 14 | static int stat_mutex_lock = 0; |
| 15 | static int stat_mutex_unlock = 0; |
| 16 | static int stat_mutex_destroy = 0; |
| 17 | |
| 18 | /* t2t.c : test program for the laog data structure performance testing |
| 19 | and "shaking" : it creates, locks/unlocks and destroy mutex. |
| 20 | |
| 21 | USAGE: t2t [many] [level] [loops] |
| 22 | many (default 100) : how many locks are created/locked/unlocked at a certain level. |
| 23 | level (default 1) : how many levels of "nested locks" are done |
| 24 | loops : how many times these locks are created and destroyed and locked/unlocked) */ |
| 25 | #define check if (ret != 0) printf("error %d at line %d\n", ret, __LINE__) |
| 26 | int doit(int argc, char*argv[]) |
| 27 | { |
| 28 | int l, i; |
| 29 | int ret; |
| 30 | |
| 31 | int clo_many = 100; |
| 32 | int clo_level = 1; |
| 33 | |
| 34 | if (argc >= 2) clo_many = atoi(argv[1]); |
| 35 | if (argc >= 3) clo_level = atoi(argv[2]); |
| 36 | |
| 37 | if (clo_many > MANY) { |
| 38 | printf("error argv[1] (many arg) %d > max MANY %d\n", clo_many, MANY); |
| 39 | exit(1); |
| 40 | } |
| 41 | |
| 42 | if (clo_level > LEVEL) { |
| 43 | printf("error argv[2] (level arg) %d > max LEVEL %d\n", clo_level, LEVEL); |
| 44 | exit(1); |
| 45 | } |
| 46 | |
| 47 | printf ("many %d level %d total_locks: %d\n", |
| 48 | clo_many, clo_level, |
| 49 | clo_many * clo_level + clo_level * (clo_level == 1 ? 0 : 1)); |
| 50 | |
| 51 | for (l = 0; l < clo_level; l++) { |
| 52 | printf ("init level %d\n", l); |
| 53 | for (i = 0; i < clo_many; i++) { |
| 54 | ret = pthread_mutex_init (&level[l].m[i], NULL); |
| 55 | check; |
| 56 | stat_mutex_init++; |
| 57 | } |
| 58 | if (clo_level > 1) { |
| 59 | ret = pthread_mutex_init (&level[l].d, NULL); |
| 60 | check; |
| 61 | stat_mutex_init++; |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | for (l = 0; l < clo_level; l++) { |
| 66 | printf ("locking level %d\n", l); |
| 67 | for (i = 0; i < clo_many; i++) { |
| 68 | ret = pthread_mutex_lock (&level[l].m[i]); |
| 69 | check; |
| 70 | stat_mutex_lock++; |
| 71 | } |
| 72 | if (clo_level > 1) { |
| 73 | ret = pthread_mutex_lock (&level[l].d); |
| 74 | check; |
| 75 | stat_mutex_lock++; |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | for (l = 0; l < clo_level; l++) { |
| 80 | printf ("unlocking level %d\n", l); |
| 81 | for (i = 0; i < clo_many; i++) { |
| 82 | ret = pthread_mutex_unlock (&level[l].m[i]); |
| 83 | check; |
| 84 | stat_mutex_unlock++; |
| 85 | } |
| 86 | if (clo_level > 1) { |
| 87 | ret = pthread_mutex_unlock (&level[l].d); |
| 88 | stat_mutex_unlock++; |
| 89 | check; |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | for (l = 0; l < clo_level; l++) { |
| 94 | printf ("deleting level %d\n", l); |
| 95 | if (clo_level > 1) { |
| 96 | ret = pthread_mutex_destroy (&level[l].d); |
| 97 | /// this tests the influence of the deletion in another order. |
| 98 | check; |
| 99 | stat_mutex_destroy++; |
| 100 | } |
| 101 | for (i = 0; i < clo_many; i++) { |
| 102 | ret = pthread_mutex_destroy (&level[l].m[i]); |
| 103 | check; |
| 104 | stat_mutex_destroy++; |
| 105 | } |
| 106 | } |
| 107 | return 0; |
| 108 | } |
| 109 | |
| 110 | int main(int argc, char*argv[]) |
| 111 | { |
| 112 | int loops = 1; |
| 113 | int i; |
| 114 | if (argc >= 4) loops = atoi(argv[3]); |
| 115 | |
| 116 | printf ("loops %d\n", loops); |
| 117 | for (i = 0; i < loops; i++) |
| 118 | doit(argc, argv); |
| 119 | |
| 120 | printf ("stats: init %d lock %d unlock %d destroy %d\n", |
| 121 | stat_mutex_init, stat_mutex_lock, |
| 122 | stat_mutex_unlock, stat_mutex_destroy); |
| 123 | return 0; |
| 124 | } |
| 125 | |