1 // D programming language runtime library
3 // written by Walter Bright, Digital Mars
6 // This is written in C because nobody has written a pthreads interface
16 #define USE_PTHREADS 1
30 // This is what the monitor reference in Object points to
31 typedef struct Monitor
33 void* impl; // for user-level monitors
34 Array devt; // for internal monitors
45 #define MONPTR(h) (&((Monitor *)(h)->monitor)->mon)
47 static volatile int inited;
49 /* =============================== Win32 ============================ */
53 static CRITICAL_SECTION _monitor_critsec;
55 void _STI_monitor_staticctor()
58 { InitializeCriticalSection(&_monitor_critsec);
63 void _STD_monitor_staticdtor()
67 DeleteCriticalSection(&_monitor_critsec);
71 void _d_monitor_create(Object *h)
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.
80 //printf("+_d_monitor_create(%p)\n", h);
83 EnterCriticalSection(&_monitor_critsec);
86 cs = (Monitor *)calloc(sizeof(Monitor), 1);
88 InitializeCriticalSection(&cs->mon);
89 h->monitor = (void *)cs;
92 LeaveCriticalSection(&_monitor_critsec);
95 //printf("-_d_monitor_create(%p)\n", h);
98 void _d_monitor_destroy(Object *h)
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);
105 //printf("-_d_monitor_destroy(%p)\n", h);
108 int _d_monitor_lock(Object *h)
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);
116 void _d_monitor_unlock(Object *h)
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);
126 /* =============================== linux ============================ */
130 // Includes attribute fixes from David Friedman's GDC port
132 static pthread_mutex_t _monitor_critsec;
133 static pthread_mutexattr_t _monitors_attr;
135 void _STI_monitor_staticctor()
139 pthread_mutexattr_init(&_monitors_attr);
140 pthread_mutexattr_settype(&_monitors_attr, PTHREAD_MUTEX_RECURSIVE_NP);
141 pthread_mutex_init(&_monitor_critsec, 0);
146 void _STD_monitor_staticdtor()
150 pthread_mutex_destroy(&_monitor_critsec);
151 pthread_mutexattr_destroy(&_monitors_attr);
155 void _d_monitor_create(Object *h)
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.
164 //printf("+_d_monitor_create(%p)\n", h);
167 pthread_mutex_lock(&_monitor_critsec);
170 cs = (Monitor *)calloc(sizeof(Monitor), 1);
172 pthread_mutex_init(&cs->mon, & _monitors_attr);
173 h->monitor = (void *)cs;
176 pthread_mutex_unlock(&_monitor_critsec);
179 //printf("-_d_monitor_create(%p)\n", h);
182 void _d_monitor_destroy(Object *h)
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);
189 //printf("-_d_monitor_destroy(%p)\n", h);
192 int _d_monitor_lock(Object *h)
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);
200 void _d_monitor_unlock(Object *h)
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);