Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/xpcom/tests/gtest/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 7 kB image not shown  

Quelle  TestSynchronization.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include "mozilla/CondVar.h"
#include "mozilla/Monitor.h"
#include "mozilla/ReentrantMonitor.h"
#include "mozilla/Mutex.h"
#include "gtest/gtest.h"

using namespace mozilla;

static PRThread* spawn(void (*run)(void*), void* arg) {
  return PR_CreateThread(PR_SYSTEM_THREAD, run, arg, PR_PRIORITY_NORMAL,
                         PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
}

//-----------------------------------------------------------------------------
// Sanity check: tests that can be done on a single thread
//
TEST(Synchronization, Sanity)
MOZ_NO_THREAD_SAFETY_ANALYSIS {
  Mutex lock("sanity::lock");
  lock.Lock();
  lock.AssertCurrentThreadOwns();
  lock.Unlock();

  {
    MutexAutoLock autolock(lock);
    lock.AssertCurrentThreadOwns();
  }

  lock.Lock();
  lock.AssertCurrentThreadOwns();
  { MutexAutoUnlock autounlock(lock); }
  lock.AssertCurrentThreadOwns();
  lock.Unlock();

  ReentrantMonitor mon("sanity::monitor");
  mon.Enter();
  mon.AssertCurrentThreadIn();
  mon.Enter();
  mon.AssertCurrentThreadIn();
  mon.Exit();
  mon.AssertCurrentThreadIn();
  mon.Exit();

  {
    ReentrantMonitorAutoEnter automon(mon);
    mon.AssertCurrentThreadIn();
  }
}

//-----------------------------------------------------------------------------
// Mutex contention tests
//
static Mutex* gLock1;

static void MutexContention_thread(void/*arg*/) {
  for (int i = 0; i < 100000; ++i) {
    gLock1->Lock();
    gLock1->AssertCurrentThreadOwns();
    gLock1->Unlock();
  }
}

TEST(Synchronization, MutexContention)
{
  gLock1 = new Mutex("lock1");
  // PURPOSELY not checking for OOM.  YAY!

  PRThread* t1 = spawn(MutexContention_thread, nullptr);
  PRThread* t2 = spawn(MutexContention_thread, nullptr);
  PRThread* t3 = spawn(MutexContention_thread, nullptr);

  PR_JoinThread(t1);
  PR_JoinThread(t2);
  PR_JoinThread(t3);

  delete gLock1;
}

//-----------------------------------------------------------------------------
// Monitor tests
//
static Monitor* gMon1;

static void MonitorContention_thread(void/*arg*/) {
  for (int i = 0; i < 100000; ++i) {
    gMon1->Lock();
    gMon1->AssertCurrentThreadOwns();
    gMon1->Unlock();
  }
}

TEST(Synchronization, MonitorContention)
{
  gMon1 = new Monitor("mon1");

  PRThread* t1 = spawn(MonitorContention_thread, nullptr);
  PRThread* t2 = spawn(MonitorContention_thread, nullptr);
  PRThread* t3 = spawn(MonitorContention_thread, nullptr);

  PR_JoinThread(t1);
  PR_JoinThread(t2);
  PR_JoinThread(t3);

  delete gMon1;
}

static ReentrantMonitor* gMon2;

static void MonitorContention2_thread(void/*arg*/)
    MOZ_NO_THREAD_SAFETY_ANALYSIS {
  for (int i = 0; i < 100000; ++i) {
    gMon2->Enter();
    gMon2->AssertCurrentThreadIn();
    {
      gMon2->Enter();
      gMon2->AssertCurrentThreadIn();
      gMon2->Exit();
    }
    gMon2->AssertCurrentThreadIn();
    gMon2->Exit();
  }
}

TEST(Synchronization, MonitorContention2)
{
  gMon2 = new ReentrantMonitor("mon1");

  PRThread* t1 = spawn(MonitorContention2_thread, nullptr);
  PRThread* t2 = spawn(MonitorContention2_thread, nullptr);
  PRThread* t3 = spawn(MonitorContention2_thread, nullptr);

  PR_JoinThread(t1);
  PR_JoinThread(t2);
  PR_JoinThread(t3);

  delete gMon2;
}

static ReentrantMonitor* gMon3;
static int32_t gMonFirst;

static void MonitorSyncSanity_thread(void/*arg*/)
    MOZ_NO_THREAD_SAFETY_ANALYSIS {
  gMon3->Enter();
  gMon3->AssertCurrentThreadIn();
  if (gMonFirst) {
    gMonFirst = 0;
    gMon3->Wait();
    gMon3->Enter();
  } else {
    gMon3->Notify();
    gMon3->Enter();
  }
  gMon3->AssertCurrentThreadIn();
  gMon3->Exit();
  gMon3->AssertCurrentThreadIn();
  gMon3->Exit();
}

TEST(Synchronization, MonitorSyncSanity)
{
  gMon3 = new ReentrantMonitor("monitor::syncsanity");

  for (int32_t i = 0; i < 10000; ++i) {
    gMonFirst = 1;
    PRThread* ping = spawn(MonitorSyncSanity_thread, nullptr);
    PRThread* pong = spawn(MonitorSyncSanity_thread, nullptr);
    PR_JoinThread(ping);
    PR_JoinThread(pong);
  }

  delete gMon3;
}

//-----------------------------------------------------------------------------
// Condvar tests
//
static Mutex* gCvlock1;
static CondVar* gCv1;
static int32_t gCvFirst;

static void CondVarSanity_thread(void/*arg*/) {
  gCvlock1->Lock();
  gCvlock1->AssertCurrentThreadOwns();
  if (gCvFirst) {
    gCvFirst = 0;
    gCv1->Wait();
  } else {
    gCv1->Notify();
  }
  gCvlock1->AssertCurrentThreadOwns();
  gCvlock1->Unlock();
}

TEST(Synchronization, CondVarSanity)
{
  gCvlock1 = new Mutex("cvlock1");
  gCv1 = new CondVar(*gCvlock1, "cvlock1");

  for (int32_t i = 0; i < 10000; ++i) {
    gCvFirst = 1;
    PRThread* ping = spawn(CondVarSanity_thread, nullptr);
    PRThread* pong = spawn(CondVarSanity_thread, nullptr);
    PR_JoinThread(ping);
    PR_JoinThread(pong);
  }

  delete gCv1;
  delete gCvlock1;
}

//-----------------------------------------------------------------------------
// AutoLock tests
//
TEST(Synchronization, AutoLock)
{
  Mutex l1 MOZ_UNANNOTATED("autolock");
  MutexAutoLock autol1(l1);

  l1.AssertCurrentThreadOwns();

  {
    Mutex l2 MOZ_UNANNOTATED("autolock2");
    MutexAutoLock autol2(l2);

    l1.AssertCurrentThreadOwns();
    l2.AssertCurrentThreadOwns();
  }

  l1.AssertCurrentThreadOwns();
}

//-----------------------------------------------------------------------------
// AutoTryLock tests
//
// The thread owns assertions make mutex analysis throw spurious warnings
TEST(Synchronization, AutoTryLock)
MOZ_NO_THREAD_SAFETY_ANALYSIS {
  Mutex l1 MOZ_UNANNOTATED("autotrylock");
  MutexAutoTryLock autol1(l1);

  EXPECT_TRUE(autol1);
  l1.AssertCurrentThreadOwns();

  MutexAutoTryLock autol2(l1);

  EXPECT_TRUE(autol1);
  EXPECT_FALSE(autol2);
  l1.AssertCurrentThreadOwns();

  {
    Mutex l2 MOZ_UNANNOTATED("autotrylock2");
    MutexAutoTryLock autol3(l2);

    EXPECT_TRUE(autol3);
    l1.AssertCurrentThreadOwns();
    l2.AssertCurrentThreadOwns();
  }

  l1.AssertCurrentThreadOwns();
}

//-----------------------------------------------------------------------------
// AutoUnlock tests
//
TEST(Synchronization, AutoUnlock)
{
  Mutex l1 MOZ_UNANNOTATED("autounlock");
  Mutex l2 MOZ_UNANNOTATED("autounlock2");

  l1.Lock();
  l1.AssertCurrentThreadOwns();

  {
    MutexAutoUnlock autol1(l1);
    {
      l2.Lock();
      l2.AssertCurrentThreadOwns();

      MutexAutoUnlock autol2(l2);
    }
    l2.AssertCurrentThreadOwns();
    l2.Unlock();
  }
  l1.AssertCurrentThreadOwns();

  l1.Unlock();
}

//-----------------------------------------------------------------------------
// AutoMonitor tests
//
TEST(Synchronization, AutoMonitor)
MOZ_NO_THREAD_SAFETY_ANALYSIS {
  ReentrantMonitor m1("automonitor");
  ReentrantMonitor m2("automonitor2");

  m1.Enter();
  m1.AssertCurrentThreadIn();
  {
    ReentrantMonitorAutoEnter autom1(m1);
    m1.AssertCurrentThreadIn();

    m2.Enter();
    m2.AssertCurrentThreadIn();
    {
      ReentrantMonitorAutoEnter autom2(m2);
      m1.AssertCurrentThreadIn();
      m2.AssertCurrentThreadIn();
    }
    m2.AssertCurrentThreadIn();
    m2.Exit();

    m1.AssertCurrentThreadIn();
  }
  m1.AssertCurrentThreadIn();
  m1.Exit();
}

87%


¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.