Changeset 181481 in webkit


Ignore:
Timestamp:
Mar 13, 2015 11:02:40 AM (9 years ago)
Author:
mark.lam@apple.com
Message:

Introduce WTF::Atomic to wrap std::atomic for a friendlier CAS.
<https://webkit.org/b/142661>

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

Changed CodeBlock, and the DFG's crashLock to use WTF::Atomic instead of
std::atomic.

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::visitAggregate):

  • bytecode/CodeBlock.h:
  • dfg/DFGCommon.cpp:

(JSC::DFG::startCrashing):

Source/WTF:

The CAS functions provided by std::atomic takes a reference to the expected
value and modifies it if the CAS fails. However, in a lot of our CAS usage,
we don't want the expected value to change. The solution to this is to
provide a WTF::Atomic struct that wraps std::atomic, and provide CAS
methods that won't alter the expected value if the CAS fails.

The method names in WTF::Atomic are chosen to be identical to those
in std::atomic so that WTF::Atomic can be a simple drop in replacement
for std::atomic.

Also changed ByteSpinLock to use WTF::Atomic instead of std::atomic.

  • wtf/Atomics.h:

(WTF::Atomic::load):
(WTF::Atomic::store):
(WTF::Atomic::compare_exchange_weak):
(WTF::Atomic::compare_exchange_strong):

  • wtf/ByteSpinLock.h:

(WTF::ByteSpinLock::ByteSpinLock):
(WTF::ByteSpinLock::lock):

Location:
trunk/Source
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r181469 r181481  
     12015-03-13  Mark Lam  <mark.lam@apple.com>
     2
     3        Introduce WTF::Atomic to wrap std::atomic for a friendlier CAS.
     4        <https://webkit.org/b/142661>
     5
     6        Reviewed by Filip Pizlo.
     7
     8        Changed CodeBlock, and the DFG's crashLock to use WTF::Atomic instead of
     9        std::atomic.
     10
     11        * bytecode/CodeBlock.cpp:
     12        (JSC::CodeBlock::CodeBlock):
     13        (JSC::CodeBlock::visitAggregate):
     14        * bytecode/CodeBlock.h:
     15        * dfg/DFGCommon.cpp:
     16        (JSC::DFG::startCrashing):
     17
    1182015-03-12  Mark Lam  <mark.lam@apple.com>
    219
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r181467 r181481  
    16461646    , m_needsActivation(other.m_needsActivation)
    16471647    , m_mayBeExecuting(false)
    1648     , m_visitAggregateHasBeenCalled(false)
    16491648    , m_source(other.m_source)
    16501649    , m_sourceOffset(other.m_sourceOffset)
     
    16631662#endif
    16641663{
     1664    m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
     1665
    16651666    ASSERT(m_heap->isDeferred());
    16661667    ASSERT(m_scopeRegister.isLocal());
     
    17081709    , m_needsActivation(unlinkedCodeBlock->hasActivationRegister() && unlinkedCodeBlock->codeType() == FunctionCode)
    17091710    , m_mayBeExecuting(false)
    1710     , m_visitAggregateHasBeenCalled(false)
    17111711    , m_source(sourceProvider)
    17121712    , m_sourceOffset(sourceOffset)
     
    17201720#endif
    17211721{
     1722    m_visitAggregateHasBeenCalled.store(false, std::memory_order_relaxed);
     1723
    17221724    ASSERT(m_heap->isDeferred());
    17231725    ASSERT(m_scopeRegister.isLocal());
     
    22032205    // To this end, use an atomic operation to check (and set) if I've been called already.
    22042206    // Only one thread may proceed past this point - whichever one wins the atomic set race.
    2205     bool expected = false;
    2206     bool setByMe = m_visitAggregateHasBeenCalled.compare_exchange_strong(expected, true, std::memory_order_acquire);
     2207    bool setByMe = m_visitAggregateHasBeenCalled.compare_exchange_strong(false, true, std::memory_order_acquire);
    22072208    if (!setByMe)
    22082209        return;
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r181456 r181481  
    10661066    bool m_needsActivation;
    10671067    bool m_mayBeExecuting;
    1068     std::atomic<bool> m_visitAggregateHasBeenCalled;
     1068    Atomic<bool> m_visitAggregateHasBeenCalled;
    10691069
    10701070    RefPtr<SourceProvider> m_source;
  • trunk/Source/JavaScriptCore/dfg/DFGCommon.cpp

    r181469 r181481  
    3535namespace JSC { namespace DFG {
    3636
    37 static std::atomic<unsigned> crashLock;
     37static Atomic<unsigned> crashLock;
    3838
    3939void startCrashing()
    4040{
    41     unsigned expected = 0;
    42     while (!crashLock.compare_exchange_weak(expected, 1, std::memory_order_acquire)) {
     41    while (!crashLock.compare_exchange_weak(0, 1, std::memory_order_acquire))
    4342        std::this_thread::yield();
    44         expected = 0;
    45     }
    4643}
    4744
  • trunk/Source/WTF/ChangeLog

    r181467 r181481  
     12015-03-13  Mark Lam  <mark.lam@apple.com>
     2
     3        Introduce WTF::Atomic to wrap std::atomic for a friendlier CAS.
     4        <https://webkit.org/b/142661>
     5
     6        Reviewed by Filip Pizlo.
     7
     8        The CAS functions provided by std::atomic takes a reference to the expected
     9        value and modifies it if the CAS fails.  However, in a lot of our CAS usage,
     10        we don't want the expected value to change.  The solution to this is to
     11        provide a WTF::Atomic struct that wraps std::atomic, and provide CAS
     12        methods that won't alter the expected value if the CAS fails.
     13
     14        The method names in WTF::Atomic are chosen to be identical to those
     15        in std::atomic so that WTF::Atomic can be a simple drop in replacement
     16        for std::atomic.
     17
     18        Also changed ByteSpinLock to use WTF::Atomic instead of std::atomic.
     19
     20        * wtf/Atomics.h:
     21        (WTF::Atomic::load):
     22        (WTF::Atomic::store):
     23        (WTF::Atomic::compare_exchange_weak):
     24        (WTF::Atomic::compare_exchange_strong):
     25        * wtf/ByteSpinLock.h:
     26        (WTF::ByteSpinLock::ByteSpinLock):
     27        (WTF::ByteSpinLock::lock):
     28
    1292015-03-12  Filip Pizlo  <fpizlo@apple.com>
    230
  • trunk/Source/WTF/wtf/Atomics.h

    r181305 r181481  
    11/*
    2  * Copyright (C) 2007, 2008, 2010, 2012, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2007-2008, 2010, 2012-2013, 2015 Apple Inc. All rights reserved.
    33 * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
    44 *
     
    6060#define Atomics_h
    6161
     62#include <atomic>
    6263#include <wtf/StdLibExtras.h>
    6364
     
    7172
    7273namespace WTF {
     74
     75// Atomic wraps around std::atomic with the sole purpose of making the compare_exchange
     76// operations not alter the expected value. This is more in line with how we typically
     77// use CAS in our code.
     78//
     79// Atomic is a struct without explicitly defined constructors so that it can be
     80// initialized at compile time.
     81
     82template<typename T>
     83struct Atomic {
     84
     85    T load(std::memory_order order) const { return value.load(order); }
     86
     87    void store(T desired, std::memory_order order) { value.store(desired, order); }
     88
     89    bool compare_exchange_weak(T expected, T desired, std::memory_order order)
     90    {
     91        T expectedOrActual = expected;
     92        return value.compare_exchange_weak(expectedOrActual, desired, order);
     93    }
     94
     95    bool compare_exchange_strong(T expected, T desired, std::memory_order order)
     96    {
     97        T expectedOrActual = expected;
     98        return value.compare_exchange_strong(expectedOrActual, desired, order);
     99    }
     100
     101    std::atomic<T> value;
     102};
    73103
    74104#if OS(WINDOWS)
     
    346376} // namespace WTF
    347377
     378using WTF::Atomic;
     379
    348380#endif // Atomics_h
  • trunk/Source/WTF/wtf/ByteSpinLock.h

    r181461 r181481  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2727#define ByteSpinLock_h
    2828
    29 #include <atomic>
    3029#include <thread>
    3130#include <wtf/Assertions.h>
     31#include <wtf/Atomics.h>
    3232#include <wtf/Locker.h>
    3333#include <wtf/Noncopyable.h>
     
    3939public:
    4040    ByteSpinLock()
    41         : m_lock(false)
    4241    {
     42        m_lock.store(false, std::memory_order_relaxed);
    4343    }
    4444
    4545    void lock()
    4646    {
    47         bool expected = false;
    48         while (!m_lock.compare_exchange_weak(expected, true, std::memory_order_acquire)) {
     47        while (!m_lock.compare_exchange_weak(false, true, std::memory_order_acquire))
    4948            std::this_thread::yield();
    50             expected = false;
    51         }
    5249    }
    5350   
     
    6057   
    6158private:
    62     std::atomic<bool> m_lock;
     59    Atomic<bool> m_lock;
    6360};
    6461
Note: See TracChangeset for help on using the changeset viewer.