annotate lphobos/std/thread.d @ 883:b52d5de7783f

GC defines and linkage changes.
author Christian Kamm <kamm incasoftware de>
date Thu, 08 Jan 2009 18:20:02 +0100
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