00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <basis/array.cpp>
00021 #include <basis/chaos.h>
00022 #include <basis/guards.h>
00023 #include <basis/istring.h>
00024 #include <mechanisms/ithread.h>
00025 #include <mechanisms/safe_roller.h>
00026 #include <mechanisms/semaphore.h>
00027 #include <mechanisms/time_stamp.h>
00028 #include <loggers/file_logger.h>
00029 #include <opsystem/path_configuration.h>
00030 #include <data_struct/static_memory_gremlin.h>
00031
00032 #ifdef __WIN32__
00033 #include <process.h>
00034 #endif
00035
00036 HOOPLE_STARTUP_CODE;
00037
00038 const int DEFAULT_FISH = 64;
00039
00040
00041 const int DEFAULT_RUN_TIME = 142000;
00042
00043
00044 int concurrent_biters = 0;
00045
00046
00047 int grab_lock = 0;
00048
00049
00050 const int MAX_GRABBERS = 8;
00051
00052
00053 semaphore *guard;
00054
00055
00056
00057 bool exit_now = false;
00058
00059
00060 const istring LOGFILE_NAME = path_configuration::make_logfile_name
00061 ("t_semaphore.log");
00062
00063
00064 #define LOG(to_print) log.log(timestamp(true) + istring(to_print))
00065
00066
00067 chaos rando;
00068
00069 class piranha : public ithread
00070 {
00071 public:
00072 piranha() : ithread() {}
00073
00074 void perform_activity(void *) {
00075 file_logger log(LOGFILE_NAME);
00076 safe_add(concurrent_biters, 1);
00077 LOG(istring(istring::SPRINTF, "there are %d biters.", concurrent_biters));
00078 while (!exit_now) {
00079 guard->wait();
00080
00081 LOG(istring(istring::SPRINTF, "locked guard!"));
00082 safe_add(grab_lock, 1);
00083 if (grab_lock > MAX_GRABBERS)
00084 deadly_error("semaphore test", "piranha", "grab lock was already active");
00085
00086 portable::sleep_ms(rando.inclusive(20, 140));
00087
00088 safe_add(grab_lock, -1);
00089
00090 LOG(istring(istring::SPRINTF, "unlocking guard!"));
00091 guard->signal();
00092 }
00093 safe_add(concurrent_biters, -1);
00094 }
00095 };
00096
00097 class barracuda : public ithread
00098 {
00099 public:
00100 barracuda() : ithread() {}
00101
00102 void perform_activity(void *) {
00103 file_logger log(LOGFILE_NAME);
00104 safe_add(concurrent_biters, 1);
00105 LOG(istring(istring::SPRINTF, "there are %d biters.", concurrent_biters));
00106 while (!exit_now) {
00107 guard->wait();
00108
00109 LOG(istring(istring::SPRINTF, "locked guard!"));
00110 safe_add(grab_lock, 1);
00111 if (grab_lock > MAX_GRABBERS)
00112 deadly_error("semaphore test", "barracuda", "grab lock was already active");
00113
00114 portable::sleep_ms(rando.inclusive(20, 140));
00115
00116
00117 safe_add(grab_lock, -1);
00118
00119 LOG(istring(istring::SPRINTF, "unlocking guard!"));
00120 guard->signal();
00121 }
00122 safe_add(concurrent_biters, -1);
00123 }
00124 };
00125
00126 int main(int formal(argc), char *formal(argv)[])
00127 {
00128 file_logger log(LOGFILE_NAME);
00129
00130 guard = new semaphore(MAX_GRABBERS, MAX_GRABBERS);
00131
00132 array<ithread *> threads;
00133
00134 for (int i = 0; i < DEFAULT_FISH; i++) {
00135 if (i % 2) threads += new piranha;
00136 else threads += new barracuda;
00137 }
00138 for (int j = 0; j < threads.length(); j++) threads[j]->start(NIL);
00139
00140 time_stamp when_to_leave(DEFAULT_RUN_TIME);
00141 while (when_to_leave > time_stamp()) { portable::sleep_ms(rando.inclusive(12, 200)); }
00142
00143 LOG("now exiting from all threads....");
00144
00145 exit_now = true;
00146 while (concurrent_biters > 0) { portable::sleep_ms(42); }
00147
00148 LOG("done exiting from all threads....");
00149
00150 delete guard;
00151
00152 for (int k = 0; k < threads.length(); k++) threads[k]->stop();
00153 for (int m = 0; m < threads.length(); m++) delete threads[m];
00154
00155 guards::alert_message("semaphore:: works for all functions tested.");
00156 return 0;
00157 }
00158