test/jdk/java/util/TimeZone/SimpleTimeZoneCloneRaceTest.java
author naoto
Fri, 26 Jul 2019 08:56:28 -0700
changeset 57544 99d2dd7b84a8
parent 48239 8067e9cba973
permissions -rw-r--r--
8212970: TZ database in "vanguard" format support Reviewed-by: rriggs, joehw, erikj, scolebourne
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
48239
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
     1
/*
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
     2
 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
     4
 *
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
     7
 * published by the Free Software Foundation.
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
     8
 *
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    13
 * accompanied this code).
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    14
 *
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    18
 *
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    21
 * questions.
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    22
 */
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    23
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    24
import java.util.Calendar;
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    25
import java.util.Locale;
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    26
import java.util.SimpleTimeZone;
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    27
import java.util.TimeZone;
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    28
import java.util.function.Supplier;
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    29
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    30
/*
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    31
 * @test
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    32
 * @bug 8191216
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    33
 * @summary test that provokes race between cloning and lazily initializing
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    34
 *          SimpleTimeZone cache fields
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    35
 */
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    36
public class SimpleTimeZoneCloneRaceTest {
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    37
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    38
    public static void main(String[] args) throws InterruptedException {
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    39
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    40
        // shared TZ user repeatedly samples sharedTZ and calculates offset
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    41
        // using the shared instance
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    42
        TimeZoneUser sharedTZuser = new TimeZoneUser(() -> sharedTZ);
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    43
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    44
        // cloned TZ user repeatedly samples sharedTZ then clones it and
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    45
        // calculates offset using the clone...
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    46
        TimeZoneUser clonedTZuser = new TimeZoneUser(() -> {
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    47
            // sample shared TZ
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    48
            TimeZone tz = sharedTZ;
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    49
            // do some computation that takes roughly the same time as it takes
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    50
            // sharedTZUser to start changing cache fields in shared TZ
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    51
            cpuHogTZ.getOffset(time);
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    52
            // now clone the sampled TZ and return it, hoping the clone is done
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    53
            // at about the right time....
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    54
            return (TimeZone) tz.clone();
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    55
        });
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    56
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    57
        // start threads
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    58
        Thread t1 = new Thread(sharedTZuser);
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    59
        Thread t2 = new Thread(clonedTZuser);
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    60
        t1.start();
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    61
        t2.start();
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    62
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    63
        // plant new SimpleTimeZone instances for 2 seconds
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    64
        long t0 = System.currentTimeMillis();
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    65
        do {
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    66
            TimeZone tz1 = createSTZ();
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    67
            TimeZone tz2 = createSTZ();
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    68
            cpuHogTZ = tz1;
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    69
            sharedTZ = tz2;
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    70
        } while (System.currentTimeMillis() - t0 < 2000L);
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    71
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    72
        sharedTZuser.stop = true;
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    73
        clonedTZuser.stop = true;
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    74
        t1.join();
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    75
        t2.join();
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    76
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    77
        System.out.println(
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    78
            String.format("shared TZ: %d correct, %d incorrect calculations",
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    79
                          sharedTZuser.correctCount, sharedTZuser.incorrectCount)
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    80
        );
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    81
        System.out.println(
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    82
            String.format("cloned TZ: %d correct, %d incorrect calculations",
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    83
                          clonedTZuser.correctCount, clonedTZuser.incorrectCount)
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    84
        );
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    85
        if (clonedTZuser.incorrectCount > 0) {
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    86
            throw new RuntimeException(clonedTZuser.incorrectCount +
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    87
                                       " fatal data races detected");
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    88
        }
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    89
    }
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    90
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    91
    static SimpleTimeZone createSTZ() {
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    92
        return new SimpleTimeZone(-28800000,
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    93
                                  "America/Los_Angeles",
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    94
                                  Calendar.APRIL, 1, -Calendar.SUNDAY,
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    95
                                  7200000,
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    96
                                  Calendar.OCTOBER, -1, Calendar.SUNDAY,
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    97
                                  7200000,
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    98
                                  3600000);
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
    99
    }
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   100
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   101
    static volatile TimeZone cpuHogTZ = createSTZ();
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   102
    static volatile TimeZone sharedTZ = createSTZ();
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   103
    static final long time;
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   104
    static final long correctOffset;
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   105
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   106
    static {
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   107
        TimeZone tz = createSTZ();
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   108
        Calendar cal = Calendar.getInstance(tz, Locale.ROOT);
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   109
        cal.set(2000, Calendar.MAY, 1, 0, 0, 0);
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   110
        time = cal.getTimeInMillis();
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   111
        correctOffset = tz.getOffset(time);
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   112
    }
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   113
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   114
    static class TimeZoneUser implements Runnable {
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   115
        private final Supplier<? extends TimeZone> tzSupplier;
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   116
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   117
        TimeZoneUser(Supplier<? extends TimeZone> tzSupplier) {
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   118
            this.tzSupplier = tzSupplier;
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   119
        }
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   120
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   121
        volatile boolean stop;
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   122
        int correctCount, incorrectCount;
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   123
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   124
        @Override
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   125
        public void run() {
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   126
            while (!stop) {
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   127
                TimeZone tz = tzSupplier.get();
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   128
                int offset = tz.getOffset(time);
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   129
                if (offset == correctOffset) {
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   130
                    correctCount++;
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   131
                } else {
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   132
                    incorrectCount++;
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   133
                }
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   134
            }
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   135
        }
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   136
    }
8067e9cba973 8191216: SimpleTimeZone.clone() has a data race on cache fields
plevart
parents:
diff changeset
   137
}