annotate lphobos/std/thread.d @ 650:aa6a0b7968f7

Added test case for bug #100 Removed dubious check for not emitting static private global in other modules without access. This should be handled properly somewhere else, it's causing unresolved global errors for stuff that should work (in MiniD)
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Sun, 05 Oct 2008 17:28:15 +0200
parents 373489eeaf90
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
131
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1 // Written in the D programming language
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
2
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
3 /*
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
4 * Copyright (C) 2002-2007 by Digital Mars, www.digitalmars.com
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
5 * Written by Walter Bright
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
6 *
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
7 * This software is provided 'as-is', without any express or implied
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
8 * warranty. In no event will the authors be held liable for any damages
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
9 * arising from the use of this software.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
10 *
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
11 * Permission is granted to anyone to use this software for any purpose,
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
12 * including commercial applications, and to alter it and redistribute it
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
13 * freely, subject to the following restrictions:
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
14 *
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
15 * o The origin of this software must not be misrepresented; you must not
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
16 * claim that you wrote the original software. If you use this software
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
17 * in a product, an acknowledgment in the product documentation would be
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
18 * appreciated but is not required.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
19 * o Altered source versions must be plainly marked as such, and must not
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
20 * be misrepresented as being the original software.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
21 * o This notice may not be removed or altered from any source
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
22 * distribution.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
23 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
24
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
25 /**************************
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
26 * The thread module defines the class $(B Thread).
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
27 *
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
28 * $(B Thread) is the basis
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
29 * for writing multithreaded applications. Each thread
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
30 * has a unique instance of class $(B Thread) associated with it.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
31 * It is important to use the $(B Thread) class to create and manage
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
32 * threads as the garbage collector needs to know about all the threads.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
33 * Macros:
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
34 * WIKI=Phobos/StdThread
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
35 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
36
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
37 module std.thread;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
38
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
39 import std.c.stdio;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
40
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
41 //debug=thread;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
42
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
43 /* ================================ Win32 ================================= */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
44
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
45 version (Win32)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
46 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
47
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
48 private import std.c.windows.windows;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
49
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
50 extern (Windows) alias uint (*stdfp)(void *);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
51
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
52 extern (C)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
53 thread_hdl _beginthreadex(void* security, uint stack_size,
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
54 stdfp start_addr, void* arglist, uint initflag,
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
55 thread_id* thrdaddr);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
56
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
57 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
58 * The type of the thread handle used by the operating system.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
59 * For Windows, it is equivalent to a HANDLE from windows.d.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
60 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
61 alias HANDLE thread_hdl;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
62
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
63 alias uint thread_id;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
64
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
65 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
66 * Thrown for errors.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
67 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
68 class ThreadError : Error
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
69 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
70 this(char[] s)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
71 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
72 super("Thread error: " ~ s);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
73 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
74 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
75
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
76 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
77 * One of these is created for each thread.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
78 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
79 class Thread
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
80 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
81 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
82 * Constructor used by classes derived from Thread that override main().
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
83 * The optional stacksize parameter default value of 0 will cause threads
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
84 * to be created with the default size for the executable - Dave Fladebo
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
85 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
86 this(size_t stacksize = 0)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
87 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
88 this.stacksize = stacksize;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
89 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
90
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
91 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
92 * Constructor used by classes derived from Thread that override run().
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
93 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
94 this(int (*fp)(void *), void *arg, size_t stacksize = 0)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
95 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
96 this.fp = fp;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
97 this.arg = arg;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
98 this.stacksize = stacksize;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
99 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
100
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
101 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
102 * Constructor used by classes derived from Thread that override run().
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
103 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
104 this(int delegate() dg, size_t stacksize = 0)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
105 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
106 this.dg = dg;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
107 this.stacksize = stacksize;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
108 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
109
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
110 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
111 * Destructor
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
112 *
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
113 * If the thread hasn't been joined yet, detach it.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
114 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
115 ~this()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
116 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
117 if (state != TS.FINISHED)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
118 CloseHandle(hdl);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
119 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
120
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
121 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
122 * The handle to this thread assigned by the operating system. This is set
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
123 * to thread_id.init if the thread hasn't been started yet.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
124 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
125 thread_hdl hdl;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
126
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
127 void* stackBottom;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
128
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
129 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
130 * Create a new thread and start it running. The new thread initializes
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
131 * itself and then calls run(). start() can only be called once.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
132 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
133 void start()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
134 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
135 if (state != TS.INITIAL)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
136 error("already started");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
137
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
138 synchronized (Thread.classinfo)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
139 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
140 for (int i = 0; 1; i++)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
141 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
142 if (i == allThreads.length)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
143 error("too many threads");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
144 if (!allThreads[i])
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
145 { allThreads[i] = this;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
146 idx = i;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
147 if (i >= allThreadsDim)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
148 allThreadsDim = i + 1;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
149 break;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
150 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
151 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
152 nthreads++;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
153 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
154
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
155 state = TS.RUNNING;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
156 hdl = _beginthreadex(null, cast(uint)stacksize, &threadstart, cast(void*)this, 0, &id);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
157 if (hdl == cast(thread_hdl)0)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
158 { state = TS.FINISHED;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
159 synchronized (Thread.classinfo) allThreads[idx] = null;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
160 idx = -1;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
161 error("failed to start");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
162 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
163 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
164
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
165 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
166 * Entry point for a thread. If not overridden, it calls the function
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
167 * pointer fp and argument arg passed in the constructor, or the delegate
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
168 * dg.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
169 * Returns: the thread exit code, which is normally 0.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
170 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
171 int run()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
172 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
173 if (fp)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
174 return fp(arg);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
175 else if (dg)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
176 return dg();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
177 assert(0);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
178 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
179
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
180 /*****************************
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
181 * Wait for this thread to terminate.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
182 * Simply returns if thread has already terminated.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
183 * Throws: $(B ThreadError) if the thread hasn't begun yet or
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
184 * is called on itself.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
185 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
186 void wait()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
187 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
188 if (isSelf)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
189 error("wait on self");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
190 if (state != TS.FINISHED)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
191 { DWORD dw;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
192
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
193 dw = WaitForSingleObject(hdl, 0xFFFFFFFF);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
194 state = TS.FINISHED;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
195 CloseHandle(hdl);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
196 hdl = null;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
197 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
198 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
199
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
200 /******************************
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
201 * Wait for this thread to terminate or until milliseconds time has
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
202 * elapsed, whichever occurs first.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
203 * Simply returns if thread has already terminated.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
204 * Throws: $(B ThreadError) if the thread hasn't begun yet or
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
205 * is called on itself.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
206 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
207 void wait(uint milliseconds)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
208 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
209 if (isSelf)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
210 error("wait on self");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
211 if (state != TS.FINISHED)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
212 { DWORD dw;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
213
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
214 dw = WaitForSingleObject(hdl, milliseconds);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
215 state = TS.FINISHED;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
216 CloseHandle(hdl);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
217 hdl = null;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
218 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
219 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
220
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
221 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
222 * The state of a thread.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
223 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
224 enum TS
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
225 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
226 INITIAL, /// The thread hasn't been started yet.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
227 RUNNING, /// The thread is running or paused.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
228 TERMINATED, /// The thread has ended.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
229 FINISHED /// The thread has been cleaned up
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
230 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
231
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
232 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
233 * Returns the state of a thread.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
234 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
235 TS getState()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
236 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
237 return state;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
238 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
239
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
240 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
241 * The priority of a thread.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
242 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
243 enum PRIORITY
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
244 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
245 INCREASE, /// Increase thread priority
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
246 DECREASE, /// Decrease thread priority
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
247 IDLE, /// Assign thread low priority
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
248 CRITICAL /// Assign thread high priority
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
249 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
250
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
251 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
252 * Adjust the priority of this thread.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
253 * Throws: ThreadError if cannot set priority
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
254 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
255 void setPriority(PRIORITY p)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
256 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
257 int nPriority;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
258
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
259 switch (p)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
260 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
261 case PRIORITY.INCREASE:
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
262 nPriority = THREAD_PRIORITY_ABOVE_NORMAL;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
263 break;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
264 case PRIORITY.DECREASE:
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
265 nPriority = THREAD_PRIORITY_BELOW_NORMAL;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
266 break;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
267 case PRIORITY.IDLE:
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
268 nPriority = THREAD_PRIORITY_IDLE;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
269 break;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
270 case PRIORITY.CRITICAL:
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
271 nPriority = THREAD_PRIORITY_TIME_CRITICAL;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
272 break;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
273 default:
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
274 assert(0);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
275 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
276
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
277 if (SetThreadPriority(hdl, nPriority) == THREAD_PRIORITY_ERROR_RETURN)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
278 error("set priority");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
279 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
280
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
281 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
282 * Returns true if this thread is the current thread.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
283 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
284 bool isSelf()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
285 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
286 //printf("id = %d, self = %d\n", id, pthread_self());
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
287 return (id == GetCurrentThreadId());
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
288 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
289
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
290 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
291 * Returns a reference to the Thread for the thread that called the
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
292 * function.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
293 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
294 static Thread getThis()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
295 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
296 //printf("getThis(), allThreadsDim = %d\n", allThreadsDim);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
297 thread_id id = GetCurrentThreadId();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
298 for (int i = 0; i < allThreadsDim; i++)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
299 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
300 Thread t = allThreads[i];
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
301 if (t && id == t.id)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
302 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
303 return t;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
304 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
305 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
306 printf("didn't find it\n");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
307 assert(0);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
308 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
309
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
310 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
311 * Returns an array of all the threads currently running.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
312 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
313 static Thread[] getAll()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
314 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
315 synchronized (Thread.classinfo) return allThreads[0 .. allThreadsDim];
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
316 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
317
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
318 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
319 * Suspend execution of this thread.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
320 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
321 void pause()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
322 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
323 if (state != TS.RUNNING || SuspendThread(hdl) == 0xFFFFFFFF)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
324 error("cannot pause");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
325 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
326
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
327 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
328 * Resume execution of this thread.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
329 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
330 void resume()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
331 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
332 if (state != TS.RUNNING || ResumeThread(hdl) == 0xFFFFFFFF)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
333 error("cannot resume");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
334 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
335
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
336 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
337 * Suspend execution of all threads but this thread.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
338 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
339 static void pauseAll()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
340 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
341 synchronized (Thread.classinfo)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
342 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
343 if (nthreads > 1)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
344 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
345 thread_id thisid = GetCurrentThreadId();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
346
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
347 for (int i = 0; i < allThreadsDim; i++)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
348 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
349 Thread t = allThreads[i];
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
350 if (t && t.id != thisid && t.state == TS.RUNNING)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
351 t.pause();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
352 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
353 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
354 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
355 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
356
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
357 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
358 * Resume execution of all paused threads.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
359 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
360 static void resumeAll()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
361 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
362 synchronized (Thread.classinfo)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
363 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
364 if (nthreads > 1)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
365 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
366 thread_id thisid = GetCurrentThreadId();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
367
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
368 for (int i = 0; i < allThreadsDim; i++)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
369 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
370 Thread t = allThreads[i];
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
371 if (t && t.id != thisid && t.state == TS.RUNNING)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
372 t.resume();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
373 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
374 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
375 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
376 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
377
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
378 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
379 * Give up the remainder of this thread's time slice.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
380 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
381 static void yield()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
382 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
383 Sleep(0);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
384 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
385
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
386 /**
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
387 *
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
388 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
389 static uint nthreads = 1;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
390
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
391 private:
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
392
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
393 static uint allThreadsDim;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
394 static Thread[0x400] allThreads; // length matches value in C runtime
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
395
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
396 TS state;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
397 int idx = -1; // index into allThreads[]
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
398 thread_id id;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
399 size_t stacksize = 0;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
400
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
401 int (*fp)(void *);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
402 void *arg;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
403
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
404 int delegate() dg;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
405
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
406 void error(char[] msg)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
407 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
408 throw new ThreadError(msg);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
409 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
410
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
411
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
412 /* ***********************************************
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
413 * This is just a wrapper to interface between C rtl and Thread.run().
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
414 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
415
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
416 extern (Windows) static uint threadstart(void *p)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
417 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
418 Thread t = cast(Thread)p;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
419 int result;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
420
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
421 debug (thread) printf("Starting thread %d\n", t.idx);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
422 t.stackBottom = os_query_stackBottom();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
423 try
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
424 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
425 result = t.run();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
426 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
427 catch (Object o)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
428 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
429 fprintf(stderr, "Error: %.*s\n", o.toString());
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
430 result = 1;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
431 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
432
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
433 debug (thread) printf("Ending thread %d\n", t.idx);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
434 t.state = TS.TERMINATED;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
435 synchronized (Thread.classinfo)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
436 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
437 allThreads[t.idx] = null;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
438 t.idx = -1;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
439 nthreads--;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
440 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
441 return result;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
442 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
443
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
444
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
445 /**************************************
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
446 * Create a Thread for global main().
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
447 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
448
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
449 public static void thread_init()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
450 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
451 Thread t = new Thread();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
452
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
453 t.state = TS.RUNNING;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
454 t.id = GetCurrentThreadId();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
455 t.hdl = Thread.getCurrentThreadHandle();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
456 t.stackBottom = os_query_stackBottom();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
457
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
458 assert(!allThreads[0]);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
459 allThreads[0] = t;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
460 allThreadsDim = 1;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
461 t.idx = 0;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
462 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
463
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
464 static ~this()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
465 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
466 if (allThreadsDim)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
467 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
468 CloseHandle(allThreads[0].hdl);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
469 allThreads[0].hdl = GetCurrentThread();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
470 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
471 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
472
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
473 /********************************************
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
474 * Returns the handle of the current thread.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
475 * This is needed because GetCurrentThread() always returns -2 which
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
476 * is a pseudo-handle representing the current thread.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
477 * The returned thread handle is a windows resource and must be explicitly
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
478 * closed.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
479 * Many thanks to Justin (jhenzie@mac.com) for figuring this out
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
480 * and providing the fix.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
481 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
482 static thread_hdl getCurrentThreadHandle()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
483 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
484 thread_hdl currentThread = GetCurrentThread();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
485 thread_hdl actualThreadHandle;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
486
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
487 //thread_hdl currentProcess = cast(thread_hdl)-1;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
488 thread_hdl currentProcess = GetCurrentProcess(); // http://www.digitalmars.com/drn-bin/wwwnews?D/21217
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
489
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
490
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
491 uint access = cast(uint)0x00000002;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
492
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
493 DuplicateHandle(currentProcess, currentThread, currentProcess,
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
494 &actualThreadHandle, cast(uint)0, TRUE, access);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
495
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
496 return actualThreadHandle;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
497 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
498 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
499
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
500
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
501 /**********************************************
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
502 * Determine "bottom" of stack (actually the top on Win32 systems).
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
503 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
504
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
505 void *os_query_stackBottom()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
506 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
507 asm
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
508 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
509 naked ;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
510 mov EAX,FS:4 ;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
511 ret ;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
512 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
513 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
514
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
515 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
516
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
517 /* ================================ linux ================================= */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
518
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
519 version (linux)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
520 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
521
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
522 private import std.c.linux.linux;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
523 private import std.c.linux.linuxextern;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
524 private import llvm.intrinsic;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
525
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
526 alias uint pthread_t;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
527 extern (C) alias void (*__sighandler_t)(int);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
528
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
529 struct sigset_t
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
530 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
531 uint __val[1024 / (8 * uint.sizeof)];
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
532 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
533
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
534 struct sigaction_t
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
535 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
536 __sighandler_t sa_handler;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
537 sigset_t sa_mask;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
538 int sa_flags;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
539 void (*sa_restorer)();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
540 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
541
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
542 struct pthread_attr_t
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
543 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
544 int __detachstate;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
545 int __schedpolicy;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
546 struct __schedparam
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
547 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
548 int __sched_priority;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
549 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
550 int __inheritsched;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
551 int __scope;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
552 size_t __guardsize;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
553 int __stackaddr_set;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
554 void *__stackaddr;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
555 size_t __stacksize;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
556 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
557
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
558 unittest
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
559 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
560 assert(sigset_t.sizeof == 128);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
561 assert(sigaction_t.sizeof == 140);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
562 assert(sem_t.sizeof == 16);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
563 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
564
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
565 extern (C)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
566 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
567 int pthread_create(pthread_t*, void*, void* (*)(void*), void*);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
568 int pthread_join(pthread_t, void**);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
569 int pthread_kill(pthread_t, int);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
570 pthread_t pthread_self();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
571 int pthread_equal(pthread_t, pthread_t);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
572 int pthread_attr_init(pthread_attr_t*);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
573 int pthread_attr_setstacksize(pthread_attr_t *, size_t);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
574 int pthread_cancel(pthread_t);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
575 int pthread_setcancelstate(int, int*);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
576 int pthread_setcanceltype(int, int*);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
577 int sched_yield();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
578 int sigfillset(sigset_t*);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
579 int sigdelset(sigset_t*, int);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
580 int sigaction(int, sigaction_t*, sigaction_t*);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
581 int sigsuspend(sigset_t*);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
582
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
583 enum
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
584 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
585 PTHREAD_CANCEL_ENABLE,
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
586 PTHREAD_CANCEL_DISABLE
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
587 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
588
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
589 enum
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
590 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
591 PTHREAD_CANCEL_DEFERRED,
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
592 PTHREAD_CANCEL_ASYNCHRONOUS
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
593 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
594 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
595
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
596 class ThreadError : Error
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
597 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
598 this(char[] s)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
599 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
600 super("Thread error: " ~ s);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
601 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
602 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
603
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
604 class Thread
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
605 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
606 // The optional stacksize parameter default value of 0 will cause threads
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
607 // to be created with the default pthread size - Dave Fladebo
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
608 this(size_t stacksize = 0)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
609 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
610 init(stacksize);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
611 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
612
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
613 this(int (*fp)(void *), void *arg, size_t stacksize = 0)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
614 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
615 this.fp = fp;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
616 this.arg = arg;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
617 init(stacksize);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
618 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
619
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
620 this(int delegate() dg, size_t stacksize = 0)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
621 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
622 this.dg = dg;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
623 init(stacksize);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
624 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
625
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
626 ~this()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
627 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
628 pthread_cond_destroy(&waitCond);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
629 pthread_mutex_destroy(&waitMtx);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
630 if (state != TS.FINISHED)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
631 pthread_detach(id);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
632 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
633
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
634 pthread_t id;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
635 void* stackBottom;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
636 void* stackTop;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
637
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
638 void start()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
639 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
640 if (state != TS.INITIAL)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
641 error("already started");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
642
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
643 synchronized (Thread.classinfo)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
644 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
645 for (int i = 0; 1; i++)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
646 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
647 if (i == allThreads.length)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
648 error("too many threads");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
649 if (!allThreads[i])
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
650 { allThreads[i] = this;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
651 idx = i;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
652 if (i >= allThreadsDim)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
653 allThreadsDim = i + 1;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
654 break;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
655 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
656 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
657 nthreads++;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
658 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
659
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
660 state = TS.RUNNING;
473
373489eeaf90 Applied downs' lphobos update
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 131
diff changeset
661 printf("creating thread x%x\n", this);
131
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
662 //result = pthread_create(&id, null, &threadstart, this);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
663 // Create with thread attributes to allow non-default stack size - Dave Fladebo
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
664 int result = pthread_create(&id, &threadAttrs, &threadstart, cast(void*)this);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
665 if (result)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
666 { state = TS.FINISHED;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
667 synchronized (Thread.classinfo) allThreads[idx] = null;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
668 idx = -1;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
669 error("failed to start"); // BUG: should report errno
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
670 }
473
373489eeaf90 Applied downs' lphobos update
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 131
diff changeset
671 printf("t = x%x, id = %d\n", this, id);
131
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
672 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
673
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
674 int run()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
675 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
676 if (fp)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
677 return fp(arg);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
678 else if (dg)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
679 return dg();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
680 assert(0);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
681 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
682
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
683 void wait()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
684 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
685 if (isSelf)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
686 error("wait on self");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
687
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
688 if (state != TS.FINISHED)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
689 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
690 void *value;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
691
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
692 int result = pthread_join(id, &value);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
693 state = TS.FINISHED;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
694 if (result)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
695 error("failed to wait");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
696 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
697 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
698
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
699 void wait(uint milliseconds)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
700 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
701 // Implemented for POSIX systems by Dave Fladebo
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
702 if (isSelf)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
703 error("wait on self");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
704 if (state != TS.FINISHED)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
705 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
706 timespec ts;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
707 timeval tv;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
708
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
709 pthread_mutex_lock(&waitMtx);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
710 gettimeofday(&tv, null);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
711 ts.tv_sec = cast(__time_t)tv.tv_sec + cast(__time_t)(milliseconds / 1_000);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
712 ts.tv_nsec = (tv.tv_usec * 1_000) + ((milliseconds % 1_000) * 1_000_000);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
713 if (ts.tv_nsec > 1_000_000_000)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
714 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
715 ts.tv_sec += 1;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
716 ts.tv_nsec -= 1_000_000_000;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
717 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
718 if (pthread_cond_timedwait(&waitCond, &waitMtx, &ts))
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
719 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
720 int oldstate, oldtype;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
721 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
722 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
723
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
724 if (pthread_cancel(id)) // thread was not completed in the timeout period, cancel it
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
725 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
726 pthread_mutex_unlock(&waitMtx);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
727 error("cannot terminate thread via timed wait");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
728 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
729
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
730 pthread_setcancelstate(oldstate, null);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
731 pthread_setcanceltype(oldtype, null);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
732
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
733 state = TS.TERMINATED;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
734 synchronized (Thread.classinfo)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
735 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
736 allThreads[idx] = null;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
737 idx = -1;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
738 nthreads--;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
739 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
740
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
741 pthread_mutex_unlock(&waitMtx);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
742 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
743 else
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
744 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
745 pthread_mutex_unlock(&waitMtx);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
746 wait(); // condition has been signalled as complete (see threadstart()), terminate normally
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
747 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
748 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
749 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
750
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
751 enum TS
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
752 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
753 INITIAL, // created
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
754 RUNNING, // running
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
755 TERMINATED, // execution finished
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
756 FINISHED // pthread_join()'ed
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
757 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
758
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
759 TS getState()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
760 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
761 return state;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
762 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
763
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
764 enum PRIORITY
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
765 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
766 INCREASE,
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
767 DECREASE,
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
768 IDLE,
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
769 CRITICAL
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
770 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
771
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
772 void setPriority(PRIORITY p)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
773 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
774 /+ not implemented
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
775 int nPriority;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
776
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
777 switch (p)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
778 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
779 case PRIORITY.INCREASE:
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
780 nPriority = THREAD_PRIORITY_ABOVE_NORMAL;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
781 break;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
782 case PRIORITY.DECREASE:
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
783 nPriority = THREAD_PRIORITY_BELOW_NORMAL;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
784 break;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
785 case PRIORITY.IDLE:
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
786 nPriority = THREAD_PRIORITY_IDLE;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
787 break;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
788 case PRIORITY.CRITICAL:
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
789 nPriority = THREAD_PRIORITY_TIME_CRITICAL;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
790 break;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
791 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
792
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
793 if (SetThreadPriority(hdl, nPriority) == THREAD_PRIORITY_ERROR_RETURN)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
794 error("set priority");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
795 +/
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
796 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
797
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
798 int isSelf()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
799 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
800 //printf("id = %d, self = %d\n", id, pthread_self());
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
801 return pthread_equal(pthread_self(), id);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
802 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
803
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
804 static Thread getThis()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
805 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
806 //printf("getThis(), allThreadsDim = %d\n", allThreadsDim);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
807 pthread_t id = pthread_self();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
808 //printf("id = %d\n", id);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
809 for (int i = 0; i < allThreadsDim; i++)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
810 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
811 Thread t = allThreads[i];
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
812 //printf("allThreads[%d] = x%x, id = %d\n", i, t, (t ? t.id : 0));
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
813 if (t && pthread_equal(id, t.id))
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
814 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
815 return t;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
816 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
817 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
818 printf("didn't find it\n");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
819 assert(null);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
820 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
821
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
822 static Thread[] getAll()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
823 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
824 synchronized (Thread.classinfo) return allThreads[0 .. allThreadsDim];
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
825 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
826
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
827 void pause()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
828 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
829 if (state == TS.RUNNING)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
830 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
831 if (pthread_kill(id, SIGUSR1))
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
832 error("cannot pause");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
833 else
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
834 sem_wait(&flagSuspend); // wait for acknowledgement
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
835 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
836 else
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
837 error("cannot pause");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
838 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
839
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
840 void resume()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
841 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
842 if (state == TS.RUNNING)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
843 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
844 if (pthread_kill(id, SIGUSR2))
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
845 error("cannot resume");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
846 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
847 else
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
848 error("cannot resume");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
849 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
850
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
851 static void pauseAll()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
852 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
853 synchronized (Thread.classinfo)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
854 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
855 if (nthreads > 1)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
856 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
857 pthread_t thisid = pthread_self();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
858 int npause = 0;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
859
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
860 for (int i = 0; i < allThreadsDim; i++)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
861 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
862 Thread t = allThreads[i];
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
863 if (t && !pthread_equal(thisid, t.id) && t.state == TS.RUNNING)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
864 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
865 if (pthread_kill(t.id, SIGUSR1))
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
866 t.error("cannot pause");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
867 else
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
868 npause++; // count of paused threads
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
869 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
870 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
871
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
872 // Wait for each paused thread to acknowledge
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
873 while (npause--)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
874 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
875 sem_wait(&flagSuspend);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
876 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
877 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
878 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
879 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
880
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
881 static void resumeAll()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
882 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
883 synchronized (Thread.classinfo)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
884 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
885 if (nthreads > 1)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
886 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
887 pthread_t thisid = pthread_self();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
888
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
889 for (int i = 0; i < allThreadsDim; i++)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
890 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
891 Thread t = allThreads[i];
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
892 if (t && t.id != thisid && t.state == TS.RUNNING)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
893 t.resume();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
894 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
895 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
896 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
897 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
898
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
899 static void yield()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
900 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
901 sched_yield();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
902 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
903
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
904 static uint nthreads = 1;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
905
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
906 private:
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
907
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
908 static uint allThreadsDim;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
909
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
910 // Set max to Windows equivalent for compatibility.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
911 // pthread_create will fail gracefully if stack limit
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
912 // is reached prior to allThreads max.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
913 static Thread[0x400] allThreads;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
914
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
915 static sem_t flagSuspend;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
916
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
917 TS state;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
918 int idx = -1; // index into allThreads[]
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
919 int flags = 0;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
920
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
921 pthread_attr_t threadAttrs;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
922 pthread_mutex_t waitMtx;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
923 pthread_cond_t waitCond;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
924
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
925 int (*fp)(void *);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
926 void *arg;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
927
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
928 int delegate() dg;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
929
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
930 void error(char[] msg)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
931 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
932 throw new ThreadError(msg);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
933 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
934
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
935 void init(size_t stackSize)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
936 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
937 // set to default values regardless
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
938 // passing this as the 2nd arg. for pthread_create()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
939 // w/o setting an attribute is equivalent to passing null.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
940 pthread_attr_init(&threadAttrs);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
941 if (stackSize > 0)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
942 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
943 if (pthread_attr_setstacksize(&threadAttrs,stackSize))
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
944 error("cannot set stack size");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
945 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
946
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
947 if (pthread_mutex_init(&waitMtx, null))
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
948 error("cannot initialize wait mutex");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
949
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
950 if (pthread_cond_init(&waitCond, null))
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
951 error("cannot initialize wait condition");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
952 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
953
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
954 /************************************************
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
955 * This is just a wrapper to interface between C rtl and Thread.run().
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
956 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
957
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
958 extern (C) static void *threadstart(void *p)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
959 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
960 Thread t = cast(Thread)p;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
961 int result;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
962
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
963 debug (thread) printf("Starting thread x%x (%d)\n", t, t.idx);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
964
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
965 // Need to set t.id here, because thread is off and running
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
966 // before pthread_create() sets it.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
967 t.id = pthread_self();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
968
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
969 t.stackBottom = getESP();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
970 try
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
971 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
972 if(t.state == TS.RUNNING)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
973 pthread_cond_signal(&t.waitCond); // signal the wait condition (see the timed wait function)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
974 result = t.run();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
975 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
976 catch (Object o)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
977 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
978 fprintf(stderr, "Error: %.*s\n", o.toString());
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
979 result = 1;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
980 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
981
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
982 debug (thread) printf("Ending thread %d\n", t.idx);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
983 t.state = TS.TERMINATED;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
984 synchronized (Thread.classinfo)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
985 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
986 allThreads[t.idx] = null;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
987 t.idx = -1;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
988 nthreads--;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
989 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
990 return cast(void*)result;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
991 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
992
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
993
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
994 /**************************************
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
995 * Create a Thread for global main().
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
996 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
997
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
998 public static void thread_init()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
999 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1000 Thread t = new Thread();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1001
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1002 t.state = TS.RUNNING;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1003 t.id = pthread_self();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1004
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1005 version (none)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1006 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1007 // See discussion: http://autopackage.org/forums/viewtopic.php?t=22
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1008 static void** libc_stack_end;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1009
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1010 if (libc_stack_end == libc_stack_end.init)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1011 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1012 void* handle = dlopen(null, RTLD_NOW);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1013 libc_stack_end = cast(void **)dlsym(handle, "__libc_stack_end");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1014 dlclose(handle);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1015 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1016 t.stackBottom = *libc_stack_end;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1017 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1018 else
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1019 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1020 t.stackBottom = cast(void*)__libc_stack_end;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1021 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1022
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1023 assert(!allThreads[0]);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1024 allThreads[0] = t;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1025 allThreadsDim = 1;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1026 t.idx = 0;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1027
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1028 /* Install signal handlers so we can suspend/resume threads
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1029 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1030
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1031 int result;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1032 sigaction_t sigact;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1033 result = sigfillset(&sigact.sa_mask);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1034 if (result)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1035 goto Lfail;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1036 sigact.sa_handler = &pauseHandler;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1037 result = sigaction(SIGUSR1, &sigact, null);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1038 if (result)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1039 goto Lfail;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1040 sigact.sa_handler = &resumeHandler;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1041 result = sigaction(SIGUSR2, &sigact, null);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1042 if (result)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1043 goto Lfail;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1044
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1045 result = sem_init(&flagSuspend, 0, 0);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1046 if (result)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1047 goto Lfail;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1048
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1049 return;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1050
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1051 Lfail:
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1052 t.error("cannot initialize threads");
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1053 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1054
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1055 /**********************************
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1056 * This gets called when a thread gets SIGUSR1.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1057 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1058
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1059 extern (C) static void pauseHandler(int sig)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1060 { int result;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1061
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1062 // Save all registers on the stack so they'll be scanned by the GC
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1063 version(none) asm
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1064 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1065 pusha ;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1066 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1067
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1068 assert(sig == SIGUSR1);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1069
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1070 sigset_t sigmask;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1071 result = sigfillset(&sigmask);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1072 assert(result == 0);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1073 result = sigdelset(&sigmask, SIGUSR2);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1074 assert(result == 0);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1075
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1076 Thread t = getThis();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1077 t.stackTop = getESP();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1078 t.flags &= ~1;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1079 // Release the semaphore _after_ stackTop is set
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1080 sem_post(&flagSuspend);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1081 while (1)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1082 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1083 sigsuspend(&sigmask); // suspend until SIGUSR2
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1084 if (t.flags & 1) // ensure it was resumeHandler()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1085 break;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1086 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1087
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1088 // Restore all registers
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1089 version(none) asm
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1090 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1091 popa ;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1092 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1093 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1094
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1095 /**********************************
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1096 * This gets called when a thread gets SIGUSR2.
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1097 */
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1098
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1099 extern (C) static void resumeHandler(int sig)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1100 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1101 Thread t = getThis();
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1102
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1103 t.flags |= 1;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1104 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1105
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1106 public static void* getESP()
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1107 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1108 version(D_InlineAsm_X86)
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1109 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1110 asm
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1111 { naked ;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1112 mov EAX,ESP ;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1113 ret ;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1114 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1115 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1116 else
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1117 {
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1118 void* p = llvm_frameaddress(0);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1119 assert(p !is null);
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1120 return p;
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1121 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1122 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1123 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1124
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1125
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1126 }
5825d48b27d1 [svn r135] * Merged DMD 1.025 *
lindquist
parents:
diff changeset
1127