Click here to Skip to main content
Licence 
First Posted 28 May 2003
Views 63,348
Downloads 1,119
Bookmarked 7 times

Unix ucontext_t Operations on Windows Platforms

By | 7 Mar 2007 | Article
An article on the implementation of Unix ucontext_t operations on Microsoft Windows.

Introduction

In this work, we implement the Unix ucontext_t operations on Windows platforms based on the Win32 API GetThreadContext and SetThreadContext functions. It is useful for Unix programmers that need to migrate their user-level threading code directly on Windows instead of using a Unix-to-NT porting environment ([1,2]).

Background

Most modern Unix environments provide to the programmer two options that allow user-level context switching between multiple threads of control within a process: either with the type jmpbuf defined in <setjmp.h> and the setjmp/longjmp pair of functions, or with the type ucontext_t defined in <ucontext.h> and the four functions getcontext, setcontext, makecontext, and swapcontext. For more information on the usage of these functions, you can look at [3]. On Windows platforms, however, the Microsoft C Runtime Library provides only the first set of functions [4].

Using the code

The following program (testcontext.c - included in the demo project) is a typical example that makes use of the ucontex_t operations. It runs successfully on both Unix and Windows platforms. On Windows, the programmer has only to include the two files (ucontext.[c,h]) in his application code. In the demo project, these two files are stored in the unix2nt directory, in order to make straightforward the compilation and execution of the test program on Unix platforms.

/* testcontext.c : demo of ucontex_t operations */
#include <stdio.h>
#include <stdlib.h>
#include <ucontext.h>

ucontext_t auc,buc,mainuc;

void a()
{
    int i;

    for (i = 0; i < 10; i++)
    {
        printf("a");
        swapcontext(&auc, &buc);        /* switch to thread B */
    }

    printf("\nswitching to main\n");
    swapcontext(&auc, &mainuc);         /* switch to main thread */
}

void b()
{
    int i;

    for (i = 0; i < 10; i++)
    {
        printf("b");
        swapcontext(&buc, &auc);        /* switch to thread A */
    }
}

int main(void)
{
    printf("start\n");                  /* main thread starts */

    /* Set up context for thread A (Unix code, see manpages) */
    getcontext(&auc);
    auc.uc_stack.ss_size = 16 * 1024;

    if ((auc.uc_stack.ss_sp = malloc(auc.uc_stack.ss_size)) == NULL)
        perror("malloc"), exit(1);

    auc.uc_stack.ss_flags = 0;
    makecontext(&auc, a, 0);

    /* Set up context for thread B */
    getcontext(&buc);
    buc.uc_stack.ss_size = 16 * 1024;

    if ((buc.uc_stack.ss_sp = malloc(buc.uc_stack.ss_size)) == NULL)
        perror("malloc"), exit(1);

    buc.uc_stack.ss_flags = 0;
    makecontext(&buc, b, 0);

    /* Switch to A */
    getcontext(&mainuc);           /* Save the context of main thread */
    swapcontext(&mainuc, &auc);    /* Switch to thread A */

    printf("\ndone\n");  /* Execution control returned to main thread */
    return 0;
}

If you compile and run the above program (testcontext.dsp), you get the following output:

C:\>testcontext.exe
start
abababababababababab
switching to main

done
C:\>

Implementation

We implemented the above functionality based on the CONTEXT data structure and the GetThreadContext and SetThreadContext functions [2]. In ucontext.h, we defined the appropriate data structures and function prototypes. The implementation of getcontext and setcontext is straightforward, using the corresponding GetThreadContext and SetThreadContext functions. In swapcontext, the current thread saves its context (getcontext) and then restores a new context (setcontext). The trickiest point is in the implementation of makecontext, where we reserve stack space for the function arguments; then we set appropriately the instruction (Eip) and the stack pointer (Esp) fields, and finally, we copy the function arguments in the reserved space. Although the latest specification of makecontext [4] restricts the arguments of the function to be of type int, according to our implementation, the maximum allowed size of an argument is 64 bits, enabling thus the passing of variables of type double. For more implementation details, see the ucontext.c and ucontext.h files.

History

  • May 22, 2003 - Initial release.
  • May 25, 2004 - Revised source code.
  • Mar 6, 2007 - Distributed under the LGPL license.

References

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

xdoukas



Greece Greece

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Questionx86_64 PinmemberL_R_N11:16 9 Apr '12  
GeneralWindows 7 PinmemberMarshallBanana15:49 20 Aug '10  
GeneralRe: Windows 7 Pinmemberxdoukas7:56 8 Oct '10  
QuestionHow can I compile it with MinGW ? Pinmemberdmichel764:28 26 Oct '09  
AnswerRe: How can I compile it with MinGW ? Pinmemberxdoukas9:55 28 Oct '09  
GeneralSuspend Problem - any advice Pinmembersnr19657:23 10 Sep '09  
GeneralRe: Suspend Problem - any advice Pinmemberxdoukas9:02 28 Oct '09  
GeneralUnpredictable behaviour due to race condition. PinmemberWolfgangSt5:36 7 May '09  
GeneralRe: Unpredictable behaviour due to race condition. Pinmemberxdoukas8:56 28 Oct '09  
Answercrash if function a() is allowed to return. basically uc_link needed to be implemented, which i've done. Pinmembersubatomicglue19:07 12 Jan '09  
GeneralRe: crash if function a() is allowed to return. basically uc_link needed to be implemented, which i've done. Pinmemberxdoukas8:48 28 Oct '09  
GeneralTwo Questions PinmemberBernhard Mulder15:17 10 Jun '04  
GeneralRe: Two Questions Pinmemberxdoukas2:33 11 Jun '04  
GeneralRe: Two Questions PinmemberBernhard Mulder5:56 11 Jun '04  
GeneralRe: Two Questions Pinmemberxdoukas7:17 11 Jun '04  
GeneralRe: Two Questions Pinmemberxdoukas5:20 13 Jun '04  
QuestionReinventing the wheel? PinsitebuilderMichael Dunn20:09 30 May '04  
AnswerRe: Reinventing the wheel? Pinmemberxdoukas23:17 31 May '04  
QuestionThreads? PinmemberJörgen Sigvardsson14:37 29 May '03  
AnswerRe: Threads? Pinsussxdoukas3:14 30 May '03  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120517.1 | Last Updated 7 Mar 2007
Article Copyright 2003 by xdoukas
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid