Cogs
Cogs Documentation

Work In Progress

This documentation is work in progress. Few classes (etc.) are yet completely documented, but I've added at least brief descriptions for most. Check the 'Modules' section for classes organized into groups. I'd like to do more clean up before I post to GitHub, but source code is viewable where linked.

Introduction

Cogs is a highly-parallel, lock-free, cross-platform, C++ template class library and application framework.

Getting Started

(TODO)

Directory Structure and Include Search Paths

Cogs source code is organized into 4 main areas: Core, Architecture, Environment, OS. Some cross-architecture (x86, AMD64, etc.), cross-environment (Visual Studio, XCode), and cross-OS (Windows, MacOS, Linux) support is accomplished by providing alternate versions of headers and classes. A project must add the appropriate arch, env and OS include paths for the desired platform. i.e. To target AMD64, MS Windows, using Visual Studio, a project would add the following include paths:

Concepts

Volatile Correctness

Most C++ programmers should be aware of the concept of const correctness. In C++, the 'const' qualifier can be added to a type, preventing non-const access to that data at compile time. Using this language feature tends to have a cascading effect, and "correctness" refers to using const for read-only references consistently throughout the code-base.

The const qualifier can also be added to member functions, causing a member function to treat it's 'this' pointer as a pointer to a const type. Methods of the same name can be overloaded with and without the const qualifier, to indicate one version of the function is to be used when called on a non-const reference, and the other is to be used when called on a const reference.

The const and volatile keywords are syntactically equivalent (defined together in C++ specs as "cv-qualifiers"). The same language features that apply to distinguishing between const and non-const types, can be used to distinguish between volatile and non-volatile types. Cogs leverages this to provide thread safe (volatile) and more efficient thread-unsafe (non-volatile) implementations of an algorithm using a single a class.

class A
{
private:
ptr<void> m_ptr;
public:
// Sees: ptr<void> m_ptr;
void foo(); // #1
// Sees: const ptr<void> m_ptr;
void foo() const; // #2
// Sees: volatile ptr<void> m_ptr;
void foo() volatile; // #3
// Sees: const volatile ptr<void> m_ptr;
void foo() const volatile; // #4
};
...
void bar(A& a1, const A& a2, volatile A& a3, const volatile A& a4)
{
a1.foo(); // Calls #1
a2.foo(); // Calls #2
a3.foo(); // Calls #3
a4.foo(); // Calls #4
}

Atomics

Underlying Cogs' lock-free algorithms is a set of atomic functionality. See: cogs::atomic

Memory Allocation

Cogs supports allocator classes. A cogs::allocator may be static or instance-based. The default allocator (cogs::buddy_block_allocator) is lock-free.

Lock-Free RAII Reference-Counted Objects

Cogs heavily leverages lock-free RAII reference-counted reference containers (i.e. smart pointers). These reference objects are copied by value, and the object referred to is disposed when its last reference goes out of scope.

volatile rcptr<A> a1 = rcnew(A)(constructorArgs);
// in another thread:
rcptr<A> a2 = a1;
// Encapsulated object is destructed and deallocated automatically once both a1 and a2 have gone out of scope.

Classes intended to be allocated using rcnew can derive from cogs::object to access their own reference-counted container using this_rcptr or this_rcref.

A cogs::rcref is similar to a cogs::rcptr, but cannot refer to null. cogs::rcptr and cogs::rcref are both considered "strong" references. (See cogs::reference_strength_type) A cogs::weak_rcptr can be used to retain a conditional reference to an object, which automatically becomes NULL when there are no longer any strong references. cogs::weak_rcptr assists in preventing circular dependencies. Generally, a cogs::weak_rcptr should be used for any reference that is not specifically intended to extend the scope of it the object.

Lock-Free Algorithms

Noteworthy lock-free algorithms include:

cogs::hazard (Hazard pointers) - Based loosely on a paper by Maged M. Michael

cogs::container_deque - A container (non-intrusive) deque/queue/stack. Allows coalescing of equal nodes. Based loosely on a paper by Maged M. Michael

cogs::container_dlist - A container (non-intrusive) double-link list. Supports lock-free traversal.

container_skiplist - A sorted container (non-intrusive) with O(log n) insert and search. Efficient insert at start/end. Based loosely on a paper by Sundell and Tsigas. This is used to provide lock-free implementations of standard associative containers such as cogs::set, cogs::multiset, cogs::map, and cogs::multimap, as well as cogs::priority_dispatcher.

cogs::transactable - A transactional type wrapper. Encapsulates a type and provides access to it using simple atomic read/write transactions.

cogs::freelist - A simple lock-free free-list.

cogs::buddy_block_allocator - An allocator that uses a set of cascading free-lists. If a blocks of a required size is not available, a block twice the size is allocated, split in half, and the other half is added to the smaller block's free-list. When a block is free, and it's associated (buddy) block is also freed, it's coalesced and released to the free-list for the larger block.

Synchronization Objects

As a cross-platform framework, Cogs abstracts the thread synchronization of the target platform. As a lock-free framework, use of blocking synchronization is discouraged. Most cogs synchronization objects provide a way to be notified of resource availability using a callback delegate, which allows traditional thread synchronization objects to also be used in a lock-free manner.

Cogs synchronization objects avoid locks internally, and leverage only a simple OS-specific semaphore when blocking is necessary.

Events - Similar to Win32 Events and pthreads condition objects - cogs::event, cogs::auto_reset_event, cogs::count_down_event, cogs::resettable_event, cogs::single_fire_event -

Timers - cogs::timer, cogs::manual_reset_timer, cogs::pulse_timer, cogs::refireable_timer, cogs::single_fire_timer -

cogs::mutex, cogs::semaphore, cogs::rwlock, cogs::priority_queue

cogs::thread, cogs::thread_pool

Delegates and Dispatchers

Although not (yet) a core guiding design principle, Cogs is heavily functional. (See: Functional Programming)

A cogs::delegate_t can opaquely encapsulate any of the following:

cogs::delegate_t does not need to precisely match expected parameters or return types, as long as the types are compatible.

A cogs::dispatcher is an interface for objects that dispatch delegates, such as a cogs::thread_pool.

Asynchronous I/O

Cogs include a robust asynchronous I/O system. The primary I/O classes are cogs::io::datasource and cogs::io::datasink. A cogs::io::datasource and a cogs::io::datasink can be 'coupled', such that data is automatically routed between them, until decoupled or one of them is closed. A cogs::io::filter can be placed between a datasink and a datasource to patch a stream.

Cogs I/O makes use of composite buffers (cogs::io::composite_buffer_t). A composite buffer is a single logical buffer potentially comprised of multiple incontiguous buffers. This is intended to minimize large buffer copies.

Cogs includes highly scalable cross-platform Network I/O.

(File I/O with scatter/gather transactions, is currently TODO).

Math

Cogs includes classes for both fixed and dynamic arbitrary precision integers (cogs::fixed_integer, cogs::dynamic_integer). When necessary, mathematical operations generate results with increasing bits, making range overflows avoidable.

cogs::number is a wrapper type that encapsulates both an underlying representation (such as a cogs::fixed_integer or cogs::dynamic_integer) and a unit base (such as seconds, minutes, meters, liters). Mathematical operations automatically perform the appropriate value and unit base conversions.

Cryptography, Hashes, CRCs and Checksums

Cogs includes a library of hash, CRC, and checksum algorithms.

Cryptographic cipher algorithms are TODO. A goal is to implement the SSL/TLS protocol.

GUI

Cogs includes a cross-platform GUI framework.

Common UI elements are implemented using a bridge pattern that facilitates both UI skinning and cross-platform support. For example, a cogs::gui::button represents a UI button. When the cogs::gui::button (or a pane it's nested within) is installed into a cogs::gui::subsystem, an additional subsystem-specific button object is created and bridged using the existing cogs::gui::button. It's possible to uninstall a UI tree from one cogs::gui::subsystem, and install it into another, for instance to change the (skinned) appearance of the user interface. Platform-specific UI is provided using a platform-specific cogs::gui::subsystem.