Skip to content

cammeresi/linker-set

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

INTRO

A linker set allows you to program declaratively rather than imperatively
by embedding configuration or behavior into a program as data.

Using a linker set, you can scatter instances of a certain type all over
your program, and, with the proper annotations, the linker will gather
them up into a special section of the ELF binary, forming an array,
which can be iterated at runtime.

See the tests in src/lib.rs for usage, but general idea is:

        use linker_set::*;

        set_declare!(name, type);

        #[set_entry(name)]
        static VAR: type = ...;

        for i in set!(name) ...

The set_declare!() macro outputs a module definition.  The module
must be imported into the scope of calls to the set_entry attribute
and the set!() macro.

If you make a linker set of an integer type, you should use typed
literals, not generic integer literals.  I.e.

        static FOO: u64 = 1000u64; // not 1000

Generic integer literals will defeat a typechecking mechanism that is
output by the set_entry macro.

All items in a set should be of the same size, the size of the declared
type.  Otherwise, stuff won't work.  The macros make an attempt to
typecheck set entries, but they aren't foolproof.  Caveat scriptor.

The index operator is kind of just for fun.  Obviously you shouldn't
depend on the linker to provide any specific ordering.

HISTORY

This idea comes from Clustrix, the best distributed relational database
in the world, which no one knew about.  Clustrix was written in a very
unusual but very interesting style of C.  Much of it was written in
continuation passing style, and continuations and lightweight threads
(fibers) ran on top of a scheduler very similar to the asynchronous
runtimes like Tokio which later became popular.  (But Clustrix was
started in 2006, before that popularity.)

Linker sets were used extensively in the Clustrix code to do things
such as specify initialization or other system processes via graphs
(initgraphs), automatically create heaps for memory allocation,
automatically allocate integers or flags for what would otherwise have to
be centrally controlled constants, and automatically register structures
or handlers with a subsystem.

This concept was present in the oldest version of the Clustrix code
in Git.  A prior Subversion repository seemed to have been lost.
The inspiration appears to have come from FreeBSD, which has several
macros whose names match exactly macros used in the Clustrix source code.

https://en.wikipedia.org/wiki/Clustrix
https://github.com/freebsd/freebsd-src/blob/main/sys/sys/linker_set.h

SEE ALSO

The crate "linkme" does a similar thing, calling the concept "distributed
slices."


Sidney Cammeresi
[email protected]

About

Declarative programming via linker-constructed arrays

Resources

License

Stars

Watchers

Forks

Languages