aboutsummaryrefslogtreecommitdiff
path: root/unused.jai
diff options
context:
space:
mode:
Diffstat (limited to 'unused.jai')
-rw-r--r--unused.jai353
1 files changed, 353 insertions, 0 deletions
diff --git a/unused.jai b/unused.jai
new file mode 100644
index 0000000..1f71b37
--- /dev/null
+++ b/unused.jai
@@ -0,0 +1,353 @@
+auto_release_temp(); // automatically release temporary memory.
+print(">%<", S64_MIN + delta, to_standard_error = true);
+print_to_builder(*builder, "Average % us (% / % bytes) ---------", dbg_average/1000, context.temporary_storage.total_bytes_occupied, context.temporary_storage.high_water_mark); // DEBUG
+print("temp [% .. % .. %] \n", context.temporary_storage.data, get_temporary_storage_mark(), context.temporary_storage.data + context.temporary_storage.size-1);
+
+
+// MEASURE PERFORMANCE
+{
+ dbg_average := 0; // DEBUG
+ dbg_count := 0; // DEBUG
+
+ #import "Basic";
+
+ // Cumulative average: CA_n+1 = (x_n+1 + n*CA_n ) / (n + 1)
+ start := current_time_monotonic(); // DEBUG
+ // ...code to be measured...
+ stop := current_time_monotonic(); // DEBUG
+ dbg_sample := to_nanoseconds(stop-start); // DEBUG
+ dbg_average = (dbg_sample + dbg_count * dbg_average) / (dbg_count + 1); // DEBUG
+ dbg_count += 1; // DEBUG
+ print("Average % ns.\n", dbg_average); // DEBUG
+}
+
+// Memory allocator debugging.
+print_owner_allocator :: (tag: string, memory: *void) {
+ owner := "unkown";
+
+ if true == xx context.allocator.proc(.IS_THIS_YOURS, 0, 0, memory, null) then owner = "default";
+ else if true == xx temp.proc(.IS_THIS_YOURS, 0, 0, memory, null) then owner = "temp";
+
+ print("'%' belongs to '%'\n", tag, owner);
+}
+
+// ttt's database debugging.
+print_database :: (db: Database) {
+ for db.tasks {
+ print("% | % : % : % : % : % : % : %\n", cast(string)it.name,
+ it.times[0],
+ it.times[1],
+ it.times[2],
+ it.times[3],
+ it.times[4],
+ it.times[5],
+ it.times[6]
+ );
+ }
+}
+
+// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- //
+
+
+// Average cumulative calculation.
+average: float64 = 0;
+counter: float64 = 0;
+t0 := current_time_monotonic();
+t1 := current_time_monotonic();
+set_cursor_position(2, 47);
+sample := cast(float64)to_nanoseconds(t1-t0)/1000;
+average = (sample + counter * average) / (counter + 1);
+counter += 1;
+print(">%us<", average);
+
+
+// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- //
+
+// Implementation of tcsetattr, tcgetattr, and tcflush using only 'ioctl' which is provided by jai.
+
+#if USE_LIBC {
+
+ libc :: #system_library "libc";
+
+ // https://codebrowser.dev/glibc/glibc/sysdeps/unix/sysv/linux/tcsetattr.c.html
+ tcsetattr :: (fd: s32, optional_actions: s32, termios_p : *Terminal_IO_Mode) -> s32 #foreign libc;
+
+ // https://codebrowser.dev/glibc/glibc/sysdeps/unix/sysv/linux/tcgetattr.c.html
+ tcgetattr :: (fd: s32, termios_p: *Terminal_IO_Mode) -> s32 #foreign libc;
+
+ // https://codebrowser.dev/glibc/glibc/sysdeps/unix/sysv/linux/tcflush.c.html
+ tcflush :: (fd: s32, queue_selector: s32) -> s32 #foreign libc;
+}
+else {
+
+ // https://codebrowser.dev/glibc/glibc/sysdeps/unix/sysv/linux/tcsetattr.c.html
+ tcsetattr :: (fd: s32, optional_actions: s32, termios_p : *Terminal_IO_Mode) -> s32 {
+
+ #if OS == .LINUX {
+ TCSETS :: 0x5402;
+ TCSETSW :: 0x5403;
+ TCSETSF :: 0x5404;
+ tcflag_t :: u32;
+ cc_t :: u8;
+ __KERNEL_NCCS :: 19;
+ __kernel_termios :: struct {
+ c_iflag : tcflag_t; // input mode flags
+ c_oflag : tcflag_t; // output mode flags
+ c_cflag : tcflag_t; // control mode flags
+ c_lflag : tcflag_t; // local mode flags
+ c_line : cc_t; // line discipline
+ c_cc : [__KERNEL_NCCS]cc_t; // control characters
+ };
+
+ k_termios: __kernel_termios;
+ cmd: u64;
+ if optional_actions == {
+ case xx Optional_Actions.TCSANOW;
+ cmd = TCSETS;
+
+ case xx Optional_Actions.TCSADRAIN;
+ cmd = TCSETSW;
+
+ case xx Optional_Actions.TCSAFLUSH;
+ cmd = TCSETSF;
+
+ case;
+ return EINVAL;
+ }
+ // k_termios.c_iflag = termios_p.c_iflag & ~IBAUD0;
+ k_termios.c_iflag = xx termios_p.c_iflag;
+ k_termios.c_oflag = xx termios_p.c_oflag;
+ k_termios.c_cflag = xx termios_p.c_cflag;
+ k_termios.c_lflag = xx termios_p.c_lflag;
+ k_termios.c_line = xx termios_p.c_line;
+ // #if _HAVE_C_ISPEED && _HAVE_STRUCT_TERMIOS_C_ISPEED
+ // k_termios.c_ispeed = termios_p->c_ispeed;
+ // #endif
+ // #if _HAVE_C_OSPEED && _HAVE_STRUCT_TERMIOS_C_OSPEED
+ // k_termios.c_ospeed = termios_p->c_ospeed;
+ // #endif
+ memcpy(*k_termios.c_cc[0], *termios_p.c_cc[0], __KERNEL_NCCS * 1);//size_of(cc_t));
+ return ioctl(fd, cmd, *k_termios);
+ }
+ #if OS == .MACOS {
+ // return __ioctl (fd, TIOCSETAF, termios_p);
+ #assert(false, "NOT IMPLEMENTED");
+ }
+ return 0;
+ }
+
+ // https://codebrowser.dev/glibc/glibc/sysdeps/unix/sysv/linux/tcgetattr.c.html
+ tcgetattr :: (fd: s32, termios_p: *Terminal_IO_Mode) -> s32 {
+ TCSETS :: 0x5402;
+ TCSETSW :: 0x5403;
+ TCSETSF :: 0x5404;
+ tcflag_t :: u32;
+ cc_t :: u8;
+ __KERNEL_NCCS :: 19;
+ __kernel_termios :: struct {
+ c_iflag : tcflag_t; // input mode flags
+ c_oflag : tcflag_t; // output mode flags
+ c_cflag : tcflag_t; // control mode flags
+ c_lflag : tcflag_t; // local mode flags
+ c_line : cc_t; // line discipline
+ c_cc : [__KERNEL_NCCS]cc_t; // control characters
+ };
+
+
+ // int
+ // __tcgetattr (int fd, struct termios *termios_p)
+ // {
+ // struct __kernel_termios k_termios;
+ k_termios: __kernel_termios;
+ retval: int;
+ retval = ioctl(fd, TCGETS, *k_termios);
+ if retval == 0 {
+ termios_p.c_iflag = xx k_termios.c_iflag;
+ termios_p.c_oflag = xx k_termios.c_oflag;
+ termios_p.c_cflag = xx k_termios.c_cflag;
+ termios_p.c_lflag = xx k_termios.c_lflag;
+ termios_p.c_line = xx k_termios.c_line;
+ // #if _HAVE_STRUCT_TERMIOS_C_ISPEED
+ // # if _HAVE_C_ISPEED
+ // termios_p->c_ispeed = k_termios.c_ispeed;
+ // # else
+ // termios_p->c_ispeed = k_termios.c_cflag & (CBAUD | CBAUDEX);
+ // # endif
+ // #endif
+ // #if _HAVE_STRUCT_TERMIOS_C_OSPEED
+ // # if _HAVE_C_OSPEED
+ // termios_p->c_ospeed = k_termios.c_ospeed;
+ // # else
+ // termios_p->c_ospeed = k_termios.c_cflag & (CBAUD | CBAUDEX);
+ // # endif
+ // #endif
+ size_of_cc_t := __KERNEL_NCCS * 1;
+ memcpy(*termios_p.c_cc[0], *k_termios.c_cc[0], size_of_cc_t);
+ // memset(*termios_p.c_cc[0] + size_of_cc_t + 1, _POSIX_VDISABLE, (NCCS - __KERNEL_NCCS) * 1);
+ //
+ // if (sizeof (cc_t) == 1 || _POSIX_VDISABLE == 0 || (unsigned char) _POSIX_VDISABLE == (unsigned char) -1) {
+ // memset (__mempcpy (&termios_p->c_cc[0], &k_termios.c_cc[0], __KERNEL_NCCS * sizeof (cc_t)), _POSIX_VDISABLE, (NCCS - __KERNEL_NCCS) * sizeof (cc_t));
+ // }
+ // else
+ // {
+ // memcpy (&termios_p->c_cc[0], &k_termios.c_cc[0], __KERNEL_NCCS * sizeof (cc_t));
+ // for (size_t cnt = __KERNEL_NCCS; cnt < NCCS; ++cnt) {
+ // termios_p->c_cc[cnt] = _POSIX_VDISABLE;
+ // }
+ // }
+ }
+ return xx retval;
+ }
+
+ // https://codebrowser.dev/glibc/glibc/sysdeps/unix/sysv/linux/tcflush.c.html
+ tcflush :: inline (fd: s32, queue_selector: s32) -> s32 {
+ TCFLSH :: 0x540B;
+ return ioctl(fd, TCFLSH, queue_selector);
+ }
+}
+
+// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- //
+
+
+Step_Iterator :: struct {
+ min: int;
+ max: int;
+ step: int;
+}
+
+step_iterator :: (min: int, max: int, step: int) -> Step_Iterator {
+ return .{ min, max, step };
+}
+
+for_expansion :: (iterator: Step_Iterator, body: Code, flags: For_Flags) #expand {
+ iteration_count: int;
+ for <=cast(bool)(flags & .REVERSE) i: iterator.min..iterator.max {
+ iteration_count += 1;
+ if iteration_count % iterator.step == 0 continue;
+
+ `it := i;
+ `it_index := void;
+
+ #insert body;
+ }
+}
+
+for step_iterator(0, 10, 2) {
+ log("%", it);
+}
+
+
+// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- //
+
+
+// Check what's going on with the temp allocator:
+// Is it really the responsible for these paths?
+// It seems that the next beta (after 0.1.055b) compiler allows us to check this pretty easily.
+//
+//
+// An example that uses several different allocators, then asks them all
+// who owns which memory.
+//
+// Note that this is probably not the kind of thing you want to do at runtime
+// in the steady state, as it may not be very fast, but it could be a very helpful
+// debugging facility.
+//
+
+#import "Basic";
+#import "Pool";
+#import "Flat_Pool";
+#import "rpmalloc";
+
+main :: () {
+ pool: Pool;
+ flat: Flat_Pool;
+
+ a := context.default_allocator;
+ b := Allocator.{pool_allocator_proc, *pool};
+ c := Allocator.{flat_pool_allocator_proc, *flat};
+ d := Allocator.{rpmalloc_allocator_proc, null};
+
+ d.proc(.STARTUP, 0, 0, null, null); // rpmalloc needs explicit init right now, but others don't.
+
+ ma := alloc(1000, allocator=a);
+ mb := alloc(1000, allocator=b);
+ mc := alloc(1000, allocator=c);
+ md := alloc(1000, allocator=d);
+
+ report_who_owns(ma, a, b, c, d);
+ report_who_owns(mb, a, b, c, d);
+ report_who_owns(mc, a, b, c, d);
+ report_who_owns(md, a, b, c, d);
+}
+
+report_who_owns :: (memory: *void, allocators: .. Allocator) {
+ someone_owns_this := false;
+
+ print("Querying all allocators for address: %\n", memory);
+
+ for allocators {
+ caps, name := get_capabilities(it);
+ assert((caps & .IS_THIS_YOURS) != 0); // It had better be claiming to support this!
+
+ yours := cast(bool) it.proc(.IS_THIS_YOURS, 0, 0, memory, it.data);
+ print("[%] says \"%\"\n", yours, name);
+
+ someone_owns_this ||= yours;
+ }
+
+ assert(someone_owns_this);
+}
+
+
+// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- //
+
+
+checked_add :: (a: $T, b: T) -> result: T, overflow: bool
+#modify {
+ if T.type == .INTEGER return;
+ T = null;
+}
+{
+ overflow: bool;
+ result: T = a + b;
+
+ info := type_info(T);
+ if info.signed {
+ // (+A) + (+B) = −C
+ // (−A) + (−B) = +C
+ if ((a > 0) && (b > 0) && (result < 0)) || ((a < 0) && (b < 0) && (result > 0)) {
+ overflow = true;
+ }
+ } else {
+ if result < a {
+ overflow = true;
+ }
+ }
+
+ return result, overflow;
+}
+
+checked_sub :: (a: $T, b: T) -> result: T, overflow: bool
+#modify {
+ if T.type == .INTEGER return;
+ T = null;
+}
+{
+ overflow: bool;
+ result: T = a - b;
+
+ info := type_info(T);
+ if info.signed {
+ // (+A) − (−B) = −C
+ // (−A) − (+B) = +C
+ if ((a > 0) && (b < 0) && (result < 0)) || ((a < 0) && (b > 0) && (result > 0)) {
+ overflow = true;
+ }
+ } else {
+ if result > a {
+ overflow = true;
+ }
+ }
+
+ return result, overflow;
+}