## log.pkg
#
# This is a low-level kludge to get around cyclic package dependencies when
# doing logging from low-level code like
src/lib/std/src/posix/winix-process--premicrothread.pkg# where file::note and logger::log_if cannot be used directly.
# Compiled by:
#
src/lib/std/src/standard-core.sublibstipulate
# Commented out temporarily(?) 2015-06-26 CrT to allow log.pkg to be used from string-guts.pkg
# package pp = posix_process; # posix_process is from
src/lib/std/src/psx/posix-process.pkgherein
package log {
#
log_note__hook = REF (NULL: Null_Or( (Void -> String) -> Void )); # This gets set at the bottom of
src/lib/std/src/io/winix-text-file-for-os-g--premicrothread.pkg log_warn__hook = REF (NULL: Null_Or( (Void -> String) -> Void )); # This gets set at the bottom of
src/lib/std/src/io/winix-text-file-for-os-g--premicrothread.pkg log_note_in_ramlog__hook = REF (NULL: Null_Or( (Void -> String) -> Void )); # This gets set at the bottom of
src/lib/std/src/io/winix-text-file-for-os-g--premicrothread.pkg log_note_on_stderr__hook = REF (NULL: Null_Or( (Void -> String) -> Void )); # This gets set at the bottom of
src/lib/std/src/io/winix-text-file-for-os-g--premicrothread.pkg log_fatal__hook = REF (\\ msg = { # log_fatal__hook gets set at the bottom of
src/lib/std/src/io/winix-text-file-for-os-g--premicrothread.pkg print msg; # We don't expect this to happen.
# Commented out temporarily(?) 2015-06-26 CrT to allow log.pkg to be used from string-guts.pkg
# pp::exit 0u127; # Lowest-possible exit() fn, to minimize number of packages where log::fatal() is unusable due to package-graph acyclicity constraint.
raise exception DIE msg; # We REALLY don't expect this to happen. We probably should call some wnx::process::exit_uncleanly wnx::process::failure type fn here.
}
);
fun note (msg_maker: Void -> String) # This is used to write routine informational messages to (typically) mythryl.log.
=
case *log_note__hook
#
THE file_note => file_note msg_maker; # file_note will be file::note(). file is from
src/lib/std/src/posix/file--premicrothread.pkg #
NULL => (); # Drop msg on the floor. We could buffer them, but that might well do more harm than good.
esac; # Also, we take advantage of this to shut off log::note during system shutdown, when evaluating
fun warn (msg_maker: Void -> String) # This is used to write warning messages to (typically) mythryl.log.
=
case *log_warn__hook
#
THE file_warn => file_warn msg_maker; # file_warn will be file::warn(). file is from
src/lib/std/src/posix/file--premicrothread.pkg #
NULL => (); # Drop msg on the floor. We could buffer them, but that might well do more harm than good.
esac; # Also, we take advantage of this to shut off log::note during system shutdown, when evaluating
fun fatal (msg: String) # This is used to write fatal-error messages to (typically) mythryl.log.
= # DOES NOT RETURN. Arg is String rather than Void -> String here, since we'll never ignore a log::fatal call.
*log_fatal__hook msg;
fun note_in_ramlog (msg_maker: Void -> String) # This is used to write informational messages to the internal circular ramlog. -- see src/c/main/ramlog.c
= # It is intended for events which happen too frequently to be written to mythryl.log, to provide forensic evidence after a crash.
case *log_note_in_ramlog__hook # ramlog contents may be dumped as ram.log -- see dump_ramlog() in src/c/heapcleaner/heap-debug-stuff.c
#
THE ramlog_note => ramlog_note msg_maker; # ramlog_note will be file::note_in_ramlog(). file is from
src/lib/std/src/posix/file--premicrothread.pkg #
NULL => ();
esac;
fun note_on_stderr (msg_maker: Void -> String) # This does a direct write(STDERR_FILENO, msg); bypassing all hostthread indirection etc.
= # It is intended for debugging use only.
case *log_note_on_stderr__hook #
#
THE stderr_note => stderr_note msg_maker; # stderr_note will be file::note_on_stderr(). file is from
src/lib/std/src/posix/file--premicrothread.pkg #
NULL => ();
esac;
# This belongs in
src/lib/src/lib/thread-kit/src/core-thread-kit/microthread-preemptive-scheduler.pkg # right above need_to_switch_threads_when_exiting_uninterruptible_scope = REF FALSE;
# -- it is here to simplify debugging by making it widely visible for use in printf()s etc
# in places where otherwise doing so would give us a circula dependency error:
#
uninterruptible_scope_mutex = REF 0; # Iff this counter > 0 then thread scheduler is in "uninterruptible mode" (aka "critical section", "atomic region" ...).
internals = REF FALSE; # To limit content of debugging outputs.
debugging = REF FALSE; # To limit scope of debugging outputs.
# See also: log_if_on in src/c/main/error-reporting.c
thread_scheduler_statestring__hook = REF (\\ () = "<unknown>");
fun thread_scheduler_statestring ()
=
*thread_scheduler_statestring__hook (); # Gets set in
src/lib/src/lib/thread-kit/src/core-thread-kit/microthread-preemptive-scheduler.pkg debug_statestring__hook = REF (\\ () = "<unknown>");
fun debug_statestring ()
=
*debug_statestring__hook (); # Gets set in
src/lib/src/lib/thread-kit/src/core-thread-kit/threadkit-unit-test.pkg get_current_microthread's_name__hook = REF (\\ () = "<unknown>");
fun get_current_microthread's_name ()
=
*get_current_microthread's_name__hook (); # Gets set in
src/lib/src/lib/thread-kit/src/core-thread-kit/microthread.pkg fun nop (x: X) = (); # Useful in debugging, say to keep the compiler from optimizing away a debug expression computation or idle loop or such -- compiler doesn't do cross-package analysis.
};
end;