150ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com/*
250ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com * Copyright 2012 Google Inc.
350ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com *
450ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com * Use of this source code is governed by a BSD-style license that can be
550ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com * found in the LICENSE file.
650ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com */
750ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com
850ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com#include "SkThread.h"
950ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com#include "SkThreadUtils.h"
1050ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com#include "SkTypes.h"
118f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "Test.h"
1250ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com
1350ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.comstruct AddInfo {
1450ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    int32_t valueToAdd;
1550ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    int timesToAdd;
1650ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    unsigned int processorAffinity;
1750ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com};
1850ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com
1950ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.comstatic int32_t base = 0;
2050ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com
2150ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.comstatic AddInfo gAdds[] = {
2250ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    { 3, 100, 23 },
2350ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    { 2, 200, 2 },
2450ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    { 7, 150, 17 },
2550ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com};
2650ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com
2750ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.comstatic void addABunchOfTimes(void* data) {
2850ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    AddInfo* addInfo = static_cast<AddInfo*>(data);
2950ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    for (int i = 0; i < addInfo->timesToAdd; i++) {
3050ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com        sk_atomic_add(&base, addInfo->valueToAdd);
3150ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    }
3250ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com}
3350ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com
34e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.orgDEF_TEST(Atomic, reporter) {
3550ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    int32_t total = base;
3650ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    SkThread* threads[SK_ARRAY_COUNT(gAdds)];
3750ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gAdds); i++) {
3850ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com        total += gAdds[i].valueToAdd * gAdds[i].timesToAdd;
3950ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    }
4050ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    // Start the threads
4150ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gAdds); i++) {
4250ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com        threads[i] = new SkThread(addABunchOfTimes, &gAdds[i]);
4350ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com        threads[i]->setProcessorAffinity(gAdds[i].processorAffinity);
4450ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com        threads[i]->start();
4550ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    }
4650ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com
4750ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    // Now end the threads
4850ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gAdds); i++) {
4950ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com        threads[i]->join();
5050ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com        delete threads[i];
5150ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    }
5250ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    REPORTER_ASSERT(reporter, total == base);
5350ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    // Ensure that the returned value from sk_atomic_add is correct.
5450ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    int32_t valueToModify = 3;
5550ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    const int32_t originalValue = valueToModify;
5650ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com    REPORTER_ASSERT(reporter, originalValue == sk_atomic_add(&valueToModify, 7));
5750ccb0a73865b0d0f0dd48989dbf5aa4a27f4a72scroggo@google.com}
58