[AArch64] Add STP pattern to store a vec_concat of two 64-bit registers
[official-gcc.git] / libcilkrts / runtime / os_mutex-unix.c
blobe0f058eb4a9ebedea2b4bdfa5174d7e2ec48bbda
1 /* os_mutex-unix.c -*-C-*-
3 *************************************************************************
5 * Copyright (C) 2009-2016, Intel Corporation
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 * * Neither the name of Intel Corporation nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
29 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
32 * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
35 * *********************************************************************
37 * PLEASE NOTE: This file is a downstream copy of a file mainitained in
38 * a repository at cilkplus.org. Changes made to this file that are not
39 * submitted through the contribution process detailed at
40 * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
41 * time that a new version is released. Changes only submitted to the
42 * GNU compiler collection or posted to the git repository at
43 * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
44 * not tracked.
46 * We welcome your contributions to this open source project. Thank you
47 * for your assistance in helping us improve Cilk Plus.
48 **************************************************************************/
50 #include "os_mutex.h"
51 #include "bug.h"
53 #include <stdlib.h>
54 #include <errno.h>
55 #include <pthread.h>
57 // contains notification macros for VTune.
58 #include "cilk-ittnotify.h"
61 * OS Mutex functions.
63 * Not to be confused with the spinlock mutexes implemented in cilk_mutex.c
66 struct os_mutex {
67 pthread_mutex_t mutex; ///< On Linux, os_mutex is implemented with a pthreads mutex
70 // Unix implementation of the global OS mutex. This will be created by the
71 // first call to global_os_mutex_lock() and *NEVER* destroyed. On gcc-based
72 // systems there's no way to guarantee the ordering of constructors and
73 // destructors, so we can't be guaranteed that our destructor for a static
74 // object will be called *after* any static destructors that may use Cilk
75 // in the user's application
76 static struct os_mutex *global_os_mutex = NULL;
78 /* Sometimes during shared library load malloc doesn't work.
79 To handle that case, preallocate space for one mutex. */
80 static struct os_mutex static_mutex;
81 static int static_mutex_used;
83 struct os_mutex *__cilkrts_os_mutex_create(void)
85 int status;
86 struct os_mutex *mutex = (struct os_mutex *)malloc(sizeof(struct os_mutex));
87 pthread_mutexattr_t attr;
89 ITT_SYNC_CREATE(mutex, "OS Mutex");
91 if (!mutex) {
92 if (static_mutex_used) {
93 __cilkrts_bug("Cilk RTS library initialization failed");
94 } else {
95 static_mutex_used = 1;
96 mutex = &static_mutex;
100 status = pthread_mutexattr_init(&attr);
101 CILK_ASSERT (status == 0);
102 #if defined DEBUG || CILK_LIB_DEBUG
103 #ifdef PTHREAD_MUTEX_ERRORCHECK
104 status = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
105 #else
106 status = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
107 #endif
108 CILK_ASSERT (status == 0);
109 #endif
110 status = pthread_mutex_init (&mutex->mutex, &attr);
111 CILK_ASSERT (status == 0);
112 pthread_mutexattr_destroy(&attr);
114 return mutex;
117 void __cilkrts_os_mutex_lock(struct os_mutex *p)
119 int status;
120 status = pthread_mutex_lock (&p->mutex);
121 ITT_SYNC_ACQUIRED(p);
122 if (__builtin_expect(status, 0) == 0)
123 return;
124 if (status == EDEADLK)
125 __cilkrts_bug("Cilk runtime error: deadlock acquiring mutex %p\n",
127 else
128 __cilkrts_bug("Cilk runtime error %d acquiring mutex %p\n",
129 status, p);
132 int __cilkrts_os_mutex_trylock(struct os_mutex *p)
134 int status;
135 status = pthread_mutex_trylock (&p->mutex);
136 return (status == 0);
139 void __cilkrts_os_mutex_unlock(struct os_mutex *p)
141 int status;
142 ITT_SYNC_RELEASING(p);
143 status = pthread_mutex_unlock (&p->mutex);
144 CILK_ASSERT(status == 0);
147 void __cilkrts_os_mutex_destroy(struct os_mutex *p)
149 pthread_mutex_destroy (&p->mutex);
150 if (p == &static_mutex) {
151 static_mutex_used = 0;
152 } else {
153 free(p);
158 * create_global_os_mutex
160 * Function used with pthread_once to initialize the global OS mutex. Since
161 * pthread_once requires a function which takes no parameters and has no
162 * return value, the global OS mutex will be stored in the static (global
163 * to the compilation unit) variable "global_os_mutex."
166 * global_os_mutex will never be destroyed.
168 static void create_global_os_mutex(void)
170 CILK_ASSERT(NULL == global_os_mutex);
171 global_os_mutex = __cilkrts_os_mutex_create();
174 void global_os_mutex_lock(void)
176 // pthread_once_t used with pthread_once to guarantee that
177 // create_global_os_mutex() is only called once
178 static pthread_once_t global_os_mutex_is_initialized = PTHREAD_ONCE_INIT;
180 // Execute create_global_os_mutex once in a thread-safe manner
181 // Note that create_global_os_mutex returns the mutex in the static
182 // (global to the module) variable "global_os_mutex"
183 pthread_once(&global_os_mutex_is_initialized,
184 create_global_os_mutex);
186 // We'd better have allocated a global_os_mutex
187 CILK_ASSERT(NULL != global_os_mutex);
189 // Acquire the global OS mutex
190 __cilkrts_os_mutex_lock(global_os_mutex);
193 void global_os_mutex_unlock(void)
195 // We'd better have allocated a global_os_mutex. This means you should
196 // have called global_os_mutex_lock() before calling
197 // global_os_mutex_unlock(), but this is the only check for it.
198 CILK_ASSERT(NULL != global_os_mutex);
200 // Release the global OS mutex
201 __cilkrts_os_mutex_unlock(global_os_mutex);
204 /* End os_mutex-unix.c */