comparison druntime/src/compiler/ldc/critical.c @ 759:d3eb054172f9

Added copy of druntime from DMD 2.020 modified for LDC.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 11 Nov 2008 01:52:37 +0100
parents
children
comparison
equal deleted inserted replaced
758:f04dde6e882c 759:d3eb054172f9
1 /*
2 * Placed into the Public Domain
3 * written by Walter Bright, Digital Mars
4 * www.digitalmars.com
5 */
6
7 /* ================================= Win32 ============================ */
8
9 #if _WIN32
10
11 #include <windows.h>
12
13 /******************************************
14 * Enter/exit critical section.
15 */
16
17 /* We don't initialize critical sections unless we actually need them.
18 * So keep a linked list of the ones we do use, and in the static destructor
19 * code, walk the list and release them.
20 */
21
22 typedef struct D_CRITICAL_SECTION
23 {
24 struct D_CRITICAL_SECTION *next;
25 CRITICAL_SECTION cs;
26 } D_CRITICAL_SECTION;
27
28 static D_CRITICAL_SECTION *dcs_list;
29 static D_CRITICAL_SECTION critical_section;
30 static volatile int inited;
31
32 void _d_criticalenter(D_CRITICAL_SECTION *dcs)
33 {
34 if (!dcs->next)
35 {
36 EnterCriticalSection(&critical_section.cs);
37 if (!dcs->next) // if, in the meantime, another thread didn't set it
38 {
39 dcs->next = dcs_list;
40 dcs_list = dcs;
41 InitializeCriticalSection(&dcs->cs);
42 }
43 LeaveCriticalSection(&critical_section.cs);
44 }
45 EnterCriticalSection(&dcs->cs);
46 }
47
48 void _d_criticalexit(D_CRITICAL_SECTION *dcs)
49 {
50 LeaveCriticalSection(&dcs->cs);
51 }
52
53 void _STI_critical_init()
54 {
55 if (!inited)
56 { InitializeCriticalSection(&critical_section.cs);
57 dcs_list = &critical_section;
58 inited = 1;
59 }
60 }
61
62 void _STD_critical_term()
63 {
64 if (inited)
65 { inited = 0;
66 while (dcs_list)
67 {
68 DeleteCriticalSection(&dcs_list->cs);
69 dcs_list = dcs_list->next;
70 }
71 }
72 }
73
74 #endif
75
76 /* ================================= linux ============================ */
77
78 #if linux || __APPLE__ || __FreeBSD__
79
80 #include <stdio.h>
81 #include <stdlib.h>
82 #include <pthread.h>
83
84 #if !linux
85 #define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
86 #endif
87
88 /******************************************
89 * Enter/exit critical section.
90 */
91
92 /* We don't initialize critical sections unless we actually need them.
93 * So keep a linked list of the ones we do use, and in the static destructor
94 * code, walk the list and release them.
95 */
96
97 typedef struct D_CRITICAL_SECTION
98 {
99 struct D_CRITICAL_SECTION *next;
100 pthread_mutex_t cs;
101 } D_CRITICAL_SECTION;
102
103 static D_CRITICAL_SECTION *dcs_list;
104 static D_CRITICAL_SECTION critical_section;
105 static pthread_mutexattr_t _criticals_attr;
106
107 void _STI_critical_init(void);
108 void _STD_critical_term(void);
109
110 void _d_criticalenter(D_CRITICAL_SECTION *dcs)
111 {
112 if (!dcs_list)
113 { _STI_critical_init();
114 atexit(_STD_critical_term);
115 }
116 //printf("_d_criticalenter(dcs = x%x)\n", dcs);
117 if (!dcs->next)
118 {
119 pthread_mutex_lock(&critical_section.cs);
120 if (!dcs->next) // if, in the meantime, another thread didn't set it
121 {
122 dcs->next = dcs_list;
123 dcs_list = dcs;
124 pthread_mutex_init(&dcs->cs, &_criticals_attr);
125 }
126 pthread_mutex_unlock(&critical_section.cs);
127 }
128 pthread_mutex_lock(&dcs->cs);
129 }
130
131 void _d_criticalexit(D_CRITICAL_SECTION *dcs)
132 {
133 //printf("_d_criticalexit(dcs = x%x)\n", dcs);
134 pthread_mutex_unlock(&dcs->cs);
135 }
136
137 void _STI_critical_init()
138 {
139 if (!dcs_list)
140 { //printf("_STI_critical_init()\n");
141 pthread_mutexattr_init(&_criticals_attr);
142 pthread_mutexattr_settype(&_criticals_attr, PTHREAD_MUTEX_RECURSIVE_NP);
143
144 // The global critical section doesn't need to be recursive
145 pthread_mutex_init(&critical_section.cs, 0);
146 dcs_list = &critical_section;
147 }
148 }
149
150 void _STD_critical_term()
151 {
152 if (dcs_list)
153 { //printf("_STI_critical_term()\n");
154 while (dcs_list)
155 {
156 //printf("\tlooping... %x\n", dcs_list);
157 pthread_mutex_destroy(&dcs_list->cs);
158 dcs_list = dcs_list->next;
159 }
160 }
161 }
162
163 #endif
164