Mercurial > projects > ldc
comparison tango/lib/compiler/llvmdc/monitor.c @ 133:44a95ac7368a trunk
[svn r137] Many fixes towards tango.io.Console working, but not quite there yet...
In particular, assertions has been fixed to include file/line info, and much more!
author | lindquist |
---|---|
date | Mon, 14 Jan 2008 05:11:54 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
132:1700239cab2e | 133:44a95ac7368a |
---|---|
1 // D programming language runtime library | |
2 // Public Domain | |
3 // written by Walter Bright, Digital Mars | |
4 // www.digitalmars.com | |
5 | |
6 // This is written in C because nobody has written a pthreads interface | |
7 // to D yet. | |
8 | |
9 | |
10 #include <stdio.h> | |
11 #include <stdlib.h> | |
12 #include <assert.h> | |
13 | |
14 #if _WIN32 | |
15 #elif linux | |
16 #define USE_PTHREADS 1 | |
17 #else | |
18 #endif | |
19 | |
20 #if _WIN32 | |
21 #include <windows.h> | |
22 #endif | |
23 | |
24 #if USE_PTHREADS | |
25 #include <pthread.h> | |
26 #endif | |
27 | |
28 #include "mars.h" | |
29 | |
30 // This is what the monitor reference in Object points to | |
31 typedef struct Monitor | |
32 { | |
33 void* impl; // for user-level monitors | |
34 | |
35 #if _WIN32 | |
36 CRITICAL_SECTION mon; | |
37 #endif | |
38 | |
39 #if USE_PTHREADS | |
40 pthread_mutex_t mon; | |
41 #endif | |
42 } Monitor; | |
43 | |
44 #define MONPTR(h) (&((Monitor *)(h)->monitor)->mon) | |
45 | |
46 static volatile int inited; | |
47 | |
48 /* =============================== Win32 ============================ */ | |
49 | |
50 #if _WIN32 | |
51 | |
52 static CRITICAL_SECTION _monitor_critsec; | |
53 | |
54 void _STI_monitor_staticctor() | |
55 { | |
56 if (!inited) | |
57 { InitializeCriticalSection(&_monitor_critsec); | |
58 inited = 1; | |
59 } | |
60 } | |
61 | |
62 void _STD_monitor_staticdtor() | |
63 { | |
64 if (inited) | |
65 { inited = 0; | |
66 DeleteCriticalSection(&_monitor_critsec); | |
67 } | |
68 } | |
69 | |
70 void _d_monitor_create(Object *h) | |
71 { | |
72 /* | |
73 * NOTE: Assume this is only called when h->monitor is null prior to the | |
74 * call. However, please note that another thread may call this function | |
75 * at the same time, so we can not assert this here. Instead, try and | |
76 * create a lock, and if one already exists then forget about it. | |
77 */ | |
78 | |
79 //printf("+_d_monitor_create(%p)\n", h); | |
80 assert(h); | |
81 Monitor *cs = NULL; | |
82 EnterCriticalSection(&_monitor_critsec); | |
83 if (!h->monitor) | |
84 { | |
85 cs = (Monitor *)calloc(sizeof(Monitor), 1); | |
86 assert(cs); | |
87 InitializeCriticalSection(&cs->mon); | |
88 h->monitor = (void *)cs; | |
89 cs = NULL; | |
90 } | |
91 LeaveCriticalSection(&_monitor_critsec); | |
92 if (cs) | |
93 free(cs); | |
94 //printf("-_d_monitor_create(%p)\n", h); | |
95 } | |
96 | |
97 void _d_monitor_destroy(Object *h) | |
98 { | |
99 //printf("+_d_monitor_destroy(%p)\n", h); | |
100 assert(h && h->monitor && !(((Monitor*)h->monitor)->impl)); | |
101 DeleteCriticalSection(MONPTR(h)); | |
102 free((void *)h->monitor); | |
103 h->monitor = NULL; | |
104 //printf("-_d_monitor_destroy(%p)\n", h); | |
105 } | |
106 | |
107 int _d_monitor_lock(Object *h) | |
108 { | |
109 //printf("+_d_monitor_acquire(%p)\n", h); | |
110 assert(h && h->monitor && !(((Monitor*)h->monitor)->impl)); | |
111 EnterCriticalSection(MONPTR(h)); | |
112 //printf("-_d_monitor_acquire(%p)\n", h); | |
113 } | |
114 | |
115 void _d_monitor_unlock(Object *h) | |
116 { | |
117 //printf("+_d_monitor_release(%p)\n", h); | |
118 assert(h && h->monitor && !(((Monitor*)h->monitor)->impl)); | |
119 LeaveCriticalSection(MONPTR(h)); | |
120 //printf("-_d_monitor_release(%p)\n", h); | |
121 } | |
122 | |
123 #endif | |
124 | |
125 /* =============================== linux ============================ */ | |
126 | |
127 #if USE_PTHREADS | |
128 | |
129 // Includes attribute fixes from David Friedman's GDC port | |
130 | |
131 static pthread_mutex_t _monitor_critsec; | |
132 static pthread_mutexattr_t _monitors_attr; | |
133 | |
134 void _STI_monitor_staticctor() | |
135 { | |
136 if (!inited) | |
137 { | |
138 pthread_mutexattr_init(&_monitors_attr); | |
139 pthread_mutexattr_settype(&_monitors_attr, PTHREAD_MUTEX_RECURSIVE_NP); | |
140 pthread_mutex_init(&_monitor_critsec, 0); | |
141 inited = 1; | |
142 } | |
143 } | |
144 | |
145 void _STD_monitor_staticdtor() | |
146 { | |
147 if (inited) | |
148 { inited = 0; | |
149 pthread_mutex_destroy(&_monitor_critsec); | |
150 pthread_mutexattr_destroy(&_monitors_attr); | |
151 } | |
152 } | |
153 | |
154 void _d_monitor_create(Object *h) | |
155 { | |
156 /* | |
157 * NOTE: Assume this is only called when h->monitor is null prior to the | |
158 * call. However, please note that another thread may call this function | |
159 * at the same time, so we can not assert this here. Instead, try and | |
160 * create a lock, and if one already exists then forget about it. | |
161 */ | |
162 | |
163 //printf("+_d_monitor_create(%p)\n", h); | |
164 assert(h); | |
165 Monitor *cs = NULL; | |
166 pthread_mutex_lock(&_monitor_critsec); | |
167 if (!h->monitor) | |
168 { | |
169 cs = (Monitor *)calloc(sizeof(Monitor), 1); | |
170 assert(cs); | |
171 pthread_mutex_init(&cs->mon, & _monitors_attr); | |
172 h->monitor = (void *)cs; | |
173 cs = NULL; | |
174 } | |
175 pthread_mutex_unlock(&_monitor_critsec); | |
176 if (cs) | |
177 free(cs); | |
178 //printf("-_d_monitor_create(%p)\n", h); | |
179 } | |
180 | |
181 void _d_monitor_destroy(Object *h) | |
182 { | |
183 //printf("+_d_monitor_destroy(%p)\n", h); | |
184 assert(h && h->monitor && !(((Monitor*)h->monitor)->impl)); | |
185 pthread_mutex_destroy(MONPTR(h)); | |
186 free((void *)h->monitor); | |
187 h->monitor = NULL; | |
188 //printf("-_d_monitor_destroy(%p)\n", h); | |
189 } | |
190 | |
191 int _d_monitor_lock(Object *h) | |
192 { | |
193 //printf("+_d_monitor_acquire(%p)\n", h); | |
194 assert(h && h->monitor && !(((Monitor*)h->monitor)->impl)); | |
195 pthread_mutex_lock(MONPTR(h)); | |
196 //printf("-_d_monitor_acquire(%p)\n", h); | |
197 } | |
198 | |
199 void _d_monitor_unlock(Object *h) | |
200 { | |
201 //printf("+_d_monitor_release(%p)\n", h); | |
202 assert(h && h->monitor && !(((Monitor*)h->monitor)->impl)); | |
203 pthread_mutex_unlock(MONPTR(h)); | |
204 //printf("-_d_monitor_release(%p)\n", h); | |
205 } | |
206 | |
207 #endif |