2 * Placed into the Public Domain
3 * written by Walter Bright, Digital Mars
7 /* ================================= Win32 ============================ */
13 /******************************************
14 * Enter/exit critical section.
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.
22 typedef struct D_CRITICAL_SECTION
24 struct D_CRITICAL_SECTION *next;
28 static D_CRITICAL_SECTION *dcs_list;
29 static D_CRITICAL_SECTION critical_section;
30 static volatile int inited;
32 void _d_criticalenter(D_CRITICAL_SECTION *dcs)
36 EnterCriticalSection(&critical_section.cs);
37 if (!dcs->next) // if, in the meantime, another thread didn't set it
41 InitializeCriticalSection(&dcs->cs);
43 LeaveCriticalSection(&critical_section.cs);
45 EnterCriticalSection(&dcs->cs);
48 void _d_criticalexit(D_CRITICAL_SECTION *dcs)
50 LeaveCriticalSection(&dcs->cs);
53 void _STI_critical_init()
56 { InitializeCriticalSection(&critical_section.cs);
57 dcs_list = &critical_section;
62 void _STD_critical_term()
68 DeleteCriticalSection(&dcs_list->cs);
69 dcs_list = dcs_list->next;
76 /* ================================= linux ============================ */
84 /******************************************
85 * Enter/exit critical section.
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.
93 typedef struct D_CRITICAL_SECTION
95 struct D_CRITICAL_SECTION *next;
99 static D_CRITICAL_SECTION *dcs_list;
100 static D_CRITICAL_SECTION critical_section;
101 static pthread_mutexattr_t _criticals_attr;
103 void _STI_critical_init(void);
104 void _STD_critical_term(void);
106 void _d_criticalenter(D_CRITICAL_SECTION *dcs)
109 { _STI_critical_init();
110 atexit(_STD_critical_term);
112 //printf("_d_criticalenter(dcs = x%x)\n", dcs);
115 pthread_mutex_lock(&critical_section.cs);
116 if (!dcs->next) // if, in the meantime, another thread didn't set it
118 dcs->next = dcs_list;
120 pthread_mutex_init(&dcs->cs, &_criticals_attr);
122 pthread_mutex_unlock(&critical_section.cs);
124 pthread_mutex_lock(&dcs->cs);
127 void _d_criticalexit(D_CRITICAL_SECTION *dcs)
129 //printf("_d_criticalexit(dcs = x%x)\n", dcs);
130 pthread_mutex_unlock(&dcs->cs);
133 void _STI_critical_init()
136 { //printf("_STI_critical_init()\n");
137 pthread_mutexattr_init(&_criticals_attr);
138 pthread_mutexattr_settype(&_criticals_attr, PTHREAD_MUTEX_RECURSIVE_NP);
140 // The global critical section doesn't need to be recursive
141 pthread_mutex_init(&critical_section.cs, 0);
142 dcs_list = &critical_section;
146 void _STD_critical_term()
149 { //printf("_STI_critical_term()\n");
152 //printf("\tlooping... %x\n", dcs_list);
153 pthread_mutex_destroy(&dcs_list->cs);
154 dcs_list = dcs_list->next;