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 pthread_once_t attr_key_once=PTHREAD_ONCE_INIT;
30 static mono_mutexattr_t attr;
32 static void attr_init(void)
34 mono_mutexattr_init(&attr);
35 mono_mutexattr_settype(&attr, MONO_MUTEX_RECURSIVE);
39 * InitializeCriticalSection:
40 * @section: The critical section to initialise
42 * Initialises a critical section.
44 void InitializeCriticalSection(WapiCriticalSection *section)
46 pthread_once(&attr_key_once, attr_init);
47 mono_mutex_init(§ion->mutex, &attr);
51 * InitializeCriticalSectionAndSpinCount:
52 * @section: The critical section to initialise.
53 * @spincount: The spin count for this critical section. Not
56 * Initialises a critical section and sets the spin count. This
57 * implementation just calls InitializeCriticalSection().
59 * Return value: %TRUE on success, %FALSE otherwise. (%FALSE never
62 gboolean InitializeCriticalSectionAndSpinCount(WapiCriticalSection *section,
63 guint32 spincount G_GNUC_UNUSED)
65 InitializeCriticalSection(section);
71 * DeleteCriticalSection:
72 * @section: The critical section to delete.
74 * Releases all resources owned by critical section @section.
76 void DeleteCriticalSection(WapiCriticalSection *section)
78 mono_mutex_destroy(§ion->mutex);
82 * SetCriticalSectionSpinCount:
83 * @section: The critical section to set
84 * @spincount: The new spin count for this critical section. Not
87 * Sets the spin count for the critical section @section. The spin
88 * count is currently ignored, and set to zero.
90 * Return value: The previous spin count. (Currently always zero).
92 guint32 SetCriticalSectionSpinCount(WapiCriticalSection *section G_GNUC_UNUSED, guint32 spincount G_GNUC_UNUSED)
98 * TryEnterCriticalSection:
99 * @section: The critical section to try and enter
101 * Attempts to enter a critical section without blocking. If
102 * successful the calling thread takes ownership of the critical
105 * A thread can recursively call EnterCriticalSection() and
106 * TryEnterCriticalSection(), but must call LeaveCriticalSection() an
107 * equal number of times.
109 * Return value: %TRUE if the thread successfully locked the critical
110 * section, %FALSE otherwise.
112 gboolean TryEnterCriticalSection(WapiCriticalSection *section)
116 ret=mono_mutex_trylock(§ion->mutex);
125 * EnterCriticalSection:
126 * @section: The critical section to enter
128 * Enters critical section @section, blocking while other threads own
129 * it. This function doesn't return until the calling thread assumes
130 * ownership of @section.
132 * A thread can recursively call EnterCriticalSection() and
133 * TryEnterCriticalSection(), but must call LeaveCriticalSection() an
134 * equal number of times.
136 void EnterCriticalSection(WapiCriticalSection *section)
138 mono_mutex_lock(§ion->mutex);
142 * LeaveCriticalSection:
143 * @section: The critical section to leave
145 * Leaves critical section @section, relinquishing ownership.
147 * A thread can recursively call EnterCriticalSection() and
148 * TryEnterCriticalSection(), but must call LeaveCriticalSection() an
149 * equal number of times.
151 void LeaveCriticalSection(WapiCriticalSection *section)
153 mono_mutex_unlock(§ion->mutex);