xref: /netbsd-src/external/gpl3/gcc.old/dist/libstdc++-v3/include/parallel/compatibility.h (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
136ac495dSmrg // -*- C++ -*-
236ac495dSmrg 
3*8feb0f0bSmrg // Copyright (C) 2007-2020 Free Software Foundation, Inc.
436ac495dSmrg //
536ac495dSmrg // This file is part of the GNU ISO C++ Library.  This library is free
636ac495dSmrg // software; you can redistribute it and/or modify it under the terms
736ac495dSmrg // of the GNU General Public License as published by the Free Software
836ac495dSmrg // Foundation; either version 3, or (at your option) any later
936ac495dSmrg // version.
1036ac495dSmrg 
1136ac495dSmrg // This library is distributed in the hope that it will be useful, but
1236ac495dSmrg // WITHOUT ANY WARRANTY; without even the implied warranty of
1336ac495dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1436ac495dSmrg // General Public License for more details.
1536ac495dSmrg 
1636ac495dSmrg // Under Section 7 of GPL version 3, you are granted additional
1736ac495dSmrg // permissions described in the GCC Runtime Library Exception, version
1836ac495dSmrg // 3.1, as published by the Free Software Foundation.
1936ac495dSmrg 
2036ac495dSmrg // You should have received a copy of the GNU General Public License and
2136ac495dSmrg // a copy of the GCC Runtime Library Exception along with this program;
2236ac495dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2336ac495dSmrg // <http://www.gnu.org/licenses/>.
2436ac495dSmrg 
2536ac495dSmrg /** @file parallel/compatibility.h
2636ac495dSmrg  *  @brief Compatibility layer, mostly concerned with atomic operations.
2736ac495dSmrg  *
2836ac495dSmrg  *  This file is a GNU parallel extension to the Standard C++ Library
2936ac495dSmrg  *  and contains implementation details for the library's internal use.
3036ac495dSmrg  */
3136ac495dSmrg 
3236ac495dSmrg // Written by Felix Putze.
3336ac495dSmrg 
3436ac495dSmrg #ifndef _GLIBCXX_PARALLEL_COMPATIBILITY_H
3536ac495dSmrg #define _GLIBCXX_PARALLEL_COMPATIBILITY_H 1
3636ac495dSmrg 
3736ac495dSmrg #include <parallel/types.h>
3836ac495dSmrg #include <parallel/base.h>
3936ac495dSmrg 
4036ac495dSmrg #if !defined(_WIN32) || defined (__CYGWIN__)
4136ac495dSmrg #include <sched.h>
4236ac495dSmrg #endif
4336ac495dSmrg 
4436ac495dSmrg #ifdef __MINGW32__
4536ac495dSmrg // Including <windows.h> will drag in all the windows32 names.  Since
4636ac495dSmrg // that can cause user code portability problems, we just declare the
4736ac495dSmrg // one needed function here.
4836ac495dSmrg extern "C"
4936ac495dSmrg __attribute((dllimport)) void __attribute__((stdcall)) Sleep (unsigned long);
5036ac495dSmrg #endif
5136ac495dSmrg 
5236ac495dSmrg namespace __gnu_parallel
5336ac495dSmrg {
5436ac495dSmrg   template<typename _Tp>
5536ac495dSmrg     inline _Tp
__add_omp(volatile _Tp * __ptr,_Tp __addend)5636ac495dSmrg     __add_omp(volatile _Tp* __ptr, _Tp __addend)
5736ac495dSmrg     {
5836ac495dSmrg       int64_t __res;
5936ac495dSmrg #pragma omp critical
6036ac495dSmrg       {
6136ac495dSmrg 	__res = *__ptr;
6236ac495dSmrg 	*(__ptr) += __addend;
6336ac495dSmrg       }
6436ac495dSmrg       return __res;
6536ac495dSmrg     }
6636ac495dSmrg 
6736ac495dSmrg   /** @brief Add a value to a variable, atomically.
6836ac495dSmrg    *
6936ac495dSmrg    *  @param __ptr Pointer to a signed integer.
7036ac495dSmrg    *  @param __addend Value to add.
7136ac495dSmrg    */
7236ac495dSmrg   template<typename _Tp>
7336ac495dSmrg     inline _Tp
__fetch_and_add(volatile _Tp * __ptr,_Tp __addend)7436ac495dSmrg     __fetch_and_add(volatile _Tp* __ptr, _Tp __addend)
7536ac495dSmrg     {
7636ac495dSmrg       if (__atomic_always_lock_free(sizeof(_Tp), __ptr))
7736ac495dSmrg 	return __atomic_fetch_add(__ptr, __addend, __ATOMIC_ACQ_REL);
7836ac495dSmrg       return __add_omp(__ptr, __addend);
7936ac495dSmrg     }
8036ac495dSmrg 
8136ac495dSmrg   template<typename _Tp>
8236ac495dSmrg     inline bool
__cas_omp(volatile _Tp * __ptr,_Tp __comparand,_Tp __replacement)8336ac495dSmrg     __cas_omp(volatile _Tp* __ptr, _Tp __comparand, _Tp __replacement)
8436ac495dSmrg     {
8536ac495dSmrg       bool __res = false;
8636ac495dSmrg #pragma omp critical
8736ac495dSmrg       {
8836ac495dSmrg 	if (*__ptr == __comparand)
8936ac495dSmrg 	  {
9036ac495dSmrg 	    *__ptr = __replacement;
9136ac495dSmrg 	    __res = true;
9236ac495dSmrg 	  }
9336ac495dSmrg       }
9436ac495dSmrg       return __res;
9536ac495dSmrg     }
9636ac495dSmrg 
9736ac495dSmrg   /** @brief Compare-and-swap
9836ac495dSmrg    *
9936ac495dSmrg    * Compare @c *__ptr and @c __comparand. If equal, let @c
10036ac495dSmrg    * *__ptr=__replacement and return @c true, return @c false otherwise.
10136ac495dSmrg    *
10236ac495dSmrg    *  @param __ptr Pointer to signed integer.
10336ac495dSmrg    *  @param __comparand Compare value.
10436ac495dSmrg    *  @param __replacement Replacement value.
10536ac495dSmrg    */
10636ac495dSmrg   template<typename _Tp>
10736ac495dSmrg     inline bool
__compare_and_swap(volatile _Tp * __ptr,_Tp __comparand,_Tp __replacement)10836ac495dSmrg     __compare_and_swap(volatile _Tp* __ptr, _Tp __comparand, _Tp __replacement)
10936ac495dSmrg     {
11036ac495dSmrg       if (__atomic_always_lock_free(sizeof(_Tp), __ptr))
11136ac495dSmrg 	return __atomic_compare_exchange_n(__ptr, &__comparand, __replacement,
11236ac495dSmrg 					   false, __ATOMIC_ACQ_REL,
11336ac495dSmrg 					   __ATOMIC_RELAXED);
11436ac495dSmrg       return __cas_omp(__ptr, __comparand, __replacement);
11536ac495dSmrg     }
11636ac495dSmrg 
11736ac495dSmrg   /** @brief Yield control to another thread, without waiting for
11836ac495dSmrg    *  the end of the time slice.
11936ac495dSmrg    */
12036ac495dSmrg   inline void
__yield()12136ac495dSmrg   __yield()
12236ac495dSmrg   {
12336ac495dSmrg #if defined (_WIN32) && !defined (__CYGWIN__)
12436ac495dSmrg     Sleep(0);
12536ac495dSmrg #else
12636ac495dSmrg     sched_yield();
12736ac495dSmrg #endif
12836ac495dSmrg   }
12936ac495dSmrg } // end namespace
13036ac495dSmrg 
13136ac495dSmrg #endif /* _GLIBCXX_PARALLEL_COMPATIBILITY_H */
132