# Dusk Examples This is a collection of examples of [Dusk][dusk] packages, that is, applications written in Dusk's Forth and wrapped through Dusk's Usermode to provide a portable executable that is small and fast. This code is available from [Dusk OS' files folder][files] or as a Git repository ([without SSL][ssl]) at: git://git.duskos.org/dusk-examples.git [dusk]: http://duskos.org [ssl]: http://duskos.org/ssl.html [files]: http://duskos.org/files/ ## Requirements Dusk's Usermode runs natively on the host machine, but this means that it can only run on CPU architectures supported by Dusk. See [Usermode README][usermode] for details. To build this project, you need: * A C compiler * Make (BSD or GNU) * A way to fetch a file from http: either `curl`, `wget`, or BSD's `ftp`. [usermode]: http://duskos.org/usermode.html ## Build Run `make` in this project's root directory. This will compile all examples. These executables are standalone. ### Frozen! All examples support freezing. Because it's not all host OSes that can build them, they're not built by default. To freeze an example, use the `_frozen` target. For example, `make hello_frozen` will yield a frozen `hello` example. ## Examples description ### hello Invoking `./hello` will print "Hello World!" and exit. Invoking it with a single argument will greet that name instead. Other arguments are ignored. ### sievec This is a "Byte Sieve" benchmark as shown on the [website's main page][dusk] and compiled with [Dusk CC][cc]. You run it with `./sievec` without arguments. On most system, you can time it with a command that looks like `time ./sievec`. This is a good example of a more complex package because it uses a filesystem to load DuskCC. It embeds a tar of Dusk's files in the executable itself and uses this as a filesystem. It's also a good example of an API extension: access to the tar data is done through an extra API function. On top of that, it's a good example how we can be "smart" about freezing: if you look at `sievec.c`, you'll see that we've carefully `#ifdef`-ed out the tar embedding from the frozen executable because once frozen, we don't need filesystem access anymore. [cc]: http://duskos.org/doc/comp/c/index.txt ### sieve This is a "Byte Sieve" benchmark as shown on the [website's main page][dusk]. You run it with `./sieve` without arguments. On most system, you can time it with a command that looks like `time ./sieve`. This timing will include "warm up" time, that is, the time Dusk needs to compile itself up, then compile the `sieve` word. ### sieveh Same as `sieve`, but with the HAL-optimized version of the algorithm. ### charcount This is a showcase of how the efficiency of the HAL isn't just about compiling C code, but how this efficiency oozes everywhere in the code, *with compound effect*. That makes Dusk really, really efficient. This is a comparison of Dusk's "rfind" method, which leverages the HAL to compile a super efficient loop against POSIX's `regex(3)`. The idea is simple: read stdin and count the number of characters between `a` and `d`. There is of course the Dusk version in `charcount.fs`, but also a reference `regex(3)` version in `charcountref.c`, which you can build with `make charcountref`. Then, you can do something like `time ./charcount < /usr/share/dict/words` to try it out. On my 10 years old NetBSD 10.0 machine, guess what? The Dusk version is 30 times, **30 times** faster than `regex(3)`. On a debian bookworm amd64 modern machine, the gains are more modest (Dusk is 15% faster), but it still manages to beat glibc and its millions upon millions of lines of code.