DevLaukey / fiber_scheduling_cpp

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

TASK1 : Fiber Switching in C++ with Context Library

This project demonstrates the implementation of fiber switching in C++ using a provided context library. Fibers are lightweight threads with their own stack, and this example shows how to switch between different fibers.

Table of Contents

Introduction

In this project, we implement a simple program that utilizes the provided context library to switch between different fibers. The context library consists of functions to save and restore the execution state, allowing for the creation of lightweight fibers.

Building

  1. Assemble Assembly Code: This command assembles the context.s assembly file into machine code and saves the result in context.o.

  2. Compile C++ Source Code to Object File: This command compiles the fibers.cpp source file into machine code and saves the result in fibers.o.

  3. Link Object Files to Create Executable: This command links the previously compiled fibers.o and context.o object files into an executable named fibers.

as -o context.o context.s
g++ -c fibers.cpp -o fibers.o
g++ fibers.o context.o -o fibers

Running

Run the compiled executable:

./fibers

Examples

  1. Header Inclusions:

    • #include <iostream>: Allows the program to perform input and output operations.
    • #include <cstdint>: Provides fixed-width integer types (uint32_t, uintptr_t, etc.).
    • #include "context.hpp": Includes the header file for the provided context-switching library.
  2. Global Variables:

    • volatile bool x = false;: A volatile boolean variable used to control the flow of execution. Its volatility ensures that the compiler does not optimize its usage.
  3. Global Contexts:

    • Context main_context; and Context goo_context;: Two instances of the Context structure provided by the context library. These represent the execution contexts for the main function and the goo function.
  4. Function Declarations:

    • void goo();: Forward declaration for the goo function.
  5. Function Definitions:

    • void foo(): Outputs a message and then switches control to the goo function using the context-switching library.
    • void goo(): Outputs a message.
  6. Main Function:

    • Allocates memory for the main stack, including additional space for the Red Zone, following the System V ABI.
    • Aligns the main stack to 16 bytes and adjusts the stack pointer for the Red Zone.
    • Retrieves the current context as the main context, sets up the foo function as the entry point, and sets the stack pointer.
    • Calls the context-switching library function set_context to switch control to the foo function.
    • After foo completes, control returns to the main function, and the program checks the condition of the volatile variable x. If true, it outputs a message.
    • Deallocates the main stack memory.

Code Snippets

context.hpp

#include <cstdint>

struct Context {
    void* rip, *rsp;
    void* rbx, *rbp, *r12, *r13, *r14, *r15;
};

extern "C" int get_context(Context* c);
extern "C" void set_context(Context* c);
extern "C" void swap_context(Context* out, Context* in);

Output

Task 1

Task 1 output

TASK2: Fiber Class

The Fiber class is a simple C++ implementation that provides a basic framework for creating and managing fibers. Fibers are lightweight threads of execution that can be cooperatively scheduled.

Contents

Features

  • Fiber Creation: Create fibers with a specified function to execute.
  • Context Switching: Swap the execution context between different fibers.
  • Stack Management: Allocate and deallocate stack space for each fiber.

Usage

To use the Fiber class, follow these steps:

  1. Include the "Fiber.hpp" header file in your project.
  2. Create a Fiber object with the desired function.
  3. Use the provided functions to get, set, and swap the context of fibers.
  4. Start the execution of fibers to switch between them.
#include "Fiber.hpp"
#include <iostream>

int main() {
    // Example usage of the Fiber class
    Fiber fooFiber(&fooFunction);
    Fiber barFiber(&barFunction);

    const Context &fooContext = fooFiber.get_context();
    fooFiber.set_context(barFiber.get_context());

    // Start the execution of fibers to switch between them
    fooFiber.start_execution(barFiber);

    return 0;
}

Implementation

The Fiber class is implemented with the following key functions:

  • Fiber::Fiber(): Default constructor for initializing the fiber.
  • Fiber::Fiber(void (*function)()): Constructor for creating a fiber with a specified function.
  • Fiber::~Fiber(): Destructor for cleaning up resources, such as deallocating the stack.
  • Fiber::get_context(): Retrieve the context of the fiber.
  • Fiber::set_context(const Context &newContext): Set the context of the fiber.
  • Fiber::swap_context(Fiber &other): Swap the context between two fibers.
  • Fiber::start_execution(Fiber &other): Start the execution of the specified

Scheduler Class

The Scheduler class is a basic fiber scheduler implementation in C++. It allows the management and execution of multiple fibers in a cooperative multitasking fashion.

Class Members

  • fibers_: A deque (double-ended queue) that holds pointers to Fiber instances. Fibers are added to this deque for scheduling.

  • context_: An instance of the Context structure representing the saved context when switching between fibers.

  • sharedData: A pointer to an integer used as shared data. Fibers can access and modify this shared data.

Public Methods

  • Scheduler(): Default constructor for the scheduler.

  • ~Scheduler(): Destructor responsible for cleaning up allocated memory for fibers.

  • spawn(Fiber *f): Adds a new fiber (Fiber instance) to the scheduler for future execution.

  • do_it(): Initiates the scheduler's execution loop. It sequentially runs fibers in a round-robin fashion until no fibers are left in the deque.

  • fiber_exit(): Signals the end of the current fiber's execution, allowing the scheduler to resume control.

  • get_shared_data() const: Retrieves a pointer to the shared data, which can be accessed by fibers.

Simple Fiber Scheduler Example

This is a basic example demonstrating the usage of a simple fiber scheduler in C++.

Overview

The program creates a scheduler (Scheduler class) that manages multiple fibers (Fiber class). Each fiber is associated with a specific function (func1, func2, func3) to be executed.

How to Run

Ensure you have a C++ compiler installed on your system. You can compile and run the program using the following commands:

g++ -std=c++11 main.cpp context.cpp Fiber.cpp Scheduler.cpp -o scheduler_example
./scheduler_example

TASK 3 Fiber and Scheduler System

This code implements a simple fiber and scheduler system in C++. Fibers are lightweight threads of execution that can be scheduled by a central scheduler. The scheduler controls the execution of fibers, allowing them to yield and resume their execution.

Fiber Class

Constructors

  • Fiber(): Default constructor, initializes the fiber with null values.
  • Fiber(std::function<void()> function): Constructor that takes a function to execute as an argument.

Methods

  • const Context &get_context() const: Get the current context of the fiber.
  • void set_context(const Context &newContext): Set the context of the fiber.
  • void swap_context(Fiber &other): Swap the context between two fibers.
  • void start_execution(Fiber &other): Start the execution of a fiber.
  • Context &get_context(): Get a non-const reference to the fiber's context.
  • int *get_data_pointer() const: Get the shared data pointer.
  • void yield(): Yield control to the scheduler.

Destructor

  • ~Fiber(): Destructor, responsible for deallocating the fiber's stack.

Scheduler Class

Constructors

  • Scheduler(): Default constructor.

Methods

  • void spawn(Fiber *f): Add a fiber to the scheduler's queue.
  • void do_it(): Execute fibers in the scheduler's queue.
  • void fiber_exit(): Exit the current fiber.
  • int *get_shared_data() const: Get the shared data pointer.

Destructor

  • ~Scheduler(): Destructor, responsible for cleaning up allocated resources.

Example Usage

#include "Fiber.hpp"
#include "Scheduler.hpp"

void func1()
{
    std::cout << "fiber 1" << std::endl;
}

void func2()
{
    std::cout << "fiber 2" << std::endl;
}

int main()
{
    Scheduler s;

    // Creating fibers
    Fiber f1(func1);
    Fiber f2(func2);

    // Spawning fibers
    s.spawn(&f1);
    s.spawn(&f2);

    // Running the scheduler
    s.do_it();

    return 0;
}

About


Languages

Language:C++ 97.5%Language:Assembly 2.5%