What perl built in functions are atomic?

multithreading, perl

Solution

Guideline: If it's an operation supported by tie, it's atomic. Otherwise, it's not.

Control:

use strict;
use warnings;
use feature qw( say );
use threads;
use threads::shared;

use constant NUM_THREADS => 4;
use constant NUM_OPS     => 100_000;

my $q :shared = 0;

my @threads;
for (1..NUM_THREADS) {
   push @threads, async {
      for (1..NUM_OPS) {
         ++$q;
      }
   };
}

$_->join for @threads;

say "Got:      ", $q;
say "Expected: ", NUM_THREADS * NUM_OPS;
say $q == NUM_THREADS * NUM_OPS ? "ok" : "fail";

Output:

Got:      163561
Expected: 400000
fail

`push @a, 1;` instead of `++$q`:

Got:      400000
Expected: 400000
ok

Problem

I'm writing some threaded code and I'm wondering what Perl built in functions and operators are atomic and safe to use on a shared variable without locking. For example, I've been told `++`, `--`, `+=` and the like are not because they are implemented as two operations. Is there a list somewhere? In particular are `push`, `pop`, `shift`, `unshift` and `splice` on a shared array atomic? Thanks.

Original source