comparison runtime/internal/monitor.c @ 443:44f08170f4ef

Removed tango from the repository and instead added a runtime dir with the files needed to patch and build tango from svn. Reworked the LLVMDC specific pragmas.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Fri, 01 Aug 2008 00:32:06 +0200
parents
children f478666f5b96
comparison
equal deleted inserted replaced
442:76078c8ab5b9 443:44f08170f4ef
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 Array devt; // for internal monitors
35
36 #if _WIN32
37 CRITICAL_SECTION mon;
38 #endif
39
40 #if USE_PTHREADS
41 pthread_mutex_t mon;
42 #endif
43 } Monitor;
44
45 #define MONPTR(h) (&((Monitor *)(h)->monitor)->mon)
46
47 static volatile int inited;
48
49 /* =============================== Win32 ============================ */
50
51 #if _WIN32
52
53 static CRITICAL_SECTION _monitor_critsec;
54
55 void _STI_monitor_staticctor()
56 {
57 if (!inited)
58 { InitializeCriticalSection(&_monitor_critsec);
59 inited = 1;
60 }
61 }
62
63 void _STD_monitor_staticdtor()
64 {
65 if (inited)
66 { inited = 0;
67 DeleteCriticalSection(&_monitor_critsec);
68 }
69 }
70
71 void _d_monitor_create(Object *h)
72 {
73 /*
74 * NOTE: Assume this is only called when h->monitor is null prior to the
75 * call. However, please note that another thread may call this function
76 * at the same time, so we can not assert this here. Instead, try and
77 * create a lock, and if one already exists then forget about it.
78 */
79
80 //printf("+_d_monitor_create(%p)\n", h);
81 assert(h);
82 Monitor *cs = NULL;
83 EnterCriticalSection(&_monitor_critsec);
84 if (!h->monitor)
85 {
86 cs = (Monitor *)calloc(sizeof(Monitor), 1);
87 assert(cs);
88 InitializeCriticalSection(&cs->mon);
89 h->monitor = (void *)cs;
90 cs = NULL;
91 }
92 LeaveCriticalSection(&_monitor_critsec);
93 if (cs)
94 free(cs);
95 //printf("-_d_monitor_create(%p)\n", h);
96 }
97
98 void _d_monitor_destroy(Object *h)
99 {
100 //printf("+_d_monitor_destroy(%p)\n", h);
101 assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
102 DeleteCriticalSection(MONPTR(h));
103 free((void *)h->monitor);
104 h->monitor = NULL;
105 //printf("-_d_monitor_destroy(%p)\n", h);
106 }
107
108 int _d_monitor_lock(Object *h)
109 {
110 //printf("+_d_monitor_acquire(%p)\n", h);
111 assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
112 EnterCriticalSection(MONPTR(h));
113 //printf("-_d_monitor_acquire(%p)\n", h);
114 }
115
116 void _d_monitor_unlock(Object *h)
117 {
118 //printf("+_d_monitor_release(%p)\n", h);
119 assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
120 LeaveCriticalSection(MONPTR(h));
121 //printf("-_d_monitor_release(%p)\n", h);
122 }
123
124 #endif
125
126 /* =============================== linux ============================ */
127
128 #if USE_PTHREADS
129
130 // Includes attribute fixes from David Friedman's GDC port
131
132 static pthread_mutex_t _monitor_critsec;
133 static pthread_mutexattr_t _monitors_attr;
134
135 void _STI_monitor_staticctor()
136 {
137 if (!inited)
138 {
139 pthread_mutexattr_init(&_monitors_attr);
140 pthread_mutexattr_settype(&_monitors_attr, PTHREAD_MUTEX_RECURSIVE_NP);
141 pthread_mutex_init(&_monitor_critsec, 0);
142 inited = 1;
143 }
144 }
145
146 void _STD_monitor_staticdtor()
147 {
148 if (inited)
149 { inited = 0;
150 pthread_mutex_destroy(&_monitor_critsec);
151 pthread_mutexattr_destroy(&_monitors_attr);
152 }
153 }
154
155 void _d_monitor_create(Object *h)
156 {
157 /*
158 * NOTE: Assume this is only called when h->monitor is null prior to the
159 * call. However, please note that another thread may call this function
160 * at the same time, so we can not assert this here. Instead, try and
161 * create a lock, and if one already exists then forget about it.
162 */
163
164 //printf("+_d_monitor_create(%p)\n", h);
165 assert(h);
166 Monitor *cs = NULL;
167 pthread_mutex_lock(&_monitor_critsec);
168 if (!h->monitor)
169 {
170 cs = (Monitor *)calloc(sizeof(Monitor), 1);
171 assert(cs);
172 pthread_mutex_init(&cs->mon, & _monitors_attr);
173 h->monitor = (void *)cs;
174 cs = NULL;
175 }
176 pthread_mutex_unlock(&_monitor_critsec);
177 if (cs)
178 free(cs);
179 //printf("-_d_monitor_create(%p)\n", h);
180 }
181
182 void _d_monitor_destroy(Object *h)
183 {
184 //printf("+_d_monitor_destroy(%p)\n", h);
185 assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
186 pthread_mutex_destroy(MONPTR(h));
187 free((void *)h->monitor);
188 h->monitor = NULL;
189 //printf("-_d_monitor_destroy(%p)\n", h);
190 }
191
192 int _d_monitor_lock(Object *h)
193 {
194 //printf("+_d_monitor_acquire(%p)\n", h);
195 assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
196 pthread_mutex_lock(MONPTR(h));
197 //printf("-_d_monitor_acquire(%p)\n", h);
198 }
199
200 void _d_monitor_unlock(Object *h)
201 {
202 //printf("+_d_monitor_release(%p)\n", h);
203 assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
204 pthread_mutex_unlock(MONPTR(h));
205 //printf("-_d_monitor_release(%p)\n", h);
206 }
207
208 #endif