comparison tango/lib/compiler/llvmdc/critical.c @ 133:44a95ac7368a trunk

[svn r137] Many fixes towards tango.io.Console working, but not quite there yet... In particular, assertions has been fixed to include file/line info, and much more!
author lindquist
date Mon, 14 Jan 2008 05:11:54 +0100
parents
children
comparison
equal deleted inserted replaced
132:1700239cab2e 133:44a95ac7368a
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