Wiki Roadmap Timeline Tickets New Ticket Source Search Help / Guide About Trac Login

root/runtime/internal/monitor.c

Revision 872:aa953cc960b6, 4.9 kB (checked in by Christian Kamm <kamm incasoftware de>, 3 years ago)

Apply BlueZeniX's patch for OpenSolaris? compatibility. Fixes #158.

Line 
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 || __APPLE__ || (defined (__SVR4) && defined (__sun))
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 #if !linux
131 #define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
132 #endif
133
134 // Includes attribute fixes from David Friedman's GDC port
135
136 static pthread_mutex_t _monitor_critsec;
137 static pthread_mutexattr_t _monitors_attr;
138
139 void _STI_monitor_staticctor()
140 {
141     if (!inited)
142     {
143     pthread_mutexattr_init(&_monitors_attr);
144     pthread_mutexattr_settype(&_monitors_attr, PTHREAD_MUTEX_RECURSIVE_NP);
145     pthread_mutex_init(&_monitor_critsec, 0);
146     inited = 1;
147     }
148 }
149
150 void _STD_monitor_staticdtor()
151 {
152     if (inited)
153     {   inited = 0;
154     pthread_mutex_destroy(&_monitor_critsec);
155     pthread_mutexattr_destroy(&_monitors_attr);
156     }
157 }
158
159 void _d_monitor_create(Object *h)
160 {
161     /*
162      * NOTE: Assume this is only called when h->monitor is null prior to the
163      * call.  However, please note that another thread may call this function
164      * at the same time, so we can not assert this here.  Instead, try and
165      * create a lock, and if one already exists then forget about it.
166      */
167
168     //printf("+_d_monitor_create(%p)\n", h);
169     assert(h);
170     Monitor *cs = NULL;
171     pthread_mutex_lock(&_monitor_critsec);
172     if (!h->monitor)
173     {
174         cs = (Monitor *)calloc(sizeof(Monitor), 1);
175         assert(cs);
176         pthread_mutex_init(&cs->mon, & _monitors_attr);
177         h->monitor = (void *)cs;
178         cs = NULL;
179     }
180     pthread_mutex_unlock(&_monitor_critsec);
181     if (cs)
182         free(cs);
183     //printf("-_d_monitor_create(%p)\n", h);
184 }
185
186 void _d_monitor_destroy(Object *h)
187 {
188     //printf("+_d_monitor_destroy(%p)\n", h);
189     assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
190     pthread_mutex_destroy(MONPTR(h));
191     free((void *)h->monitor);
192     h->monitor = NULL;
193     //printf("-_d_monitor_destroy(%p)\n", h);
194 }
195
196 int _d_monitor_lock(Object *h)
197 {
198     //printf("+_d_monitor_acquire(%p)\n", h);
199     assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
200     pthread_mutex_lock(MONPTR(h));
201     //printf("-_d_monitor_acquire(%p)\n", h);
202 }
203
204 void _d_monitor_unlock(Object *h)
205 {
206     //printf("+_d_monitor_release(%p)\n", h);
207     assert(h && h->monitor && !(((Monitor*)h->monitor)->impl));
208     pthread_mutex_unlock(MONPTR(h));
209     //printf("-_d_monitor_release(%p)\n", h);
210 }
211
212 #endif
Note: See TracBrowser for help on using the browser.
Copyright © 2008, LDC Development Team.