Skip to content

A multithreading library for POSIX-compliant Unixes

Notifications You must be signed in to change notification settings

AnupNair08/tlib

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tlib

A multithreading library for Unix-like POSIX compliant systems

Contents

About

tlib is a multithreading library that lets programs control multiple flows of work that run in an interleaved manner and supports user level threads in either a One-One mapping model or a Many-One mapping model. tlib is available for Unix-like POSIX conformant operating systems.

Building

   # Run the root directory of the project
   make
   # To compile the binaries run
   make tlib

   # To compile the test suite
   make alltest
   # To run the tests
   ./run.sh

   # To generate API docs
   make docs

Mapping models

A mapping model refers to the way in which a thread created by the user maps to the kernel level thread. There are three main types of which the two implemented in tlib are :

  1. One-one model

    • One one model will use the clone system call to create a corresponding kernel thread for each user level thread. It is referred to as LWP.
    • LWPs share a same set of resources that are allocated to the process. These include address space, physical memory pages, file systems, open files and signal handlers.
    • Extensive resource sharing is the reason these processes are called light-weight processes.
    • One-one threading model is highly used in OS like Linux and Windows.
  2. Many-one model

    • There is a mapping for many user level threads onto a single kernel thread.
    • The library handles the multiplexing of the threads into a single kernel thread with aspects such as scheduling, managing the context of threads etc.
    • The scheduling and context switching are entirely handled by the library and the kernel sees a single flow of execution.
                       User space                                            User space
          ┌─────────────────────────────────┐                   ┌─────────────────────────────────┐
          │                                 │                   │                                 │
          │                                 │                   │                                 │
          │                                 │                   │     ┌─┐  ┌─┐      ┌─┐ ┌─┐       │
          │                                 │                   │     └┼┘  └┼┘      └┼┘ └┼┘       │
          │                                 │                   │      │    │        │   │        │
          │     ┌─┐  ┌─┐      ┌─┐ ┌─┐       │                   │      │    │      ┌─┘   │        │
          │     └┼┘  └┼┘      └┼┘ └┼┘       │                   │      └───▲▼──────▼─◄───┘        │
          │      │    │        │   │        │                   │          │   map   │            │
          │      │    │        │   │        │                   │          │         │            │
          └──────┼────┼────────┼───┼────────┘                   └──────────┴────┬────┴────────────┘
                 │    │        │   │                                            │
                 │    │        │   │                                            │
          ┌──────┼────┼────────┼───┼────────┐                   ┌───────────────┼─────────────────┐
          │      │    │        │   │        │                   │               │                 │
          │      │    │        │   │        │                   │               │                 │
          │      │    │        │   │        │                   │               │                 │
          │      │    │       ┌┼┐ ┌┼┐       │                   │               │                 │
          │     ┌┼┐  ┌┼┐      └─┘ └─┘       │                   │              ┌┼┐                │
          │     └─┘  └─┘                    │                   │              └─┘                │
          │                                 │                   │                                 │
          │                                 │                   │                                 │
          │                                 │                   │                                 │
          └─────────────────────────────────┘                   └─────────────────────────────────┘
                      Kernel space                                          Kernel space
    
    
                One One Threading model                                Many One Threading model
    
    

Available APIs

  • tlib provides two mapping models and the desired model can be chosen without changing any API calls. The implementation remains abstract to the user programs.

  • Each of the two models provides the following set of API calls:

    1. Thread APIs

      1. Thread Creation

        Function Description
        thread_create() Creates a new thread
        thread_join() Waits for a callee thread to be terminated
        thread_kill() Send a signal to a specific thread
        thread_exit() Exit the thread routine
      2. Thread Attribute handling

        Function Description
        thread_attr_init() Initialize an attribute object
        thread_attr_destroy() Destroy an attribute object
        thread_attr_setStack() Set a user defined stack size
        thread_attr_getStack() Get the size of the current thread stack
        thread_attr_setGuard() Set a user defined guard page size
        thread_attr_getGuard() Get the size of the current thread stack guard page
    2. Synchronization Primitves APIs

      1. Spin Lock

        Function Description
        spin_init() Initialize a spinlock object
        spin_acquire() Acquire a spinlock
        spin_release() Release a spinlock
        spin_trylock() Check if a spinlock can be acquired
      2. Mutex Lock

        Function Description
        mutex_init() Initialize a mutex object
        mutex_acquire() Acquire a mutex
        mutex_release() Release a mutex
        mutex_trylock() Check if a mutex can be acquired

Usage

To use tlib in your programs, do the following:

// Use one of the macros to use the desired mapping
#define ONE_ONE
// #define MANY_ONE
#include <stdio.h>

#ifdef ONE_ONE
   #include "src/OneOne/thread.h"
#else
   #include "src/ManyOne/thread.h"
#endif

int global_var = 0;
void func1(){
   printf("In thread routine 1");
   global_var++;
   return;
}

void func2(){
   printf("In thread routine 2");
   global_var++;
   return;
}

int main(){
   thread t1,t2;
   thread_create(&t1, NULL, func1, NULL);
   thread_create(&t2, NULL, func2, NULL);
   thread_join(t1,NULL);
   thread_join(t2,NULL);
   return 0;
}

Running Tests

The library comes with an extensive test suite for checking the implementation and testing the performance of the library. Each implementation has a set of unit tests that check the correctness of the APIs. There is a test for checking the synchronization primitves and a classic program of readers writers to check the working of synchronization primitives namely mutex and spinlock. The test suite also includes a robust testing program that checks for the error handling and incorrect input cases. Finally there is a benchmark program which is a matrix multiplication program in the single and multi-threaded environments to compare the performance of using a threading library.

To run the tests:

#Run the following in the root directory of the project

# Compile and auto run
make run

# Compile all binaries
make alltest
# Start the test suite
./run.sh


# Check for memory leaks
make check-leak

The shell script will test all the functionalities mentioned in the test suite above. In addition, the memory leak checker uses valgrind to look at potential memory leaks in the test code.

References