102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch/*
202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * Copyright (C) 2013 Google Inc. All rights reserved.
302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch *
402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * Redistribution and use in source and binary forms, with or without
502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * modification, are permitted provided that the following conditions are
602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * met:
702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch *
802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch *     * Redistributions of source code must retain the above copyright
902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * notice, this list of conditions and the following disclaimer.
1002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch *     * Redistributions in binary form must reproduce the above
1102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * copyright notice, this list of conditions and the following disclaimer
1202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * in the documentation and/or other materials provided with the
1302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * distribution.
1402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch *     * Neither the name of Google Inc. nor the names of its
1502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * contributors may be used to endorse or promote products derived from
1602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * this software without specific prior written permission.
1702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch *
1802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch */
3002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
311fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch#include "config.h"
321fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch#include "wtf/SpinLock.h"
3302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
3451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/Task.h"
3551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "public/platform/Platform.h"
3651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "public/platform/WebThread.h"
3751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "wtf/OwnPtr.h"
3851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "wtf/PassOwnPtr.h"
391fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch#include <gtest/gtest.h>
4002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
411fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdochnamespace {
4202772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciusing namespace blink;
447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
451fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdochstatic const size_t bufferSize = 16;
4602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
471fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdochstatic int lock = 0;
4802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
491fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdochstatic void fillBuffer(volatile char* buffer, char fillPattern)
501fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch{
51f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    for (size_t i = 0; i < bufferSize; ++i)
521fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        buffer[i] = fillPattern;
531fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch}
5402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
551fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdochstatic void changeAndCheckBuffer(volatile char* buffer)
561fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch{
571fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    fillBuffer(buffer, '\0');
581fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    int total = 0;
59f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    for (size_t i = 0; i < bufferSize; ++i)
601fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        total += buffer[i];
6102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
621fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    EXPECT_EQ(0, total);
6302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
641fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    // This will mess with the other thread's calculation if we accidentally get
651fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    // concurrency.
661fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    fillBuffer(buffer, '!');
671fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch}
6802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
6951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static void threadMain(volatile char* buffer)
701fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch{
711fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    for (int i = 0; i < 500000; ++i) {
721fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        spinLockLock(&lock);
731fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        changeAndCheckBuffer(buffer);
741fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch        spinLockUnlock(&lock);
751fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    }
761fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch}
7702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
781fad5ca6c42d689812b66fc493992aa6d747a6fbBen MurdochTEST(WTF_SpinLock, Torture)
791fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch{
801fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch    char sharedBuffer[bufferSize];
8102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    OwnPtr<WebThread> thread1 = adoptPtr(Platform::current()->createThread("thread1"));
837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    OwnPtr<WebThread> thread2 = adoptPtr(Platform::current()->createThread("thread2"));
8451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
8551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    thread1->postTask(new Task(WTF::bind(&threadMain, static_cast<char*>(sharedBuffer))));
8651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    thread2->postTask(new Task(WTF::bind(&threadMain, static_cast<char*>(sharedBuffer))));
8702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
8851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    thread1.clear();
8951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    thread2.clear();
901fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch}
9102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
921fad5ca6c42d689812b66fc493992aa6d747a6fbBen Murdoch} // namespace
93