00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <basis/chaos.h>
00022 #include <basis/guards.h>
00023 #include <basis/istring.h>
00024 #include <data_struct/amorph.cpp>
00025 #include <mechanisms/ithread.h>
00026 #include <mechanisms/time_stamp.h>
00027 #include <loggers/file_logger.h>
00028 #include <opsystem/path_configuration.h>
00029 #include <data_struct/static_memory_gremlin.h>
00030
00031 HOOPLE_STARTUP_CODE;
00032
00033 const int DEFAULT_FISH_LOW = 50;
00034 const int DEFAULT_FISH_HIGH = 200;
00035
00036
00037 const int DEFAULT_RUN_TIME = 5 * MINUTE_ms;
00038
00039
00040
00041
00042 const int SLEEP_LOW = 28;
00043 const int SLEEP_HIGH = 114;
00044
00045
00046 const istring LOGFILE_NAME = path_configuration::make_logfile_name
00047 ("t_debug_allocs.log");
00048
00049
00050 const int MAX_ALLOCS_PER_THREAD = 30;
00051
00052
00053 const int MAX_ALLOC = 20000;
00054
00055
00056 #define LOG(to_print) log.log(timestamp(true) + istring(to_print))
00057
00058
00059 chaos rando;
00060
00061 class memory_abuser : public ithread
00062 {
00063 public:
00064 memory_abuser() : ithread(0) {}
00065
00066 virtual ~memory_abuser() {
00067 for (int i = 0; i < _allocations.length(); i++)
00068 WHACK(_allocations[i]);
00069 }
00070
00071 enum test_actions {
00072 FIRST_TEST,
00073 ALLOCATE = FIRST_TEST,
00074 DEALLOCATE,
00075 NOTHING,
00076 ALLOC_DEALLOC,
00077 DEALLOC_ALLOC,
00078 LAST_TEST = DEALLOC_ALLOC
00079 };
00080
00081 void perform_activity(void *formal(data)) {
00082 while (!should_stop()) {
00083 int action = rando.inclusive(FIRST_TEST, LAST_TEST);
00084 switch (action) {
00085 case ALLOCATE: {
00086 if (_allocations.length() > MAX_ALLOCS_PER_THREAD)
00087 break;
00088 int size = rando.inclusive(1, MAX_ALLOC);
00089 byte *alloc = new byte[size];
00090 _allocations += alloc;
00091 break;
00092 }
00093 case DEALLOCATE: {
00094 if (!_allocations.length()) break;
00095 int posn = rando.inclusive(0, _allocations.length() - 1);
00096 WHACK(_allocations[posn]);
00097 _allocations.zap(posn, posn);
00098 break;
00099 }
00100 case NOTHING:
00101
00102 break;
00103 case ALLOC_DEALLOC: {
00104 int size = rando.inclusive(1, MAX_ALLOC);
00105 byte *alloc = new byte[size];
00106 _allocations += alloc;
00107 int posn = rando.inclusive(0, _allocations.length() - 1);
00108 WHACK(_allocations[posn]);
00109 _allocations.zap(posn, posn);
00110 break;
00111 }
00112 case DEALLOC_ALLOC: {
00113 if (!_allocations.length()) break;
00114 int posn = rando.inclusive(0, _allocations.length() - 1);
00115 WHACK(_allocations[posn]);
00116 _allocations.zap(posn, posn);
00117 int size = rando.inclusive(1, MAX_ALLOC);
00118 byte *alloc = new byte[size];
00119 _allocations += alloc;
00120 break;
00121 }
00122
00123 }
00124 int might_sleep = rando.inclusive(1, 100);
00125
00126 if (might_sleep >= 98) {
00127 int sleepy = rando.inclusive(SLEEP_LOW, SLEEP_HIGH);
00128 portable::sleep_ms(sleepy);
00129 }
00130 }
00131 }
00132
00133 private:
00134 array<byte *> _allocations;
00135 };
00136
00137 #define static_class_name() "t_debug_alloc"
00138
00139 #ifdef __WIN32__
00140 int WINAPI WinMain(application_instance instance,
00141 application_instance prev_instance, LPSTR lpCmdLine, int nCmdShow)
00142 #else
00143 int main(int formal(argc), char *formal(argv)[])
00144 #endif
00145 {
00146 FUNCDEF("main");
00147 file_logger log(LOGFILE_NAME);
00148
00149 amorph<ithread> thread_list;
00150
00151 int fishies = rando.inclusive(DEFAULT_FISH_LOW, DEFAULT_FISH_HIGH);
00152 LOG(istring(istring::SPRINTF, "using %d fish in test.", fishies));
00153
00154 for (int i = 0; i < fishies; i++) {
00155 ithread *t = new memory_abuser;
00156 thread_list.append(t);
00157 ithread *q = thread_list[thread_list.elements() - 1];
00158 if (q != t)
00159 deadly_error(static_class_name(), func, "amorph has incorrect pointer!");
00160
00161 thread_list[thread_list.elements() - 1]->start(NIL);
00162 }
00163
00164 time_stamp when_to_leave(DEFAULT_RUN_TIME);
00165 while (when_to_leave > time_stamp())
00166 portable::sleep_ms(rando.inclusive(12, 200));
00167
00168 LOG("now exiting from all threads....");
00169
00170
00171
00172
00173 for (int j = 0; j < thread_list.elements(); j++) thread_list[j]->stop();
00174
00175 thread_list.reset();
00176
00177 LOG("done exiting from all threads....");
00178
00179 guards::alert_message("OS allocations:: works for all functions tested.");
00180 return 0;
00181 }
00182
00183 #undef static_class_name
00184