Garbage collectors in C
Go to file
Peter McGoron f440716bf9 uns_lisp: swap 2024-07-16 14:46:27 -04:00
examples uns_lisp: swap 2024-07-16 14:46:27 -04:00
include Major API reorganization, test infrastructure 2024-07-08 19:58:22 -04:00
.gitignore Major API reorganization, test infrastructure 2024-07-08 19:58:22 -04:00
COPYING cheney copying collector 2024-06-11 23:40:34 -04:00
Makefile fine-grained valgrind support (warning: slow) 2024-07-14 01:43:56 -04:00
README.rst import flatrate lisp, rename to Universal Service LISP 2024-07-10 10:47:55 -04:00
cheney_c89.c fine-grained valgrind support (warning: slow) 2024-07-14 01:43:56 -04:00
gen_tests.sh cheney_c89: valgrind 2024-07-14 01:20:50 -04:00
uns.c Major API reorganization, test infrastructure 2024-07-08 19:58:22 -04:00

README.rst

=================
Universal Service
=================

Universal Service is a collection of garbage collectors written in C,
designed to allow flexibility in programs that use it. All collectors
are accessed using a common API so code written for one collector can be
used with other collectors with the same feature set without modification.

-----------
Terminology
-----------

Generally speaking, ``UNS_WORD`` must be an integer that can be converted
to and from a pointer to data (such as ``uintptr_t``). ``UNS_SWORD`` is the
signed version of ``UNS_WORD``. Both must be integer types.

In collectors where this conversion cannot be assumed (like C89 collectors)
or is not possible, then ``UNS_WORD`` should be a type that can be used to
index any arrays (like ``size_t``).

A "region" denotes a block of memory in the heap. The "header" of a
region is a hidden area of the region that holds information about
the region.  It may not be connected to the actual region itself. A
"pointer to a region" is a pointer to the first byte of user accessable
space: it is not a pointer to the header.

----------
Collectors
----------

* ``cheney_c89``: A pure C89 copying collector. Useful for applications
  that want a resizable heap.
* (Planned) ``inplace_c89``: A pure C89 mark-lazy-sweep collector with
  support for weak references.

-----------------
Adding Collectors
-----------------

The minimum set of functions a collector must define are

* ``init``: Initialize ``Uns_GC`` with the heap and callbacks specific to
  that collector.
* ``collect``: Force a garbage collection.
* ``alloc``: Allocate memory. All allocators must support at least
  ``UNS_BYTES`` and ``UNS_RECORD``. All other type combinations are
  optional. ``UNS_RECORD`` may be equivalent to a type combination
  containing ``UNS_RECORD``.
* ``deinit``: Free heap.
* ``record_set``: Set an entry in a record to the passed value.
  This function is not allowed to cause a garbage collection.
* ``record_get``: Get the value of an entry.
  This function is not allowed to cause a garbage collection.

-------
License
-------

Universal Service is licensed under the LGPL-3.0-or-later.

Contrary to popular belief, **static linking LGPL code does not force
your code to be LGPL.** The LGPL requires you to allow the user to swap
out the LGPL code for anything that fits the interface, and for you to
redistribute modifications to the LGPL code. From the
`GNU Project FAQ <https://www.gnu.org/licenses/gpl-faq.html#LGPLStaticVsDynamic>`_:

> Does the LGPL have different requirements for statically vs dynamically
> linked modules with a covered work?
>
> For the purpose of complying with the LGPL (any extant version: v2,
> v2.1 or v3):
>
> If you statically link against an LGPLed library, you must also
> provide your application in an object (not necessarily source) format,
> so that a user has the opportunity to modify the library and relink
> the application.

You can statically link any LGPL 3.0 code to code of permissive licenses
(like MIT), and even to source-available licenses (like the SSPL or the
Commons Clause) as long as the end user can recompile the program to use
their own version of the library.

----
Todo
----

* call before gc and after gc
* Address sanitizer, ub sanitizer if available