← back to home

Owl

20232 viewsView on GitHub
CSystemsLibraryConcurrency

A general-purpose C library featuring collections, threading utilities, and system tools

A lightweight, general-purpose C library providing essential data structures and system utilities. Originally built to power Kraken, a multi-threaded HTTP server, but designed to be used independently in any C project.

What's Inside

Collections

Singly Linked List - A type-safe linked list implementation with insertion and removal operations. Useful for dynamic data storage and efficient sequential access patterns.

Queue - A bounded FIFO queue with configurable capacity, perfect for producer-consumer patterns like HTTP request queuing and job scheduling.

Hashmap - An open-addressing hashmap using Robin Hood hashing for better cache locality and reduced clustering. Supports custom hash functions (SipHash-2-4 and MurmurHash3 included) and custom comparators. Perfect for building caches, routing tables, and fast lookups.

Threading

Thread Pool - A simple but effective thread pool for concurrent task execution. Manages worker threads and a task queue internally. Ideal for handling parallel I/O operations or computational tasks.

Utilities

Panic - Quick error handling macro that prints the error message with file/line information and exits.

Log - Convenience logging macros for formatted output.

Quick Start

Building

Compile to a static library:

make

Or build as a shared library:

make -e SHARED=1

The compiled library will be available in the lib/ directory.

Using Owl

Include the main header in your project:

#include "owl.h"

Example: Thread Pool

#include "owl.h"
 
void *process_request(void *arg) {
    // Your task logic here
    return NULL;
}
 
int main() {
    owl_thread_pool_t *tp = owl_thread_pool_init(4);
 
    owl_worker_task_t task = owl_worker_task_init(process_request, NULL);
    owl_thread_pool_enqueue_task(tp, &task);
 
    owl_thread_pool_free(tp); // Waits for all tasks to complete
}

Example: Hashmap

#include "owl.h"
 
struct user {
    char *name;
    int age;
};
 
uint64_t user_hash(const void *item, uint64_t seed0, uint64_t seed1) {
    const struct user *user = item;
    return owl_hashmap_sip(user->name, strlen(user->name), seed0, seed1);
}
 
int user_compare(const void *a, const void *b, void *udata) {
    return strcmp(((struct user *)a)->name, ((struct user *)b)->name);
}
 
int main() {
    owl_hashmap_t *map = owl_hashmap_new(
        sizeof(struct user), 0, 0, 0,
        user_hash, user_compare, NULL, NULL
    );
 
    owl_hashmap_set(map, &(struct user){.name = "Alice", .age = 30});
    struct user *u = owl_hashmap_get(map, &(struct user){.name = "Alice"});
 
    owl_hashmap_free(map);
}

Design Philosophy

Technical Notes

2kudos