From a54a021b1cf8d3e7f3405ed88a06ef38e3103970 Mon Sep 17 00:00:00 2001 From: "Fred T. Hamster" Date: Sun, 8 Feb 2026 15:43:44 -0500 Subject: [PATCH] test timer driver is working again had to bring back some old windoze code for it, in event_extensions. this will not build for real yet on windows, but that's a task for another day. the tester is working great on linux! --- .../library/application/event_extensions.cpp | 93 ++++++++++++++ .../library/application/event_extensions.h | 60 +++++++++ nucleus/library/application/makefile | 7 +- .../library/application/windoze_helper.cpp | 3 + nucleus/library/application/windoze_helper.h | 2 +- .../{aa-readme.txt => aa_readme.txt} | 5 +- nucleus/library/tests_application/makefile | 11 -- nucleus/library/tests_timely/makefile | 2 +- .../library/tests_timely/test_earth_time.cpp | 2 + .../library/tests_timely/test_stopwatch.cpp | 3 +- .../test_timer_driver.cpp | 115 ++++++++++-------- nucleus/library/timely/timer_driver.cpp | 28 +++-- .../buildor/upgrade_hoople_to_feistymeow.sh | 1 + 13 files changed, 253 insertions(+), 79 deletions(-) create mode 100644 nucleus/library/application/event_extensions.cpp create mode 100644 nucleus/library/application/event_extensions.h rename nucleus/library/tests_application/{aa-readme.txt => aa_readme.txt} (96%) rename nucleus/library/{tests_application => tests_timely}/test_timer_driver.cpp (63%) diff --git a/nucleus/library/application/event_extensions.cpp b/nucleus/library/application/event_extensions.cpp new file mode 100644 index 00000000..92de8078 --- /dev/null +++ b/nucleus/library/application/event_extensions.cpp @@ -0,0 +1,93 @@ +#ifndef EVENT_EXTENSIONS_IMPLEMENTATION_FILE +#define EVENT_EXTENSIONS_IMPLEMENTATION_FILE + +/*****************************************************************************\ +* * +* Name : event_extensions * +* Author : Chris Koeritz * +* * +******************************************************************************* +* Copyright (c) 1995-$now By Author. This program is free software; you can * +* redistribute it and/or modify it under the terms of the GNU General Public * +* License as published by the Free Software Foundation; either version 2 of * +* the License or (at your option) any later version. This is online at: * +* http://www.fsf.org/copyleft/gpl.html * +* Please send any updates to: fred@gruntose.com * +\*****************************************************************************/ + +#ifdef __WIN32__ + +#include "event_extensions.h" + +#include +#include +#include + +#include + +bool event_extensions::poll() +{ + MSG message; + return poll(message); +} + +bool event_extensions::poll(MSG &message) +{ + return windoze_helper::event_poll(message); +/* + message.hwnd = 0; + message.message = 0; + message.wParam = 0; + message.lParam = 0; + if (PeekMessage(&message, NIL, 0, 0, PM_REMOVE)) { + TranslateMessage(&message); + DispatchMessage(&message); + } + return true; +*/ +} + +bool event_extensions::poll(int wait) +{ + time_stamp start_time; + do { + MSG message; + if (!poll(message)) return false; + } while (wait && (time_stamp().value() - start_time.value() <= wait)); + return true; +} + +bool event_extensions::poll_on_message(window_handle handle, UINT look_for, + int wait, MSG &message) +{ + time_stamp start_time; + do { + bool okay = poll(message); + if (!okay) return false; + if ( (message.hwnd == handle) && (message.message == look_for) ) + return true; + } while (time_stamp().value() - start_time.value() <= wait); + // keep going while time is left. + return false; +} + +bool event_extensions::poll_on_message_and_wparam(window_handle handle, + UINT look_for, WPARAM look_also, int wait, MSG &message) +{ + time_stamp start_time; + do { + bool okay = poll(message); + if (!okay) return false; + if ( (message.hwnd == handle) && (message.wParam == look_also) + && (message.message == look_for) ) + return true; + } while (time_stamp().value() - start_time.value() <= wait); + // keep going while time is left. + return false; +} + +#endif + + +#endif //EVENT_EXTENSIONS_IMPLEMENTATION_FILE + diff --git a/nucleus/library/application/event_extensions.h b/nucleus/library/application/event_extensions.h new file mode 100644 index 00000000..9b671dbd --- /dev/null +++ b/nucleus/library/application/event_extensions.h @@ -0,0 +1,60 @@ +#ifndef EVENT_EXTENSIONS_CLASS +#define EVENT_EXTENSIONS_CLASS + +/*****************************************************************************\ +* * +* Name : event_extensions * +* Author : Chris Koeritz * +* * +******************************************************************************* +* Copyright (c) 1995-$now By Author. This program is free software; you can * +* redistribute it and/or modify it under the terms of the GNU General Public * +* License as published by the Free Software Foundation; either version 2 of * +* the License or (at your option) any later version. This is online at: * +* http://www.fsf.org/copyleft/gpl.html * +* Please send any updates to: fred@gruntose.com * +\*****************************************************************************/ + +//! Provides some useful extensions to event handling in windows. + +#ifdef __WIN32__ + +#include "opsysdll.h" + +#include +#include + +class OPSYSTEM_CLASS_STYLE event_extensions +{ +public: + static bool poll(); + //!< allows one event to be processed. + /*!< this will possibly yield control to other programs also. if an event + is processed, then true is returned. if no event was found, then false + is returned. */ + + static bool poll(MSG &message); + //!< processes one event like poll, but returns what the event was. + /*!< if no message was processed, then "message" is reset to zeros. */ + + static bool poll(int wait); + //!< polls for events until the "wait" time (in milliseconds) has elapsed. + /*!< this does not block other windows in the program because events are + still being handled. the return value is true if the poll completed + successfully and false if it had to abort for some reason. */ + + static bool poll_on_message(window_handle handle, UINT msg, int wait, + MSG &found); + //!< polls awaiting the message "msg" for the window "win". + /*!< if the message is found within "wait" milliseconds, then it is + stored in "found" and true is returned. otherwise, false is returned. */ + + static bool poll_on_message_and_wparam(window_handle handle, UINT msg, + WPARAM wparam, int wait, MSG &found); + //!< like poll_on_message, but also requires the wParam to equal "wparam". +}; + +#endif // win32. + +#endif // outer guard. + diff --git a/nucleus/library/application/makefile b/nucleus/library/application/makefile index c2548b55..c564ff4c 100644 --- a/nucleus/library/application/makefile +++ b/nucleus/library/application/makefile @@ -2,9 +2,10 @@ include cpp/variables.def PROJECT = application TYPE = library -SOURCE = application_shell.cpp callstack_tracker.cpp command_line.cpp dll_root.cpp \ - hoople_service.cpp launch_manager.cpp memory_checker.cpp redirecter.cpp \ - registry_config.cpp shared_memory.cpp singleton_application.cpp windoze_helper.cpp +SOURCE = application_shell.cpp callstack_tracker.cpp command_line.cpp \ + dll_root.cpp event_extensions.cpp hoople_service.cpp launch_manager.cpp \ + memory_checker.cpp redirecter.cpp registry_config.cpp shared_memory.cpp \ + singleton_application.cpp windoze_helper.cpp TARGETS = application.lib LOCAL_LIBS_USED = basis diff --git a/nucleus/library/application/windoze_helper.cpp b/nucleus/library/application/windoze_helper.cpp index 1dfbefad..7e643faa 100644 --- a/nucleus/library/application/windoze_helper.cpp +++ b/nucleus/library/application/windoze_helper.cpp @@ -300,6 +300,7 @@ istring null_device() return "/dev/null"; #endif } +*/ #ifdef __WIN32__ bool event_poll(MSG &message) @@ -316,6 +317,8 @@ bool event_poll(MSG &message) } #endif +/* + // makes a complaint about a failure. #ifndef EMBEDDED_BUILD #define COMPLAIN_QUERY(to_print) { \ diff --git a/nucleus/library/application/windoze_helper.h b/nucleus/library/application/windoze_helper.h index 9a149a41..1c0bab93 100644 --- a/nucleus/library/application/windoze_helper.h +++ b/nucleus/library/application/windoze_helper.h @@ -199,7 +199,7 @@ namespace application { // ms-windows of more modern types, i.e. win32. #ifdef __WIN32__ -// bool event_poll(MSG &message); + bool event_poll(MSG &message); //!< tries to process one win32 event and retrieve the "message" from it. /*!< this is a very general poll and will retrieve any message that's available for the current thread. the message is actually processed diff --git a/nucleus/library/tests_application/aa-readme.txt b/nucleus/library/tests_application/aa_readme.txt similarity index 96% rename from nucleus/library/tests_application/aa-readme.txt rename to nucleus/library/tests_application/aa_readme.txt index 51fa928c..aa4670e1 100644 --- a/nucleus/library/tests_application/aa-readme.txt +++ b/nucleus/library/tests_application/aa_readme.txt @@ -22,8 +22,11 @@ hoople_service.h launch_manager.h memory_checker.h redirecter.h -registry_config.h +DONE: registry_config.h shared_memory.h singleton_application.h window_classist.h windoze_helper.h + + + diff --git a/nucleus/library/tests_application/makefile b/nucleus/library/tests_application/makefile index 99d37536..ab587320 100644 --- a/nucleus/library/tests_application/makefile +++ b/nucleus/library/tests_application/makefile @@ -6,21 +6,10 @@ PROJECT = tests_application TYPE = test TARGETS = test_break_signal.exe test_command_line.exe test_path_configuration.exe \ test_registry_configurator.exe -# test_logger.exe \ -# test_redirection.exe \ -# test_rendezvous.exe test_system_values.exe test_timer_driver.exe -#ifeq "$(findstring EMBEDDED_BUILD, $(DEFINITIONS))" "" -# TARGETS += test_shared_memory.exe -#endif -##LOCAL_LIBS_USED = basis i_library DEFINITIONS += USE_FEISTY_MEOW_DLLS LOCAL_LIBS_USED = unit_test application configuration filesystem loggers \ mathematics nodes processes structures textual timely structures basis RUN_TARGETS = $(ACTUAL_TARGETS) -# test_logger.exe \ -# test_path_configuration.exe test_registry_configurator.exe \ -# test_system_values.exe test_timer_driver.exe - include cpp/rules.def diff --git a/nucleus/library/tests_timely/makefile b/nucleus/library/tests_timely/makefile index f3690f45..db6d5f65 100644 --- a/nucleus/library/tests_timely/makefile +++ b/nucleus/library/tests_timely/makefile @@ -2,7 +2,7 @@ include cpp/variables.def PROJECT = tests_timely TYPE = test -TARGETS = test_earth_time.exe test_stopwatch.exe +TARGETS = test_earth_time.exe test_stopwatch.exe test_timer_driver.exe DEFINITIONS += USE_FEISTY_MEOW_DLLS LOCAL_LIBS_USED = unit_test application processes loggers configuration mathematics nodes \ structures textual timely filesystem structures basis diff --git a/nucleus/library/tests_timely/test_earth_time.cpp b/nucleus/library/tests_timely/test_earth_time.cpp index 75b7770f..373a19d7 100644 --- a/nucleus/library/tests_timely/test_earth_time.cpp +++ b/nucleus/library/tests_timely/test_earth_time.cpp @@ -145,6 +145,8 @@ int test_earth_time::execute() run_test_02(); run_test_03(); + critical_events::alert_message(astring(class_name()) + ": works for those functions tested."); + return final_report(); } diff --git a/nucleus/library/tests_timely/test_stopwatch.cpp b/nucleus/library/tests_timely/test_stopwatch.cpp index 6352cba9..fd20ca02 100644 --- a/nucleus/library/tests_timely/test_stopwatch.cpp +++ b/nucleus/library/tests_timely/test_stopwatch.cpp @@ -81,7 +81,8 @@ int test_stopwatch::execute() deadly_error(class_name(), "second", "unacceptable timer deviation"); fred_time.reset(); - critical_events::alert_message("stopwatch:: works for those functions tested."); + critical_events::alert_message(astring(class_name()) + ": works for those functions tested."); + return 0; } diff --git a/nucleus/library/tests_application/test_timer_driver.cpp b/nucleus/library/tests_timely/test_timer_driver.cpp similarity index 63% rename from nucleus/library/tests_application/test_timer_driver.cpp rename to nucleus/library/tests_timely/test_timer_driver.cpp index ba7fff19..4eb3a1c7 100644 --- a/nucleus/library/tests_application/test_timer_driver.cpp +++ b/nucleus/library/tests_timely/test_timer_driver.cpp @@ -16,36 +16,50 @@ * Please send any updates to: fred@gruntose.com * \*****************************************************************************/ -#include -#include +#include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include #include -#include -#include - -#define LOG(s) STAMPED_EMERGENCY_LOG(program_wide_logger(), s) - -const int TEST_DURATION = 3 * MINUTE_ms; +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace application; +using namespace basis; +using namespace filesystem; +using namespace loggers; +using namespace processes; +using namespace structures; +using namespace timely; +using namespace unit_test; + +#define LOG(s) STAMPED_EMERGENCY_LOG(program_wide_logger::get(), s) + +const int DEFAULT_TEST_DURATION = 3 * SECOND_ms; + // with no arguments to the test, we'll run timers for this very short duration. const int MAX_THREADS = 120; -//////////////////////////////////////////////////////////////////////////// +////////////// -class timer_driver_tester : public application_shell +class timer_driver_tester : virtual public unit_base, virtual public application_shell { public: timer_driver_tester() - : application_shell(static_class_name()), _in_progress(false) {} - IMPLEMENT_CLASS_NAME("timer_driver_tester"); + : application_shell(), _in_progress(false) {} + DEFINE_CLASS_NAME("timer_driver_tester"); virtual ~timer_driver_tester() {} int execute(); @@ -64,16 +78,16 @@ private: thread_cabinet _threads; // storage for our time_stamp testing threads. }; -//////////////////////////////////////////////////////////////////////////// +////////////// -class timer_test_thread : public ithread +class timer_test_thread : public ethread { public: timer_test_thread(application_shell &parent) - : ithread(parent.randomizer().inclusive(20, 480)), _parent(parent) - { start(NIL); } + : ethread(parent.randomizer().inclusive(8, 25)), _parent(parent) + { start(NULL_POINTER); } - IMPLEMENT_CLASS_NAME("timer_test_thread"); + DEFINE_CLASS_NAME("timer_test_thread"); void perform_activity(void *) { FUNCDEF("perform_activity"); if (time_stamp() < _started) @@ -93,23 +107,23 @@ private: time_stamp _last; }; -//////////////////////////////////////////////////////////////////////////// +////////////// -class my_timer_handler : public timed_object +class my_timer_handler : public timeable { public: my_timer_handler(timer_driver_tester &parent, int id) : _id(id), _parent(parent) {} virtual ~my_timer_handler() {} - IMPLEMENT_CLASS_NAME("my_timer_handler"); + DEFINE_CLASS_NAME("my_timer_handler"); virtual void handle_timer_callback() { FUNCDEF("handle_timer_callback"); if (_parent.in_progress()) LOG("saw in progress flag set to true! we interrupted real " "ops, not just sleep!"); - LOG(isprintf("timer%d hit.", _id)); + LOG(a_sprintf("timer%d hit.", _id)); timer_test_thread *new_thread = new timer_test_thread(_parent); - unique_int id = _parent.threads().add_thread(new_thread, false, NIL); + unique_int id = _parent.threads().add_thread(new_thread, false, NULL_POINTER); // the test thread auto-starts, so we don't let the cabinet start it. if (!id) deadly_error(class_name(), func, "failed to start a new thread."); @@ -118,11 +132,11 @@ public: int gone_index = _parent.randomizer().inclusive(0, _parent.threads().threads() - 1); unique_int gone_thread = _parent.threads().thread_ids()[gone_index]; _parent.threads().cancel_thread(gone_thread); - portable::sleep_ms(100); // allow thread to start up. + time_control::sleep_ms(100); // allow thread to start up. } _parent.threads().clean_debris(); // toss any dead threads. - LOG(isprintf("%d threads checking time_stamp.", _parent.threads().threads())); + LOG(a_sprintf("%d threads checking time_stamp.", _parent.threads().threads())); } private: @@ -130,30 +144,35 @@ private: timer_driver_tester &_parent; }; -//////////////////////////////////////////////////////////////////////////// +////////////// #define CREATE_TIMER(name, id, dur) \ my_timer_handler name(*this, id); \ program_wide_timer().set_timer(dur, &name); \ - LOG(istring("timer ") + #name + " hitting every " \ - + #dur + " ms") + LOG(astring("created timer ") + #name + " which hits every " + #dur + " ms") #define ZAP_TIMER(name) \ program_wide_timer().zap_timer(&name) int timer_driver_tester::execute() { - SET_DEFAULT_COMBO_LOGGER; + int next_id = 1001; // we start issuing timer IDs at 1001 for this test. + + int runtime_ms = DEFAULT_TEST_DURATION; + if (application::_global_argc >= 2) { + astring passed_runtime = application::_global_argv[1]; + runtime_ms = passed_runtime.convert(DEFAULT_TEST_DURATION); + } - CREATE_TIMER(timer1, 1, 500); -// CREATE_TIMER(timer1, 1, 10); - CREATE_TIMER(timer2, 2, SECOND_ms); - CREATE_TIMER(timer3, 3, 3 * SECOND_ms); - CREATE_TIMER(timer4, 4, 8 * SECOND_ms); - CREATE_TIMER(timer5, 5, 12 * SECOND_ms); + // some odd timer cycles below to avoid waiting longer than our short default. + CREATE_TIMER(timer1, unique_int(next_id++).raw_id(), 1 * SECOND_ms); + CREATE_TIMER(timer2, unique_int(next_id++).raw_id(), 250); + CREATE_TIMER(timer3, unique_int(next_id++).raw_id(), 3 * SECOND_ms); + CREATE_TIMER(timer4, unique_int(next_id++).raw_id(), 140); + CREATE_TIMER(timer5, unique_int(next_id++).raw_id(), 500); LOG("pausing for a while..."); - time_stamp when_done(TEST_DURATION); + time_stamp when_done(runtime_ms); while (time_stamp() < when_done) { _in_progress = true; // do some various calculations in here and see if we're interrupted @@ -165,25 +184,25 @@ int timer_driver_tester::execute() } _in_progress = false; #ifdef __UNIX__ - portable::sleep_ms(100); + time_control::sleep_ms(100); #else bool okay = event_extensions::poll(); if (!okay) break; #endif } - guards::alert_message("timer_driver:: works for all functions tested (if messages seem appropriate)."); - ZAP_TIMER(timer1); ZAP_TIMER(timer2); ZAP_TIMER(timer3); ZAP_TIMER(timer4); ZAP_TIMER(timer5); + critical_events::alert_message(astring(class_name()) + ": works for those functions tested."); + return 0; } -//////////////////////////////////////////////////////////////////////////// +////////////// HOOPLE_MAIN(timer_driver_tester, ) diff --git a/nucleus/library/timely/timer_driver.cpp b/nucleus/library/timely/timer_driver.cpp index 8b6a5fbd..1f5421c9 100644 --- a/nucleus/library/timely/timer_driver.cpp +++ b/nucleus/library/timely/timer_driver.cpp @@ -36,7 +36,7 @@ using namespace timely; // uncomment for noisy code. #undef LOG -#define LOG(tpr) printf("%s", (time_stamp::notarize() + "timer_driver::" + func + tpr).s() ) +#define LOG(tpr) printf("%s\n", (time_stamp::notarize() + "timer_driver::" + func + ": " + tpr).s() ) namespace timely { @@ -285,9 +285,9 @@ void timer_driver::handle_system_timer() } unhook_OS_timer(); -#ifdef DEBUG_TIMER_DRIVER - LOG("into handling OS timer..."); -#endif +//#ifdef DEBUG_TIMER_DRIVER +// LOG("into handling OS timer..."); +//#endif array to_invoke_now; @@ -376,9 +376,9 @@ void timer_driver::handle_system_timer() } } -#ifdef DEBUG_TIMER_DRIVER - LOG("done handling OS timer."); -#endif +//#ifdef DEBUG_TIMER_DRIVER +// LOG("done handling OS timer."); +//#endif // set the next expiration time to the smallest next guy. reset_OS_timer(next_timer_duration); @@ -426,18 +426,20 @@ void timer_driver::hookup_OS_timer(int duration) void timer_driver::unhook_OS_timer() { -#ifdef DEBUG_TIMER_DRIVER - FUNCDEF("unhook_OS_timer"); -#endif +//#ifdef DEBUG_TIMER_DRIVER +// FUNCDEF("unhook_OS_timer"); +//#endif + //#if defined(__UNIX__) || defined(__GNU_WINDOWS__) // postpone the thread for quite a while so we can take care of business. _prompter->reschedule(LONG_TIME); //#elif defined(_MSC_VER) // if (_real_timer_id) KillTimer(NULL_POINTER, (UINT_PTR)_real_timer_id); //#endif -#ifdef DEBUG_TIMER_DRIVER - LOG("unhooked OS timer."); -#endif + +//#ifdef DEBUG_TIMER_DRIVER +// LOG("unhooked OS timer."); +//#endif } void timer_driver::reset_OS_timer(int next_hit) diff --git a/scripts/buildor/upgrade_hoople_to_feistymeow.sh b/scripts/buildor/upgrade_hoople_to_feistymeow.sh index 61802fe4..79b16e49 100644 --- a/scripts/buildor/upgrade_hoople_to_feistymeow.sh +++ b/scripts/buildor/upgrade_hoople_to_feistymeow.sh @@ -157,6 +157,7 @@ standards and usages." | sed -e 's/^#include *$/#include /g' \ | sed -e 's/^#include *$/#include /g' \ | sed -e 's/^#include *$/#include /g' \ + | sed -e 's/^#include *$/#include /g' \ | sed -e 's/log_base::NO_ENDING/parser_bits::NO_ENDING/g' \ | sed -e 's/log_base::CRLF_AT_END/parser_bits::CRLF_AT_END/g' \ | sed -e 's/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/[\/]*/\/\/\/\/\/\/\/\/\/\/\/\/\/\//g' \ -- 2.34.1