Skip to content

Commit 3af0796

Browse files
committed
[runtime] addressed review comments outlined in #1950 (Merge pull request #2332 from shawnce/SR-946_polish)
[runtime] addressed review comments outlined in #1950
2 parents 7972609 + d78c6e3 commit 3af0796

File tree

6 files changed

+127
-194
lines changed

6 files changed

+127
-194
lines changed

include/swift/Runtime/Mutex.h

Lines changed: 34 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ class Mutex {
136136
///
137137
/// Precondition: Mutex not held by this thread, undefined otherwise.
138138
template <typename CriticalSection>
139-
void lock(CriticalSection criticalSection) {
139+
void withLock(CriticalSection criticalSection) {
140140
lock();
141141
criticalSection();
142142
unlock();
@@ -155,7 +155,7 @@ class Mutex {
155155
/// ...all while being correctly protected by mutex.
156156
///
157157
/// ```
158-
/// mutex.lockOrWait(condition, [&value] {
158+
/// mutex.withLockOrWait(condition, [&value] {
159159
/// if (value > 0) {
160160
/// value--;
161161
/// return true;
@@ -166,9 +166,9 @@ class Mutex {
166166
///
167167
/// Precondition: Mutex not held by this thread, undefined otherwise.
168168
template <typename CriticalSection>
169-
void lockOrWait(ConditionVariable &condition,
170-
CriticalSection criticalSection) {
171-
lock([&] {
169+
void withLockOrWait(ConditionVariable &condition,
170+
CriticalSection criticalSection) {
171+
withLock([&] {
172172
while (!criticalSection()) {
173173
wait(condition);
174174
}
@@ -185,14 +185,14 @@ class Mutex {
185185
/// then notifies one condition waiter about this change.
186186
///
187187
/// ```
188-
/// mutex.lockAndNotifyOne([&value] { value++; });
188+
/// mutex.withLockThenNotifyOne(condition, [&value] { value++; });
189189
/// ```
190190
///
191191
/// Precondition: Mutex not held by this thread, undefined otherwise.
192192
template <typename CriticalSection>
193-
void lockAndNotifyOne(ConditionVariable &condition,
194-
CriticalSection criticalSection) {
195-
lock([&] {
193+
void withLockThenNotifyOne(ConditionVariable &condition,
194+
CriticalSection criticalSection) {
195+
withLock([&] {
196196
criticalSection();
197197
condition.notifyOne();
198198
});
@@ -208,14 +208,14 @@ class Mutex {
208208
/// then notifies all condition waiters about this change.
209209
///
210210
/// ```
211-
/// mutex.lockAndNotifyAll([&value] { value++; });
211+
/// mutex.withLockThenNotifyAll(condition, [&value] { value++; });
212212
/// ```
213213
///
214214
/// Precondition: Mutex not held by this thread, undefined otherwise.
215215
template <typename CriticalSection>
216-
void lockAndNotifyAll(ConditionVariable &condition,
217-
CriticalSection criticalSection) {
218-
lock([&] {
216+
void withLockThenNotifyAll(ConditionVariable &condition,
217+
CriticalSection criticalSection) {
218+
withLock([&] {
219219
criticalSection();
220220
condition.notifyAll();
221221
});
@@ -343,12 +343,12 @@ class ReadWriteLock {
343343
/// the read lock.
344344
///
345345
/// ```
346-
/// rw.readLock([&value] { value = cachedValue; });
346+
/// rw.withReadLock([&value] { value = cachedValue; });
347347
/// ```
348348
///
349349
/// Precondition: ReadWriteLock not held by this thread, undefined otherwise.
350350
template <typename CriticalSection>
351-
void readLock(CriticalSection criticalSection) {
351+
void withReadLock(CriticalSection criticalSection) {
352352
readLock();
353353
criticalSection();
354354
readUnlock();
@@ -363,61 +363,17 @@ class ReadWriteLock {
363363
/// the write lock.
364364
///
365365
/// ```
366-
/// rw.writeLock([&newValue] { cachedValue = newValue });
366+
/// rw.withWriteLock([&newValue] { cachedValue = newValue });
367367
/// ```
368368
///
369369
/// Precondition: ReadWriteLock not held by this thread, undefined otherwise.
370370
template <typename CriticalSection>
371-
void writeLock(CriticalSection criticalSection) {
371+
void withWriteLock(CriticalSection criticalSection) {
372372
writeLock();
373373
criticalSection();
374374
writeUnlock();
375375
}
376376

377-
/// Acquires read lock before calling the read critical section and if
378-
/// the critical section returns `true` (done) readWriteLock returns to the
379-
/// caller. If the read critical section returns `false` the read lock
380-
/// will be dropped, the write lock will be acquired and then the read
381-
/// critical section will be called again. Then if the critical section
382-
/// returns `true` (done) readWriteLock returns to the caller. If the read
383-
/// critical section returns `false` then the write critical section will
384-
/// be called (with write lock still held).
385-
///
386-
/// Note in all situations on return to caller the ReadWriteLock will
387-
/// not be held.
388-
///
389-
/// For example the following attempts to get a cachedValue if it exists
390-
/// if not found it will create the needed cachedValue.
391-
///
392-
/// ```
393-
/// rw.readWriteLock(
394-
/// [&value] {
395-
/// if (cachedValue) {
396-
/// value = cachedValue;
397-
/// return true;
398-
/// }
399-
/// return false;
400-
/// },
401-
/// [&value] {
402-
/// cachedValue = createValue();
403-
/// value = cachedValue;
404-
/// });
405-
/// ```
406-
///
407-
/// Precondition: ReadWriteLock not held by this thread, undefined otherwise.
408-
template <typename ReadonlySection, typename WriteSection>
409-
void readWriteLock(ReadonlySection readSection, WriteSection writeSection) {
410-
bool done;
411-
readLock([&done, &readSection] { done = readSection(); });
412-
if (!done) {
413-
writeLock([&readSection, &writeSection] {
414-
if (!readSection()) {
415-
writeSection();
416-
}
417-
});
418-
}
419-
}
420-
421377
private:
422378
ReadWriteLockHandle Handle;
423379
};
@@ -485,38 +441,38 @@ class StaticMutex {
485441

486442
/// See Mutex::lock
487443
template <typename CriticalSection>
488-
void lock(CriticalSection criticalSection) {
444+
void withLock(CriticalSection criticalSection) {
489445
lock();
490446
criticalSection();
491447
unlock();
492448
}
493449

494-
/// See Mutex::lockOrWait
450+
/// See Mutex::withLockOrWait
495451
template <typename CriticalSection>
496-
void lockOrWait(StaticConditionVariable &condition,
497-
CriticalSection criticalSection) {
498-
lock([&] {
452+
void withLockOrWait(StaticConditionVariable &condition,
453+
CriticalSection criticalSection) {
454+
withLock([&] {
499455
while (!criticalSection()) {
500456
wait(condition);
501457
}
502458
});
503459
}
504460

505-
/// See Mutex::lockAndNotifyOne
461+
/// See Mutex::withLockThenNotifyOne
506462
template <typename CriticalSection>
507-
void lockAndNotifyOne(StaticConditionVariable &condition,
508-
CriticalSection criticalSection) {
509-
lock([&] {
463+
void withLockThenNotifyOne(StaticConditionVariable &condition,
464+
CriticalSection criticalSection) {
465+
withLock([&] {
510466
criticalSection();
511467
condition.notifyOne();
512468
});
513469
}
514470

515-
/// See Mutex::lockAndNotifyAll
471+
/// See Mutex::withLockThenNotifyAll
516472
template <typename CriticalSection>
517-
void lockAndNotifyAll(StaticConditionVariable &condition,
518-
CriticalSection criticalSection) {
519-
lock([&] {
473+
void withLockThenNotifyAll(StaticConditionVariable &condition,
474+
CriticalSection criticalSection) {
475+
withLock([&] {
520476
criticalSection();
521477
condition.notifyAll();
522478
});
@@ -566,36 +522,22 @@ class StaticReadWriteLock {
566522
/// See ReadWriteLock::writeUnlock
567523
void writeUnlock() { ReadWriteLockPlatformHelper::writeUnlock(Handle); }
568524

569-
/// See ReadWriteLock::readLock
525+
/// See ReadWriteLock::withReadLock
570526
template <typename CriticalSection>
571-
void readLock(CriticalSection criticalSection) {
527+
void withReadLock(CriticalSection criticalSection) {
572528
readLock();
573529
criticalSection();
574530
readUnlock();
575531
}
576532

577-
/// See ReadWriteLock::writeLock
533+
/// See ReadWriteLock::withWriteLock
578534
template <typename CriticalSection>
579-
void writeLock(CriticalSection criticalSection) {
535+
void withWriteLock(CriticalSection criticalSection) {
580536
writeLock();
581537
criticalSection();
582538
writeUnlock();
583539
}
584540

585-
/// See ReadWriteLock::readWriteLock
586-
template <typename ReadonlySection, typename WriteSection>
587-
void readWriteLock(ReadonlySection readSection, WriteSection writeSection) {
588-
bool done;
589-
readLock([&done, &readSection] { done = readSection(); });
590-
if (!done) {
591-
writeLock([&readSection, &writeSection] {
592-
if (!readSection()) {
593-
writeSection();
594-
}
595-
});
596-
}
597-
}
598-
599541
private:
600542
ReadWriteLockHandle Handle;
601543
};

stdlib/public/runtime/Casting.cpp

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -354,30 +354,40 @@ swift_getTypeName(const Metadata *type, bool qualified) {
354354
Key key(type, qualified);
355355
auto &cache = TypeNameCache.get();
356356

357-
Pair pair;
358-
TypeNameCacheLock.readWriteLock(
359-
[&] {
360-
auto found = cache.find(key);
361-
if (found != cache.end()) {
362-
auto result = found->second;
363-
pair = Pair{result.first, result.second};
364-
return true; // Cache hit, return true (e.g. done)
365-
}
366-
return false; // Cache missed, return false to move to write lock.
367-
},
368-
[&] {
369-
// Build the metadata name.
370-
auto name = nameForMetadata(type, qualified);
371-
// Copy it to memory we can reference forever.
372-
auto size = name.size();
373-
auto result = (char *)malloc(size + 1);
374-
memcpy(result, name.data(), size);
375-
result[size] = 0;
376-
cache.insert({key, {result, size}});
377-
pair = Pair{result, size};
378-
});
379-
380-
return pair;
357+
// Attempt read-only lookup of cache entry.
358+
{
359+
StaticScopedReadLock guard(TypeNameCacheLock);
360+
361+
auto found = cache.find(key);
362+
if (found != cache.end()) {
363+
auto result = found->second;
364+
return Pair{result.first, result.second};
365+
}
366+
}
367+
368+
// Read-only lookup failed to find item, we may need to create it.
369+
{
370+
StaticScopedWriteLock guard(TypeNameCacheLock);
371+
372+
// Do lookup again just to make sure it wasn't created by another
373+
// thread before we acquired the write lock.
374+
auto found = cache.find(key);
375+
if (found != cache.end()) {
376+
auto result = found->second;
377+
return Pair{result.first, result.second};
378+
}
379+
380+
// Build the metadata name.
381+
auto name = nameForMetadata(type, qualified);
382+
// Copy it to memory we can reference forever.
383+
auto size = name.size();
384+
auto result = (char *)malloc(size + 1);
385+
memcpy(result, name.data(), size);
386+
result[size] = 0;
387+
388+
cache.insert({key, {result, size}});
389+
return Pair{result, size};
390+
}
381391
}
382392

383393
/// Report a dynamic cast failure.

stdlib/public/runtime/Errors.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,10 @@ struct crashreporter_annotations_t gCRAnnotations
168168
static void
169169
reportOnCrash(uint32_t flags, const char *message)
170170
{
171+
// We must use an "unsafe" mutex in this pathway since the normal "safe"
172+
// mutex calls fatalError when an error is detected and fatalError ends up
173+
// calling us. In other words we could get infinite recursion if the
174+
// mutex errors.
171175
static StaticUnsafeMutex crashlogLock();
172176

173177
crashlogLock.lock();

stdlib/public/runtime/MetadataCache.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ template <class ValueTy> class MetadataCache {
337337
// appear there. Note that we have to check again immediately
338338
// after acquiring the lock to prevent a race.
339339
auto concurrency = Concurrency.get();
340-
concurrency->Lock.lockOrWait(concurrency->Queue, [&value, &entry, this] {
340+
concurrency->Lock.withLockOrWait(concurrency->Queue, [&, this] {
341341
if ((value = entry->getValue())) {
342342
return true; // found a value, done waiting
343343
}
@@ -373,9 +373,8 @@ template <class ValueTy> class MetadataCache {
373373

374374
// Acquire the lock, set the value, and notify any waiters.
375375
auto concurrency = Concurrency.get();
376-
concurrency->Lock.lockAndNotifyAll(concurrency->Queue, [&entry, &value] {
377-
entry->setValue(value);
378-
});
376+
concurrency->Lock.withLockThenNotifyAll(
377+
concurrency->Queue, [&entry, &value] { entry->setValue(value); });
379378

380379
return value;
381380
}

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ _typeByMangledName(const llvm::StringRef typeName) {
263263
return Value->getMetadata();
264264

265265
// Check type metadata records
266-
T.SectionsToScanLock.lock([&] {
266+
T.SectionsToScanLock.withLock([&] {
267267
foundMetadata = _searchTypeMetadataRecords(T, typeName);
268268
});
269269

0 commit comments

Comments
 (0)