Skip to content

Instantly share code, notes, and snippets.

View jdryg's full-sized avatar

Jim Drygiannakis jdryg

View GitHub Profile

API Design: Builder APIs (October-2020)

Some time has past (three years!) since I last wrote about API specifically about coroutines style APIs so I thought why not write another one about a different API type I encounter relatively often. The builder API.

Now first let me take a step back and put this into 20,000 feet view on where builder APIs are located in the grant scheme. In general everything in computing is separated into input, processing and finally output. In its most basic form I am currently typing on my keyboard. All pressed keys are processed from the OS up to the browser I am writing this in and finally rendered and displayed on the screen as output. Of course this example is very user centric

// https://github.com/memononen/nanosvg
#include <nanosvg.h>
struct CLSVG {
vg::CommandListHandle handle = { VG_INVALID_HANDLE };
float width = 0.0f;
float height = 0.0f;
};
static uint32_t modulate_color_alpha(uint32_t color, float alpha) {
#include "FunctionalPropertyModifiers.h"
void fpmCallStore::CallAll(double time)
{
for (auto i : m_FunctionCallMap)
{
const fpmFunctionCalls& calls = i->value;
calls.call_all_fn(i->key, calls, time);

I was told by @mmozeiko that Address Sanitizer (ASAN) works on Windows now. I'd tried it a few years ago with no luck, so this was exciting news to hear.

It was a pretty smooth experience, but with a few gotchas I wanted to document.

First, download and run the LLVM installer for Windows: https://llvm.org/builds/

Then download and install the VS extension if you're a Visual Studio 2017 user like I am.

It's now very easy to use Clang to build your existing MSVC projects since there's a cl compatible frontend:

@vurtun
vurtun / _readme_quarks.md
Last active December 9, 2023 12:03
Quarks: Graphical user interface

gui

@twoscomplement
twoscomplement / TransientFunction.h
Last active August 19, 2023 08:32
TransientFunction: A light-weight alternative to std::function [C++11]
// TransientFuction: A light-weight alternative to std::function [C++11]
// Pass any callback - including capturing lambdas - cheaply and quickly as a
// function argument
//
// Based on:
// https://deplinenoise.wordpress.com/2014/02/23/using-c11-capturing-lambdas-w-vanilla-c-api-functions/
//
// - No instantiation of called function at each call site
// - Simple to use - use TransientFunction<> as the function argument
// - Low cost: cheap setup, one indirect function call to invoke
@vurtun
vurtun / defl.c
Last active June 13, 2023 21:30
Full deflate/inflate implementation in ~300 LoC
/* ===============================================================
* SDEFL
* ===============================================================
* public domain - no warranty implied; use at your own risk
* References:
https://bitbucket.org/rmitton/tigr/src/be3832bee7fb2f274fe5823e38f8ec7fa94e0ce9/src/tigr_inflate.c?at=default&fileviewer=file-view-default
https://github.com/github/putty/blob/49fb598b0e78d09d6a2a42679ee0649df482090e/sshzlib.c
https://www.ietf.org/rfc/rfc1951.txt
*/
#include <stdlib.h>
// Single process, registered outputs.
// Version 1 uses a blocking assignment to a flip-flop in a clocked block. This goes against almost all
// best-practices guidelines, even among single-process folks, but it's interesting that it directly expresses
// the intention of the design. Not an endorsement, mind you, but I'm definitely finding that with single-process
// registered-output designs, this kind of thing is tempting...
module srl_fifo#(
parameter DATA_WIDTH = 32,
parameter DEPTH = 16
// This was mostly done as a fun experiment to see how much I could minimize LUT count and combinational delays.
// Vivado synthesizes this to 17-18 LUTs for the default parameters (32-bit addresses, 8 KB cache, 32-byte cachelines).
// About half those LUTs are for the tag comparator. Note that the LUT count is carefully designed to be independent
// of the cacheline width by avoiding any output muxes (e.g. rather than forwarding the fill response, which would
// create an output mux between the fill response and the cache array, it just repeats the cache lookup). The downside
// of this general kind of design is that it takes 3 cycles to report a hit. You could easily do a design with combinational
// outputs that produces a result in 1 cycle, albeit with very restrictive setup times and combinational output delays.
//
// See if you can reduce the LUT count further! (Yes, it's silly, since the cacheline-to-word shifter is going to dominate.)
enum {
PAGE_SIZE = 4096,
MINIMUM_RANGE_SIZE = 1024 * PAGE_SIZE
};
void *AllocateRange(uint32_t *size) {
*size = (*size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
if (*size < MINIMUM_RANGE_SIZE) {
*size = MINIMUM_RANGE_SIZE;
}