StarPU Internal Handbook
thread.h
Go to the documentation of this file.
1/* StarPU --- Runtime system for heterogeneous multicore architectures.
2 *
3 * Copyright (C) 2010-2021 Université de Bordeaux, CNRS (LaBRI UMR 5800), Inria
4 *
5 * StarPU is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation; either version 2.1 of the License, or (at
8 * your option) any later version.
9 *
10 * StarPU is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 *
14 * See the GNU Lesser General Public License in COPYING.LGPL for more details.
15 */
16
17#ifndef __COMMON_THREAD_H__
18#define __COMMON_THREAD_H__
19
22#include <common/utils.h>
23
24#if defined(STARPU_LINUX_SYS) && defined(STARPU_HAVE_XCHG)
25int _starpu_pthread_spin_do_lock(starpu_pthread_spinlock_t *lock);
26#endif
27
28#if defined(STARPU_SIMGRID) || (defined(STARPU_LINUX_SYS) && defined(STARPU_HAVE_XCHG)) || !defined(STARPU_HAVE_PTHREAD_SPIN_LOCK)
29
30static inline int _starpu_pthread_spin_init(starpu_pthread_spinlock_t *lock, int pshared STARPU_ATTRIBUTE_UNUSED)
31{
32 lock->taken = 0;
33 return 0;
34}
35#define starpu_pthread_spin_init _starpu_pthread_spin_init
36
37static inline int _starpu_pthread_spin_destroy(starpu_pthread_spinlock_t *lock STARPU_ATTRIBUTE_UNUSED)
38{
39 /* we don't do anything */
40 return 0;
41}
42#define starpu_pthread_spin_destroy _starpu_pthread_spin_destroy
43
44static inline int _starpu_pthread_spin_lock(starpu_pthread_spinlock_t *lock)
45{
46#ifdef STARPU_SIMGRID
47 while (1)
48 {
49 if (STARPU_LIKELY(!lock->taken))
50 {
51 lock->taken = 1;
52 return 0;
53 }
54 /* Give hand to another thread, hopefully the one which has the
55 * spinlock and probably just has also a short-lived mutex. */
56 starpu_sleep(0.000001);
57 STARPU_UYIELD();
58 }
59#elif defined(STARPU_LINUX_SYS) && defined(STARPU_HAVE_XCHG)
60 if (STARPU_LIKELY(STARPU_VAL_COMPARE_AND_SWAP(&lock->taken, 0, 1) == 0))
61 /* Got it on first try! */
62 return 0;
63
64 return _starpu_pthread_spin_do_lock(lock);
65#else /* !SIMGRID && !LINUX */
66 uint32_t prev;
67 do
68 {
69 prev = STARPU_TEST_AND_SET(&lock->taken, 1);
70 if (STARPU_UNLIKELY(prev))
71 STARPU_UYIELD();
72 }
73 while (STARPU_UNLIKELY(prev));
74 return 0;
75#endif
76}
77#define starpu_pthread_spin_lock _starpu_pthread_spin_lock
78
79static inline void _starpu_pthread_spin_checklocked(starpu_pthread_spinlock_t *lock STARPU_ATTRIBUTE_UNUSED)
80{
81#ifdef STARPU_SIMGRID
82 STARPU_ASSERT(lock->taken);
83#elif defined(STARPU_LINUX_SYS) && defined(STARPU_HAVE_XCHG)
84 STARPU_ASSERT(lock->taken == 1 || lock->taken == 2);
85#else
86 STARPU_ASSERT(lock->taken);
87#endif
88}
89
90static inline int _starpu_pthread_spin_trylock(starpu_pthread_spinlock_t *lock)
91{
92#ifdef STARPU_SIMGRID
93 if (STARPU_UNLIKELY(lock->taken))
94 return EBUSY;
95 lock->taken = 1;
96 return 0;
97#elif defined(STARPU_LINUX_SYS) && defined(STARPU_HAVE_XCHG)
98 unsigned prev;
99 prev = STARPU_VAL_COMPARE_AND_SWAP(&lock->taken, 0, 1);
100 return (prev == 0)?0:EBUSY;
101#else /* !SIMGRID && !LINUX */
102 uint32_t prev;
103 prev = STARPU_TEST_AND_SET(&lock->taken, 1);
104 return (prev == 0)?0:EBUSY;
105#endif
106}
107#define starpu_pthread_spin_trylock _starpu_pthread_spin_trylock
108
109#if defined(STARPU_LINUX_SYS) && defined(STARPU_HAVE_XCHG)
110void _starpu_pthread_spin_do_unlock(starpu_pthread_spinlock_t *lock);
111#endif
112
113static inline int _starpu_pthread_spin_unlock(starpu_pthread_spinlock_t *lock)
114{
115#ifdef STARPU_SIMGRID
116 lock->taken = 0;
117#elif defined(STARPU_LINUX_SYS) && defined(STARPU_HAVE_XCHG)
118 STARPU_ASSERT(lock->taken != 0);
119 STARPU_SYNCHRONIZE();
120 unsigned next = STARPU_ATOMIC_ADD(&lock->taken, -1);
121 if (STARPU_LIKELY(next == 0))
122 /* Nobody to wake, we are done */
123 return 0;
124 _starpu_pthread_spin_do_unlock(lock);
125#else /* !SIMGRID && !LINUX */
126 STARPU_RELEASE(&lock->taken);
127#endif
128 return 0;
129}
130#define starpu_pthread_spin_unlock _starpu_pthread_spin_unlock
131
132#else /* defined(STARPU_SIMGRID) || (defined(STARPU_LINUX_SYS) && defined(STARPU_HAVE_XCHG)) || !defined(STARPU_HAVE_PTHREAD_SPIN_LOCK) */
133
134static inline void _starpu_pthread_spin_checklocked(starpu_pthread_spinlock_t *lock STARPU_ATTRIBUTE_UNUSED)
135{
136 STARPU_ASSERT(pthread_spin_trylock((pthread_spinlock_t *)lock) != 0);
137}
138
139#endif /* defined(STARPU_SIMGRID) || (defined(STARPU_LINUX_SYS) && defined(STARPU_HAVE_XCHG)) || !defined(STARPU_HAVE_PTHREAD_SPIN_LOCK) */
140
141
142#endif /* __COMMON_THREAD_H__ */
143
144