2 * critical-sections.c: Critical sections
5 * Dick Porter (dick@ximian.com)
7 * (C) 2002 Ximian, Inc.
14 #include "mono/io-layer/wapi.h"
16 #include "mono-mutex.h"
20 /* A critical section is really just like a lightweight mutex. It
21 * can't be waited for, and doesn't have a handle.
24 /* According to the MSDN docs, the Microsoft implementation spins a
25 * number of times then waits for a semaphore. I could implement that
26 * here but I'd need a mutex around the critical section structure
27 * anyway. So I may as well just use a pthread mutex.
29 static mono_once_t attr_key_once=MONO_ONCE_INIT;
30 static mono_mutexattr_t attr;
32 static void attr_init(void)
36 ret = mono_mutexattr_init(&attr);
39 ret = mono_mutexattr_settype(&attr, MONO_MUTEX_RECURSIVE);
44 * InitializeCriticalSection:
45 * @section: The critical section to initialise
47 * Initialises a critical section.
49 void InitializeCriticalSection(WapiCriticalSection *section)
53 mono_once(&attr_key_once, attr_init);
54 ret = mono_mutex_init(§ion->mutex, &attr);
59 * InitializeCriticalSectionAndSpinCount:
60 * @section: The critical section to initialise.
61 * @spincount: The spin count for this critical section. Not
64 * Initialises a critical section and sets the spin count. This
65 * implementation just calls InitializeCriticalSection().
67 * Return value: %TRUE on success, %FALSE otherwise. (%FALSE never
70 gboolean InitializeCriticalSectionAndSpinCount(WapiCriticalSection *section,
71 guint32 spincount G_GNUC_UNUSED)
73 InitializeCriticalSection(section);
79 * DeleteCriticalSection:
80 * @section: The critical section to delete.
82 * Releases all resources owned by critical section @section.
84 void DeleteCriticalSection(WapiCriticalSection *section)
88 ret = mono_mutex_destroy(§ion->mutex);
93 * SetCriticalSectionSpinCount:
94 * @section: The critical section to set
95 * @spincount: The new spin count for this critical section. Not
98 * Sets the spin count for the critical section @section. The spin
99 * count is currently ignored, and set to zero.
101 * Return value: The previous spin count. (Currently always zero).
103 guint32 SetCriticalSectionSpinCount(WapiCriticalSection *section G_GNUC_UNUSED, guint32 spincount G_GNUC_UNUSED)
109 * TryEnterCriticalSection:
110 * @section: The critical section to try and enter
112 * Attempts to enter a critical section without blocking. If
113 * successful the calling thread takes ownership of the critical
116 * A thread can recursively call EnterCriticalSection() and
117 * TryEnterCriticalSection(), but must call LeaveCriticalSection() an
118 * equal number of times.
120 * Return value: %TRUE if the thread successfully locked the critical
121 * section, %FALSE otherwise.
123 gboolean TryEnterCriticalSection(WapiCriticalSection *section)
127 ret=mono_mutex_trylock(§ion->mutex);
136 * EnterCriticalSection:
137 * @section: The critical section to enter
139 * Enters critical section @section, blocking while other threads own
140 * it. This function doesn't return until the calling thread assumes
141 * ownership of @section.
143 * A thread can recursively call EnterCriticalSection() and
144 * TryEnterCriticalSection(), but must call LeaveCriticalSection() an
145 * equal number of times.
147 void EnterCriticalSection(WapiCriticalSection *section)
151 if ((stat = mono_mutex_lock(§ion->mutex)) != 0) {
152 g_error (G_GNUC_PRETTY_FUNCTION
153 ": EnterCriticalSection failed: %s", g_strerror(stat));
158 * LeaveCriticalSection:
159 * @section: The critical section to leave
161 * Leaves critical section @section, relinquishing ownership.
163 * A thread can recursively call EnterCriticalSection() and
164 * TryEnterCriticalSection(), but must call LeaveCriticalSection() an
165 * equal number of times.
167 void LeaveCriticalSection(WapiCriticalSection *section)
171 ret = mono_mutex_unlock(§ion->mutex);