config/linux/ptrlock.c

Go to the documentation of this file.
00001 /* Copyright (C) 2008, 2009 Free Software Foundation, Inc.
00002    Contributed by Jakub Jelinek <jakub@redhat.com>.
00003 
00004    This file is part of the GNU OpenMP Library (libgomp).
00005 
00006    Libgomp is free software; you can redistribute it and/or modify it
00007    under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 3, or (at your option)
00009    any later version.
00010 
00011    Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
00012    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00013    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
00014    more details.
00015 
00016    Under Section 7 of GPL version 3, you are granted additional
00017    permissions described in the GCC Runtime Library Exception, version
00018    3.1, as published by the Free Software Foundation.
00019 
00020    You should have received a copy of the GNU General Public License and
00021    a copy of the GCC Runtime Library Exception along with this program;
00022    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023    <http://www.gnu.org/licenses/>.  */
00024 
00025 /* This is a Linux specific implementation of a mutex synchronization
00026    mechanism for libgomp.  This type is private to the library.  This
00027    implementation uses atomic instructions and the futex syscall.  */
00028 
00029 #include <endian.h>
00030 #include <limits.h>
00031 #include "wait.h"
00032 
00033 void *
00034 gomp_ptrlock_get_slow (gomp_ptrlock_t *ptrlock)
00035 {
00036   int *intptr;
00037   __sync_bool_compare_and_swap (ptrlock, 1, 2);
00038 
00039   /* futex works on ints, not pointers.
00040      But a valid work share pointer will be at least
00041      8 byte aligned, so it is safe to assume the low
00042      32-bits of the pointer won't contain values 1 or 2.  */
00043   __asm volatile ("" : "=r" (intptr) : "0" (ptrlock));
00044 #if __BYTE_ORDER == __BIG_ENDIAN
00045   if (sizeof (*ptrlock) > sizeof (int))
00046     intptr += (sizeof (*ptrlock) / sizeof (int)) - 1;
00047 #endif
00048   do
00049     do_wait (intptr, 2);
00050   while (*intptr == 2);
00051   __asm volatile ("" : : : "memory");
00052   return *ptrlock;
00053 }
00054 
00055 void
00056 gomp_ptrlock_set_slow (gomp_ptrlock_t *ptrlock, void *ptr)
00057 {
00058   int *intptr;
00059 
00060   *ptrlock = ptr;
00061   __asm volatile ("" : "=r" (intptr) : "0" (ptrlock));
00062 #if __BYTE_ORDER == __BIG_ENDIAN
00063   if (sizeof (*ptrlock) > sizeof (int))
00064     intptr += (sizeof (*ptrlock) / sizeof (int)) - 1;
00065 #endif
00066   futex_wake (intptr, INT_MAX);
00067 }

Generated on Fri Apr 5 05:38:09 2013 for Libgomp by  doxygen 1.4.7