Aurora Runtime: cross-platform platform-abstraction library - the 100kloc of /base/*.cx nobody wants to write.
Go to file
2021-09-06 15:44:00 +01:00
Include [*] untested possible alternative solution, expose internal buffer size, caller does not manage internal buffer size (yet) 2021-09-06 15:22:17 +01:00
Source [*] Improve win32 stdin preemption on deinit 2021-09-06 15:44:00 +01:00
.gitignore Major patch [1/2] 2021-09-06 11:58:08 +01:00
Aurora.json Major patch [1/2] 2021-09-06 11:58:08 +01:00
LICENSE [+] Added license 2021-06-30 10:28:35 +01:00
readme.txt [*] Rename readme 2021-09-06 12:08:53 +01:00

## IN DEVELOPMENT

## AuroraRuntime

The Aurora Runtime is an extensive platform abstraction layer for cross-platform C++ development
across embedded and PC systems. Simply fetch a binary package for your toolchain or integrate 
our build scripts into your applications build pipeline to get started.

## Features

- Lightweight threading primitives backed by OS specific backends
- Async threading primitives, including WaitMultipleObjects paradigm [WIP]
- Async and regular IO abstraction 
- Optional event driven async programming paradigm
- Console; graphical and standard; binary and UTF-8 logger
- Debug and Telementry; asserts, exception logging, fio, nio backends
- Crypto ECC/[25519, P-384, P-256], [AES, RSA, X509], [common digests]
- IPC [WIP]
- Network
- Random
- Hardware Info
- FIO settings registry
- Compression
- Locale and encoding
- C++ utility templates and macros

## Links

API: 
Doxygen: 
Examples: 
Tests: 
Cmake-stable:
Build Pipeline: 

## Utilities

Aurora Runtime provides macros and some template apis to make writing common C++ idioms and 
tricks easier.

## Logging

Aurora Runtime does not attempt to implement your favourite production logger. We instead
implement a subscription based log message dispatcher with some default backends including
a file logger, Windows debug logging, Windows conhost stdin/out using UTF-8, UNIX stdin/out
respecting the applications codepage, a wxWidgets toolkit GUI, and hopefully more to come. 
Additionally, consoles that provide an input stream can be used in conjunction with the parse
subsystem to provide basic command-based deserialization, tokenization, and dispatch.

## Loop [WIP]

Aurora Runtime offers a main loop that connects multiple input sources into one delegate.  
Timers, semaphores, mutexes, events, X11, FDs, Win32 msg loop, macos, IPC, file aio handles, and
async runner main loop sources will be supported. This equates to a cross-platfom equivalent of
NT's MsgWaitForMultipleObjects in the form of a MainLoop object and a WaitMultiple function.

## Thread Primitives

The Aurora Runtime provides platform optimized threading primitives inheriting from a featureful
IWaitable interface. Each method is guaranteed.

- IWaitable
   ::TryLock()
   ::Lock(timeout)
   ::Lock()
   ::Unlock() 

- arbitrary IWaitable condition variable
- condition mutex : IWaitable
- condition variable : IWaitable
- critical section : IWaitable (aka reentrant mutex)
- event : IWaitable
- mutex : IWaitable
- semaphore : IWaitable
- rwlock (aka shared mutex)
   IWaitable ::GetRead(),
   IWaitable ::GetWrite() 
- spinlocks

We acknowledge and wish to solve the two problems cross-platform developers frequently face.

Problem one:
    Most STL implementations have generally awful to unnecessarily inefficient abstraction. 
    Defer to libc++'s abuse of spin while (cond) yield loops and msvc/stl's painfully slow
    std::mutex and semaphore primitives. 

Problem Two:
    Moving to or from linux, macos, bsd, and win32 under varous kernels, there is no one 
    standard (even in posix land) for the key thread primitives everybody be using. 

Bonus point NT:
    The userland CriticalSection set of APIs generally suck, lacking timeouts and try lock 

Bonus point UNIX:
    No wait multiple mechanism


If you wish to wait on primitives in an asynchronous application, look into runloop sources

## Strings

Currently using a typedef of `std::string`, the Aurora Runtime is looking to switch over the
string type over to `tiny-utf8`'s string type. **All** strings are assumed to be UTF-8.

## Memory

Assumes using AuSPtr, AuWWPtr = std::xxx or app wide redefinition to an alternative smart ptr
implementation. Macros AU_WEAK_FROM_THIS, AU_SHARED_FROM_THIS provide decltype(this) Au[W/S]Ptrs
when the std::enable_shared_from_this or equivalent is utilized. UnsafeRaiiToShared converts raw
pointers to ownerless shared pointers for use with shared apis. 

## IO

The IO subsystem consists of three interfaces, StreamReaders, StreamWriters, and 
ArbitraryStreamReaders; an FS namespace; a network namespace; and an optional 
async file io namespace.

A note about encoding; stdin, file encoding, text decoders, and other IO resources work with
codepage UTF-8 as the internal encoding scheme. String overloads and dedicated string APIs in
the IO subsystem will always write BOM prefixed UTF-8 and attempt to read a BOM to translate
any other input to UTF-8.

## NIO

The networking stack supports a handful of architectural paradigms
- block on write
- delegate write to end of network frame on write
- read with an all-or-nothing flag and an async flag
- read with an asynchronous stream callback
- peaking
- async read/write pump whenever or all 

## FIO

We suspect most developers delegate IO to a worker thread, don't wish to deal with an extern 
async model nor want excessively buffered streams, therefore the FIO API implements a read/write
seekable C-like interface in a file stream object. An alternative AFIO namespace exists for the
few platforms that provide posix AIO, win32 overlap, or linux's io syscalls.

File stream, buffered read/write utilities, stat, exists, copy, move, remove, and itr backed
by the best platform specific blocking apis.
Guaranteed 64-bit file pointer safety across seek functions.
[Open]Write to a file under a path of missing directories guarantees creation of missing sub
directorieis.

### Paths

We assume all paths are messy. Incorrect splitters, double splitters, relative paths, and
keywords are resolved internally. No such URL or path builder, data structure to hold a 
tokenized representation, or similar concept exists in the codebase. All string 'paths' are
simply expanded, similar to 'fullpath', at time of usage. 

Path tokens include:
[0] == '.' = cwd
[0] == '~' = platform specific user directory / brand / Profile
[0] == '!' = platform specific app config directory / brand / System
[0] == '?' = ., !, or ~
.. = go back
/ = splitter
\ = splitter 

## Aurora Async

The Aurora Runtime offers an optional asynchronous task driven model under the Aurora::Async 
namespace. Featuring promises, thread group pooling, functional-to-task wrapping, and 
task-completion callback-task-dispatch idioms built around 3 concepts.  
  
Jobs are callee provided interfaces providing ::onSuccess/onFailure(const in, const out)  
Tasks are an internally-provided interface providing optional<out> onFrame(const in)  
WorkItems adapt a job and a task into one concept. They take a minimum sched delay, promises,
initial delay, and other requirements; to provide a Dispatch routine capable of handling
promises and other abstract developer requirements  

We will not define a standard way to use these concepts.  
For instance, there is no guidance on whether or not you should use public task state structs
and request a Task pointer from a public API or you should accept Job and return a WorkItem;
when or where you should dispatch; whether or not to use C or Functional interfaces.

## Proccesses

The Aurora Runtime provides worker process monitoring, worker Stdin/out stream redirection,
process spawning, file opening, and url opening functionality.

## Locale

Encoding and decoding UTF-8, UTF-16, UTF-32, GBK, GB-2312, and SJIS support using platform
specific APIs. Fetch system language and country backed by environment variables, platform
specific apis, the unix locale env variable, and/or the provided overload mechanism.

## Philosophies

- Assume C++17 language support in the language driver

- To avoid reinventing the wheel, solve the large issues nobody is tackling

- Use AuXXX type bindings for std types, allow customers to overload the std namespace

- Dependencies should be added conservatively when appropriate

- Dependencies should be cross-platform friendly
  It is recommended to fork and replace any legacy OS specific code with equivalent
  AuroraRuntime concepts

- Dependencies, excluding core reference algorithms (eg compression), must be rewritten
   and phased out over time.

- Dependencies should not be added if most platforms provide some degree of native support
  Examples: -> Don't depend on a pthread shim for windows; implement the best thread 
               primitives that lie on the best possible api for them 
               Don't depend on ICU when POSIX's iconv and Win32's multibyte apis cover
               everything a conservative developer cares about; chinese, utf-16, utf-8,
               utf-32 conversion, on top of all the ancient windows codepages

- Dependencies should only be added when it saves development time and adds production
  hardening
  Examples: -> Use embedded crypto libraries; libtomcrypt, libtommath
                -> While there are some bugs in libtomcrypt and others, none appear to 
                   cryptographically cripple the library. Could you do better?
            -> Use portable libraries like mbedtls, O(1) heap, mimalloc
                -> Writing a [D]TLS/allocator stack would take too much time
                -> Linking against external allocators, small cross-platform utilities, and 
                   so on is probably fine 
            -> Feel free to shim libcurl instead of inventing yet another http stack