Wiki Roadmap Timeline Tickets New Ticket Source Search Help / Guide About Trac Login

root/runtime/internal/critical.c

Revision 872:aa953cc960b6, 3.6 kB (checked in by Christian Kamm <kamm incasoftware de>, 3 years ago)

Apply BlueZeniX's patch for OpenSolaris? compatibility. Fixes #158.

Line 
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__ || (defined(__SVR4) && defined (__sun))
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
Note: See TracBrowser for help on using the browser.
Copyright © 2008, LDC Development Team.