1*0fc04c29Smrg /* Copyright (C) 2002-2019 Free Software Foundation, Inc.
210d565efSmrg    Contributed by Zack Weinberg <zack@codesourcery.com>
310d565efSmrg 
410d565efSmrg This file is part of GCC.
510d565efSmrg 
610d565efSmrg GCC is free software; you can redistribute it and/or modify it under
710d565efSmrg the terms of the GNU General Public License as published by the Free
810d565efSmrg Software Foundation; either version 3, or (at your option) any later
910d565efSmrg version.
1010d565efSmrg 
1110d565efSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1210d565efSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
1310d565efSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1410d565efSmrg for more details.
1510d565efSmrg 
1610d565efSmrg Under Section 7 of GPL version 3, you are granted additional
1710d565efSmrg permissions described in the GCC Runtime Library Exception, version
1810d565efSmrg 3.1, as published by the Free Software Foundation.
1910d565efSmrg 
2010d565efSmrg You should have received a copy of the GNU General Public License and
2110d565efSmrg a copy of the GCC Runtime Library Exception along with this program;
2210d565efSmrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2310d565efSmrg <http://www.gnu.org/licenses/>.  */
2410d565efSmrg 
2510d565efSmrg /* Threads compatibility routines for libgcc2 for VxWorks.
2610d565efSmrg    These are out-of-line routines called from gthr-vxworks.h.  */
2710d565efSmrg 
2810d565efSmrg #include "tconfig.h"
2910d565efSmrg #include "tsystem.h"
3010d565efSmrg #include "gthr.h"
3110d565efSmrg 
3210d565efSmrg #if defined(__GTHREADS)
3310d565efSmrg #include <vxWorks.h>
3410d565efSmrg #ifndef __RTP__
3510d565efSmrg #include <vxLib.h>
3610d565efSmrg #endif
3710d565efSmrg #include <taskLib.h>
3810d565efSmrg #ifndef __RTP__
3910d565efSmrg #include <taskHookLib.h>
4010d565efSmrg #else
4110d565efSmrg # include <errno.h>
4210d565efSmrg #endif
4310d565efSmrg 
4410d565efSmrg /* Init-once operation.
4510d565efSmrg 
4610d565efSmrg    This would be a clone of the implementation from gthr-solaris.h,
4710d565efSmrg    except that we have a bootstrap problem - the whole point of this
4810d565efSmrg    exercise is to prevent double initialization, but if two threads
4910d565efSmrg    are racing with each other, once->mutex is liable to be initialized
5010d565efSmrg    by both.  Then each thread will lock its own mutex, and proceed to
5110d565efSmrg    call the initialization routine.
5210d565efSmrg 
5310d565efSmrg    So instead we use a bare atomic primitive (vxTas()) to handle
5410d565efSmrg    mutual exclusion.  Threads losing the race then busy-wait, calling
5510d565efSmrg    taskDelay() to yield the processor, until the initialization is
5610d565efSmrg    completed.  Inefficient, but reliable.  */
5710d565efSmrg 
5810d565efSmrg int
__gthread_once(__gthread_once_t * guard,void (* func)(void))5910d565efSmrg __gthread_once (__gthread_once_t *guard, void (*func)(void))
6010d565efSmrg {
6110d565efSmrg   if (guard->done)
6210d565efSmrg     return 0;
6310d565efSmrg 
6410d565efSmrg #ifdef __RTP__
6510d565efSmrg   __gthread_lock_library ();
6610d565efSmrg #else
6710d565efSmrg   while (!vxTas ((void *)&guard->busy))
6810d565efSmrg     {
6910d565efSmrg #ifdef __PPC__
7010d565efSmrg       /* This can happen on powerpc, which is using all 32 bits
7110d565efSmrg 	 of the gthread_once_t structure.  */
7210d565efSmrg       if (guard->done)
73c7a68eb7Smrg 	return 0;
7410d565efSmrg #endif
7510d565efSmrg       taskDelay (1);
7610d565efSmrg     }
7710d565efSmrg #endif
7810d565efSmrg 
7910d565efSmrg   /* Only one thread at a time gets here.  Check ->done again, then
8010d565efSmrg      go ahead and call func() if no one has done it yet.  */
8110d565efSmrg   if (!guard->done)
8210d565efSmrg     {
8310d565efSmrg       func ();
8410d565efSmrg       guard->done = 1;
8510d565efSmrg     }
8610d565efSmrg 
8710d565efSmrg #ifdef __RTP__
8810d565efSmrg   __gthread_unlock_library ();
8910d565efSmrg #else
9010d565efSmrg   guard->busy = 0;
9110d565efSmrg #endif
9210d565efSmrg   return 0;
9310d565efSmrg }
9410d565efSmrg 
9510d565efSmrg #endif /* __GTHREADS */
96