Jump to content
  • Advertisement
Sign in to follow this  
  • entries
    24
  • comments
    21
  • views
    17675

T t HR h E readi ADI n N g G

Sign in to follow this  
Enigma

247 views

Continuing my language-shootout mission I spent what little free time I had this week looking at the issue of threading. This seems to be one area where C++ falls badly behind other languages currently in the shootout. As I understand it this is partly because the standard threading implementation for C++ under *nix, pthreads, uses kernel-space threads, as opposed to user-space threads. Kernel-space threads are also known as "heavyweight" threads, as opposed to "lightweight" user-space threads and the cost of a context switch is much higher.

In an effort to produce a much more efficient C++ concurrency implementation I investigated a couple of alternative threading libraries. Eventually however the fact that for shootout development I'm running Gentoo from a LiveCD with a RamDrive (I don't trust it sufficiently to allow it to write to my NTFS partition) and the added complexity this adds to downloading and installing a threading library together with a growing interest in the subject led me to decide to try and write my own extremely minimal threading library.

I decided to aim as low as possible and therefore targeted a non pre-emptive user-space system on x86 with a de-facto standard C++ stack. Non pre-emptive threads simply mean that instead of each thread running for a certain period of time and then being pre-empted in favour of another thread instead each thread runs until it decides to give up the processor. This has obvious advantages in terms of reduced synchronisation and scheduling burdens and obvious disadvantages in terms of threads potentially never giving up the processor. Also, as I understand it, a purely user-space thread library cannot take advantage of multiple processors, kernel-space threads are required for this, although multiple user-space threads can be multiplexed onto multiple kernel-space threads.

After a bit of reading around interprocessor interrupts, x86 segments and global and local descriptor tables amongst others I eventually managed to implement a very simple system which currently works under a basic test program on two compilers under windows, with or without optimisations:
#include 
#include "test_threads.h"

void thread_function(int i)
{
std::cout << "thread " << i << '\n';
yield();
std::cout << "thread " << i << '\n';
}

int main()
{
thread_t * thread1 = create_thread(thread_function, 1);
thread_t * thread2 = create_thread(thread_function, 2);
while (thread1->running && thread2->running)
{
std::cout << "main thread\n";
yield();
}
std::cout << "main thread\n";
}
output:
main thread
thread 1
thread 2
main thread
thread 1
thread 2
main thread
I'm now working on porting the system to gcc, which is the target compiler for the language shootout. Unfortunately gcc introduces extra complications with it's alternative assembler syntax and lack of __declspec(naked) directive.

If people are sufficiently interested I may try to write up my experiences if and when I manage to develop a working language-shootout program with my own threading library. I'm sure I'm not doing things the best way possible, but it's an interesting journey and I've learnt a lot already.

?nigma
Sign in to follow this  


0 Comments


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!