Mercurial > projects > ldc
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 |