1/* cilk_fiber-unix.h                  -*-C++-*-
2 *
3 *************************************************************************
4 *
5 *  @copyright
6 *  Copyright (C) 2012-2013, Intel Corporation
7 *  All rights reserved.
8 *
9 *  @copyright
10 *  Redistribution and use in source and binary forms, with or without
11 *  modification, are permitted provided that the following conditions
12 *  are met:
13 *
14 *    * Redistributions of source code must retain the above copyright
15 *      notice, this list of conditions and the following disclaimer.
16 *    * Redistributions in binary form must reproduce the above copyright
17 *      notice, this list of conditions and the following disclaimer in
18 *      the documentation and/or other materials provided with the
19 *      distribution.
20 *    * Neither the name of Intel Corporation nor the names of its
21 *      contributors may be used to endorse or promote products derived
22 *      from this software without specific prior written permission.
23 *
24 *  @copyright
25 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 *  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
32 *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
33 *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
35 *  WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 *  POSSIBILITY OF SUCH DAMAGE.
37 **************************************************************************/
38
39#ifndef INCLUDED_CILK_FIBER_UNIX_DOT_H
40#define INCLUDED_CILK_FIBER_UNIX_DOT_H
41
42#ifndef __cplusplus
43#   error cilk_fiber-unix.h is a C++-only header
44#endif
45
46#include "cilk_fiber.h"
47#include "jmpbuf.h"
48
49/**
50 * @file cilk_fiber-unix.h
51 *
52 * @brief Unix-specific implementation for cilk_fiber.
53 */
54
55/**
56 * @brief Unix-specific fiber class derived from portable fiber class
57 */
58struct cilk_fiber_sysdep : public cilk_fiber
59{
60  public:
61
62#if SUPPORT_GET_CURRENT_FIBER
63    /**
64     * @brief Gets the current fiber from TLS.
65     */
66    static cilk_fiber_sysdep* get_current_fiber_sysdep();
67#endif
68
69    /**
70     * @brief Construct the system-dependent portion of a fiber.
71     *
72     * @param stack_size  The size of the stack for this fiber.
73     */
74    cilk_fiber_sysdep(std::size_t stack_size);
75
76    /**
77     * @brief Construct the system-dependent of a fiber created from a
78     * thread.
79     */
80    cilk_fiber_sysdep(from_thread_t);
81
82    /**
83     * @brief Destructor
84     */
85    ~cilk_fiber_sysdep();
86
87    /**
88     * @brief OS-specific calls to convert this fiber back to thread.
89     *
90     * Nothing to do for Linux.
91     */
92    void convert_fiber_back_to_thread();
93
94    /**
95     * @brief System-dependent function to suspend self and resume execution of "other".
96     *
97     * This fiber is suspended.
98     *
99     * @pre @c is_resumable() should be true.
100     *
101     * @param other              Fiber to resume.
102     */
103    void suspend_self_and_resume_other_sysdep(cilk_fiber_sysdep* other);
104
105    /**
106     * @brief System-dependent function called to jump to @p other
107     * fiber.
108     *
109     * @pre @c is_resumable() should be false.
110     *
111     * @param other  Fiber to resume.
112     */
113    NORETURN jump_to_resume_other_sysdep(cilk_fiber_sysdep* other);
114
115    /**
116     * @brief Runs the start_proc.
117     * @pre is_resumable() should be false.
118     * @pre is_allocated_from_thread() should be false.
119     * @pre m_start_proc must be valid.
120     */
121    NORETURN run();
122
123    /**
124     * @brief Returns the base of this fiber's stack.
125     */
126    inline char* get_stack_base_sysdep() { return m_stack_base; }
127
128  private:
129    char*                       m_stack_base;     ///< The base of this fiber's stack.
130    char*                       m_stack;          // Stack memory (low address)
131    __CILK_JUMP_BUFFER          m_resume_jmpbuf;  // Place to resume fiber
132    unsigned                    m_magic;          // Magic number for checking
133
134    static int                  s_page_size;      // Page size for
135                                                  // stacks.
136
137    // Allocate memory for a stack.  This method
138    // initializes m_stack and m_stack_base.
139    void make_stack(size_t stack_size);
140
141    // Deallocates memory for the stack.
142    void free_stack();
143
144    // Common helper method for implementation of resume_other_sysdep
145    // variants.
146    inline void resume_other_sysdep(cilk_fiber_sysdep* other);
147};
148
149#endif // ! defined(INCLUDED_CILK_FIBER_UNIX_DOT_H)
150