Statistics
| Branch: | Revision:

root / include / ccoroutine.h @ ffa9279f

History | View | Annotate | Download (4.33 KB)

1
//==========================================================================
2
//   CCOROUTINE.H  -  header for
3
//                     OMNeT++/OMNEST
4
//            Discrete System Simulation in C++
5
//
6
//  Declarations:
7
//    class cCoroutine: coroutines
8
//
9
//==========================================================================
10

    
11
/*--------------------------------------------------------------*
12
  Copyright (C) 1992-2008 Andras Varga
13
  Copyright (C) 2006-2008 OpenSim Ltd.
14

15
  This file is distributed WITHOUT ANY WARRANTY. See the file
16
  `license' for details on this and other legal matters.
17
*--------------------------------------------------------------*/
18

    
19
#ifndef __CCOROUTINE_H
20
#define __CCOROUTINE_H
21

    
22
#include "simkerneldefs.h"
23
#include "platdep/platmisc.h"  // for <windows.h>
24

    
25
// select coroutine library
26
#ifdef _WIN32
27
#define USE_WIN32_FIBERS
28
#else
29
#define USE_PORTABLE_COROUTINES
30
#endif
31

    
32
NAMESPACE_BEGIN
33

    
34
#ifdef USE_PORTABLE_COROUTINES
35
struct _Task;
36
#endif
37

    
38
/**
39
 * Prototype for functions that can be used with cCoroutine objects as
40
 * coroutine bodies.
41
 * @ingroup EnumsTypes
42
 */
43
typedef void (*CoroutineFnp)( void * );
44

    
45
//--------------------------------------------------------------------------
46

    
47
/**
48
 * Low-level coroutine library. Coroutines are used by cSimpleModule.
49
 *
50
 * cCoroutine has platform-dependent implementation:
51
 *
52
 * On Windows, it uses the Win32 Fiber API.
53

54
 * On other platforms, the implementation a portable coroutine library,
55
 * first described by Stig Kofoed ("Portable coroutines", see the Manual
56
 * for a better reference). It creates all coroutine stacks within the main
57
 * stack, and uses setjmp()/longjmp() for context switching. This
58
 * implies that the maximum stack space allowed by the operating system
59
 * for the \opp process must be sufficiently high (several,
60
 * maybe several hundred megabytes), otherwise a segmentation fault
61
 * will occur.
62
 *
63
 * @ingroup Internals
64
 */
65
class SIM_API cCoroutine
66
{
67
  protected:
68
#ifdef USE_WIN32_FIBERS
69
    LPVOID lpFiber;
70
    static LPVOID lpMainFiber;
71
    unsigned stacksize;
72
#endif
73
#ifdef USE_PORTABLE_COROUTINES
74
    _Task *task;
75
#endif
76

    
77
  public:
78
    /** @name Coroutine control */
79
    //@{
80

    
81
    /**
82
     * Initializes the coroutine library. This function has to be called
83
     * exactly once in a program, possibly at the top of main().
84
     */
85
    static void init(unsigned total_stack, unsigned main_stack);
86

    
87
    /**
88
     * Switch to another coroutine. The execution of the current coroutine
89
     * is suspended and the other coroutine is resumed from the point it
90
     * last left off.
91
     */
92
    static void switchTo(cCoroutine *cor);
93

    
94
    /**
95
     * Switch to the main coroutine (the one main() runs in).
96
     */
97
    static void switchToMain();
98
    //@}
99

    
100
    /** @name Constructor, destructor */
101
    //@{
102

    
103
    /**
104
     * Sets up a coroutine. The arguments are the function that should be
105
     * run in the coroutine, a pointer that is passed to the coroutine
106
     * function, and the stack size.
107
     */
108
    bool setup(CoroutineFnp fnp, void *arg, unsigned stack_size);
109

    
110
    /**
111
     * Constructor.
112
     */
113
    cCoroutine();
114

    
115
    /**
116
     * Destructor.
117
     */
118
    virtual ~cCoroutine();
119
    //@}
120

    
121
    /** @name Coroutine statistics */
122
    //@{
123

    
124
    /**
125
     * Returns true if there was a stack overflow during execution of the
126
     * coroutine.
127
     *
128
     * Windows/Fiber API: Not implemented: always returns false.
129
     *
130
     * Portable coroutines: it checks the intactness of a predefined byte pattern
131
     * (0xdeadbeef) at the stack boundary, and report stack overflow
132
     * if it was overwritten. The mechanism usually works fine, but occasionally
133
     * it can be fooled by large uninitialized local variables
134
     * (e.g. char buffer[256]): if the byte pattern happens to fall in the
135
     * middle of such a local variable, it may be preserved intact and
136
     * stack violation is not detected.
137
     */
138
    virtual bool hasStackOverflow() const;
139

    
140
    /**
141
     * Returns the stack size of the coroutine.
142
     */
143
    virtual unsigned getStackSize() const;
144

    
145
    /**
146
     * Returns the amount of stack actually used by the coroutine.
147
     *
148
     * Windows/Fiber API: Not implemented, always returns 0.
149
     *
150
     * Portable coroutines: It works by checking the intactness of
151
     * predefined byte patterns (0xdeadbeef) placed in the stack.
152
     */
153
    virtual unsigned getStackUsage() const;
154
    //@}
155
};
156

    
157
NAMESPACE_END
158

    
159

    
160
#endif
161

    
162