OLD | NEW |
1 /* Copyright (c) 2009, Google Inc. | 1 /* Copyright (c) 2009, Google Inc. |
2 * All rights reserved. | 2 * All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 | 80 |
81 namespace base { | 81 namespace base { |
82 namespace internal { | 82 namespace internal { |
83 | 83 |
84 void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop) { | 84 void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop) { |
85 if (loop != 0) { | 85 if (loop != 0) { |
86 int save_errno = errno; | 86 int save_errno = errno; |
87 struct timespec tm; | 87 struct timespec tm; |
88 tm.tv_sec = 0; | 88 tm.tv_sec = 0; |
89 if (have_futex) { | 89 if (have_futex) { |
| 90 // Wait between 0-16ms. |
90 tm.tv_nsec = base::internal::SuggestedDelayNS(loop); | 91 tm.tv_nsec = base::internal::SuggestedDelayNS(loop); |
91 } else { | 92 // Note: since Unlock() is optimized to not do a compare-and-swap, |
92 tm.tv_nsec = 2000001; // above 2ms so linux 2.4 doesn't spin | 93 // we can't expect explicit wake-ups. Therefore we shouldn't wait too |
93 } | 94 // long here. |
94 if (have_futex) { | |
95 tm.tv_nsec *= 16; // increase the delay; we expect explicit wakeups | |
96 syscall(__NR_futex, reinterpret_cast<int *>(const_cast<Atomic32 *>(w)), | 95 syscall(__NR_futex, reinterpret_cast<int *>(const_cast<Atomic32 *>(w)), |
97 FUTEX_WAIT | futex_private_flag, | 96 FUTEX_WAIT | futex_private_flag, |
98 value, reinterpret_cast<struct kernel_timespec *>(&tm)); | 97 value, reinterpret_cast<struct kernel_timespec *>(&tm)); |
99 } else { | 98 } else { |
| 99 tm.tv_nsec = 2000001; // above 2ms so linux 2.4 doesn't spin |
100 nanosleep(&tm, NULL); | 100 nanosleep(&tm, NULL); |
101 } | 101 } |
102 errno = save_errno; | 102 errno = save_errno; |
103 } | 103 } |
104 } | 104 } |
105 | 105 |
106 void SpinLockWake(volatile Atomic32 *w, bool all) { | 106 void SpinLockWake(volatile Atomic32 *w, bool all) { |
107 if (have_futex) { | 107 if (have_futex) { |
108 syscall(__NR_futex, reinterpret_cast<int *>(const_cast<Atomic32 *>(w)), | 108 syscall(__NR_futex, reinterpret_cast<int *>(const_cast<Atomic32 *>(w)), |
109 FUTEX_WAKE | futex_private_flag, 1, 0); | 109 FUTEX_WAKE | futex_private_flag, 1, 0); |
110 } | 110 } |
111 } | 111 } |
112 | 112 |
113 } // namespace internal | 113 } // namespace internal |
114 } // namespace base | 114 } // namespace base |
OLD | NEW |