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