Mercurial > projects > ldc
comparison runtime/internal/critical.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 | 02fb65cddc3e |
comparison
equal
deleted
inserted
replaced
442:76078c8ab5b9 | 443:44f08170f4ef |
---|---|
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 | |
79 | |
80 #include <stdio.h> | |
81 #include <stdlib.h> | |
82 #include <pthread.h> | |
83 | |
84 /****************************************** | |
85 * Enter/exit critical section. | |
86 */ | |
87 | |
88 /* We don't initialize critical sections unless we actually need them. | |
89 * So keep a linked list of the ones we do use, and in the static destructor | |
90 * code, walk the list and release them. | |
91 */ | |
92 | |
93 typedef struct D_CRITICAL_SECTION | |
94 { | |
95 struct D_CRITICAL_SECTION *next; | |
96 pthread_mutex_t cs; | |
97 } D_CRITICAL_SECTION; | |
98 | |
99 static D_CRITICAL_SECTION *dcs_list; | |
100 static D_CRITICAL_SECTION critical_section; | |
101 static pthread_mutexattr_t _criticals_attr; | |
102 | |
103 void _STI_critical_init(void); | |
104 void _STD_critical_term(void); | |
105 | |
106 void _d_criticalenter(D_CRITICAL_SECTION *dcs) | |
107 { | |
108 if (!dcs_list) | |
109 { _STI_critical_init(); | |
110 atexit(_STD_critical_term); | |
111 } | |
112 //printf("_d_criticalenter(dcs = x%x)\n", dcs); | |
113 if (!dcs->next) | |
114 { | |
115 pthread_mutex_lock(&critical_section.cs); | |
116 if (!dcs->next) // if, in the meantime, another thread didn't set it | |
117 { | |
118 dcs->next = dcs_list; | |
119 dcs_list = dcs; | |
120 pthread_mutex_init(&dcs->cs, &_criticals_attr); | |
121 } | |
122 pthread_mutex_unlock(&critical_section.cs); | |
123 } | |
124 pthread_mutex_lock(&dcs->cs); | |
125 } | |
126 | |
127 void _d_criticalexit(D_CRITICAL_SECTION *dcs) | |
128 { | |
129 //printf("_d_criticalexit(dcs = x%x)\n", dcs); | |
130 pthread_mutex_unlock(&dcs->cs); | |
131 } | |
132 | |
133 void _STI_critical_init() | |
134 { | |
135 if (!dcs_list) | |
136 { //printf("_STI_critical_init()\n"); | |
137 pthread_mutexattr_init(&_criticals_attr); | |
138 pthread_mutexattr_settype(&_criticals_attr, PTHREAD_MUTEX_RECURSIVE_NP); | |
139 | |
140 // The global critical section doesn't need to be recursive | |
141 pthread_mutex_init(&critical_section.cs, 0); | |
142 dcs_list = &critical_section; | |
143 } | |
144 } | |
145 | |
146 void _STD_critical_term() | |
147 { | |
148 if (dcs_list) | |
149 { //printf("_STI_critical_term()\n"); | |
150 while (dcs_list) | |
151 { | |
152 //printf("\tlooping... %x\n", dcs_list); | |
153 pthread_mutex_destroy(&dcs_list->cs); | |
154 dcs_list = dcs_list->next; | |
155 } | |
156 } | |
157 } | |
158 | |
159 #endif | |
160 |