comparison druntime/src/compiler/ldc/monitor.c @ 1458:e0b2d67cfe7c

Added druntime (this should be removed once it works).
author Robert Clipsham <robert@octarineparrot.com>
date Tue, 02 Jun 2009 17:43:06 +0100
parents
children
comparison
equal deleted inserted replaced
1456:7b218ec1044f 1458:e0b2d67cfe7c
1 /**
2 * Contains the implementation for object monitors.
3 *
4 * Copyright: Copyright Digital Mars 2000 - 2009.
5 * License: <a href="http://www.boost.org/LICENSE_1_0.txt>Boost License 1.0</a>.
6 * Authors: Walter Bright, Sean Kelly
7 *
8 * Copyright Digital Mars 2000 - 2009.
9 * Distributed under the Boost Software License, Version 1.0.
10 * (See accompanying file LICENSE_1_0.txt or copy at
11 * http://www.boost.org/LICENSE_1_0.txt)
12 */
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <assert.h>
16
17 #if _WIN32
18 #elif linux || __APPLE__
19 #define USE_PTHREADS 1
20 #else
21 #endif
22
23 #if _WIN32
24 #include <windows.h>
25 #endif
26
27 #if USE_PTHREADS
28 #include <pthread.h>
29 #endif
30
31 #include "mars.h"
32
33 // This is what the monitor reference in Object points to
34 typedef struct Monitor
35 {
36 void* impl; // for user-level monitors
37 Array devt; // for internal monitors
38
39 #if _WIN32
40 CRITICAL_SECTION mon;
41 #endif
42
43 #if USE_PTHREADS
44 pthread_mutex_t mon;
45 #endif
46 } Monitor;
47
48 #define MONPTR(h) (&((Monitor *)(h)->monitor)->mon)
49
50 static volatile int inited;
51
52 /* =============================== Win32 ============================ */
53
54 #if _WIN32
55
56 static CRITICAL_SECTION _monitor_critsec;
57
58 void _STI_monitor_staticctor()
59 {
60 if (!inited)
61 { InitializeCriticalSection(&_monitor_critsec);
62 inited = 1;
63 }
64 }
65
66 void _STD_monitor_staticdtor()
67 {
68 if (inited)
69 { inited = 0;
70 DeleteCriticalSection(&_monitor_critsec);
71 }
72 }
73
74 void _d_monitor_create(Object *h)
75 {
76 /*
77 * NOTE: Assume this is only called when h->monitor is null prior to the
78 * call. However, please note that another thread may call this function
79 * at the same time, so we can not assert this here. Instead, try and
80 * create a lock, and if one already exists then forget about it.
81 */
82
83 //printf("+_d_monitor_create(%p)\n", h);
84 assert(h);
85 Monitor *cs = NULL;
86 EnterCriticalSection(&_monitor_critsec);
87 if (!h->monitor)
88 {
89 cs = (Monitor *)calloc(sizeof(Monitor), 1);
90 assert(cs);
91 InitializeCriticalSection(&cs->mon);
92 h->monitor = (void *)cs;
93 cs = NULL;
94 }
95 LeaveCriticalSection(&_monitor_critsec);
96 if (cs)
97 free(cs);
98 //printf("-_d_monitor_create(%p)\n", h);
99 }
100
101 void _d_monitor_destroy(Object *h)
102 {
103 //printf("+_d_monitor_destroy(%p)\n", h);
104 assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
105 DeleteCriticalSection(MONPTR(h));
106 free((void *)h->monitor);
107 h->monitor = NULL;
108 //printf("-_d_monitor_destroy(%p)\n", h);
109 }
110
111 int _d_monitor_lock(Object *h)
112 {
113 //printf("+_d_monitor_acquire(%p)\n", h);
114 assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
115 EnterCriticalSection(MONPTR(h));
116 //printf("-_d_monitor_acquire(%p)\n", h);
117 }
118
119 void _d_monitor_unlock(Object *h)
120 {
121 //printf("+_d_monitor_release(%p)\n", h);
122 assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
123 LeaveCriticalSection(MONPTR(h));
124 //printf("-_d_monitor_release(%p)\n", h);
125 }
126
127 #endif
128
129 /* =============================== linux ============================ */
130
131 #if USE_PTHREADS
132
133 #ifndef PTHREAD_MUTEX_RECURSIVE
134 # define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
135 #endif
136
137 // Includes attribute fixes from David Friedman's GDC port
138
139 static pthread_mutex_t _monitor_critsec;
140 static pthread_mutexattr_t _monitors_attr;
141
142 void _STI_monitor_staticctor()
143 {
144 if (!inited)
145 {
146 pthread_mutexattr_init(&_monitors_attr);
147 pthread_mutexattr_settype(&_monitors_attr, PTHREAD_MUTEX_RECURSIVE);
148 pthread_mutex_init(&_monitor_critsec, 0);
149 inited = 1;
150 }
151 }
152
153 void _STD_monitor_staticdtor()
154 {
155 if (inited)
156 { inited = 0;
157 pthread_mutex_destroy(&_monitor_critsec);
158 pthread_mutexattr_destroy(&_monitors_attr);
159 }
160 }
161
162 void _d_monitor_create(Object *h)
163 {
164 /*
165 * NOTE: Assume this is only called when h->monitor is null prior to the
166 * call. However, please note that another thread may call this function
167 * at the same time, so we can not assert this here. Instead, try and
168 * create a lock, and if one already exists then forget about it.
169 */
170
171 //printf("+_d_monitor_create(%p)\n", h);
172 assert(h);
173 Monitor *cs = NULL;
174 pthread_mutex_lock(&_monitor_critsec);
175 if (!h->monitor)
176 {
177 cs = (Monitor *)calloc(sizeof(Monitor), 1);
178 assert(cs);
179 pthread_mutex_init(&cs->mon, & _monitors_attr);
180 h->monitor = (void *)cs;
181 cs = NULL;
182 }
183 pthread_mutex_unlock(&_monitor_critsec);
184 if (cs)
185 free(cs);
186 //printf("-_d_monitor_create(%p)\n", h);
187 }
188
189 void _d_monitor_destroy(Object *h)
190 {
191 //printf("+_d_monitor_destroy(%p)\n", h);
192 assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
193 pthread_mutex_destroy(MONPTR(h));
194 free((void *)h->monitor);
195 h->monitor = NULL;
196 //printf("-_d_monitor_destroy(%p)\n", h);
197 }
198
199 int _d_monitor_lock(Object *h)
200 {
201 //printf("+_d_monitor_acquire(%p)\n", h);
202 assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
203 pthread_mutex_lock(MONPTR(h));
204 //printf("-_d_monitor_acquire(%p)\n", h);
205 }
206
207 void _d_monitor_unlock(Object *h)
208 {
209 //printf("+_d_monitor_release(%p)\n", h);
210 assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
211 pthread_mutex_unlock(MONPTR(h));
212 //printf("-_d_monitor_release(%p)\n", h);
213 }
214
215 #endif