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