public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "dvyukov at google dot com" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug sanitizer/55561] TSAN crashes for Fortran
Date: Mon, 10 Dec 2012 15:07:00 -0000	[thread overview]
Message-ID: <bug-55561-4-b8jCrBKEdP@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-55561-4@http.gcc.gnu.org/bugzilla/>


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55561

--- Comment #12 from Dmitry Vyukov <dvyukov at google dot com> 2012-12-10 15:07:11 UTC ---
(In reply to comment #11)
> (In reply to comment #10)
> > Is is a correct report? Or false positive?
> 
> This is a correct report for the testcase in comment #0 (as J is shared between
> threads).

That's great that gcc tsan works for Fortran/OpenMP out of the box!

However, most likely Fortran/OpenMP will require some special handling to
produce better reports and catch more bugs (ThreadSanitizer reasons about
synchronization on pthread level, and not on OpenMP level). We won't have spare
cycles for that in near future.
I am working on ThreadSanitizer tasking API, I would appreciate if you review
it and comment on whether it will fit Fortran/OpenMP model (the work is
currently in very early "what if" stage).
The is the proposed public API:


// The tasking API is intended for programs that use finer-grained tasks
// on top of threads.  For such programs ThreadSanitizer can produce
// bad reports (namely, thread creation stack is useless), and catch less
// bugs because it does not understand task boundaries.
// The tasking API allows programs to annotate tasks to solve both problems.
// The API is intended to be flexible enough to support standard C++ tasks,
// OpenMP tasks as well as custom tasks.  It's also intended to be
// non-intrusive as possible to be used merely as annotations in existing code.

// Creation of a task.
// TASK is an arbitrary pointer that uniquely identifies the task.
// ThreadSanitizer stores any required internal info offline.
// FLAGS see below.
void __tsan_task_create(void *task, unsigned flags);

// Destruction of a task, frees all associated resources.
// After that the TASK pointer can be reused for another task.
void __tsan_task_destroy(void *task);

// Denotes beginning of execution of the TASK.
// When the function returns ThreadSanitizer effectively switches
// to another thread context associated with the task.
// Returns TASK.  This is needed because re-reading it even from stack variable
// can result in a data race with the worker thread (since we are already in
the
// task context).
// Tasks can be recursive, but must be strictly nested.
void* __tsan_task_begin(void *task);

// Denotes end of execution of the TASK.
// When the function returns ThreadSanitizer effectively switches
// back to worker thread context.
void __tsan_task_end(void *task);

// If set, ThreadSanitizer uses separate thread context for task execution.
// If not set, ThreadSanitizer can not detect any new data races but still
// produces better reports (namely, task creation stack).  A user may not want
// to set in two cases:
// 1. If task executor executes tasks in single thread (and that is the part
//    of public contract).
// 2. If ThreadSanitizer produces false postives, but a user still wants
//    to take advantage of better reports.
const unsigned __TSAN_TASK_FLAG_SYNC = 1 << 0;

// Denotes that the task is periodic, i.e. can be executed several times
// (intended for periodic timer tasks and IO rediness notifications).
// If set, then __tsan_task_begin()/__tsan_task_end() can be called several
// times.  After the last execution the task must be explicitly destroyed with
// __tsan_task_destroy().
const unsigned __TSAN_TASK_FLAG_PERIODIC = 1 << 1;

// Usage examples:
/*
1. Non-prdiodic task:

void ThreadPool::Add(Task *t) {
  __tsan_task_create(t, __TSAN_TASK_FLAG_SYNC);
  mutex_.lock();
  queue_.push_back(t);
  mutex_.unlock();  
}

void ThreadPool::WorkerThread() {
  for (;;) {
    mutex_.lock();
    while (queue_.empty())
      convvar_.wait(&mutex_);
    Task *t = queue_.pop_front();    
    mutex_.unlock();
    t = __tsan_task_begin(t);
    t->Execute();
    __tsan_task_end(t);
    __tsan_task_destroy(t);
    delete t;
  }
}

This is semantically equivalent to:

void ThreadPool::Add(Task *t) {
  pthread_create(&t->thread_, 0, &Task::Execute, t);
}

2. Priodic task:

void ThreadPool::AddPeriodic(Task *t) {
  __tsan_task_create(t, __TSAN_TASK_FLAG_SYNC | __TSAN_TASK_FLAG_PERIODIC);
  AddPeriodicImpl(t, t->Period());
}

void ThreadPool::WorkerThread() {
  for (;;) {
    Task* t = CheckPeriodicTasks();
    if (t) {
      t = __tsan_task_begin(t);
      t->Execute();
      __tsan_task_end(t);
      AddPeriodicImpl(t, t->Period());
    }
    ...
  }
}

void ThreadPool::CancelPeriodic(Task *t) {
  CancelPeriodicImpl(t);
  __tsan_task_destroy(t);
  delete t;
}

This is semantically equivalent to:

void ThreadPool::Add(Task *t) {
  pthread_create(&t->thread_, 0, &ExecutePeriodic, t);
}

void *ExecutePeriodic(Task *t) {
  while (!t->Cancelled()) {
    sleep(t->Period());
    t->Execute();
  }
}

void ThreadPool::CancelPeriodic(Task *t) {
  t->SetCancelled();
  pthread_join(t->thread_, 0);
  delete t;
}
*/


  parent reply	other threads:[~2012-12-10 15:07 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-12-02  8:16 [Bug sanitizer/55561] New: " Joost.VandeVondele at mat dot ethz.ch
2012-12-02  9:21 ` [Bug sanitizer/55561] " dvyukov at google dot com
2012-12-02  9:30 ` Joost.VandeVondele at mat dot ethz.ch
2012-12-02  9:36 ` dvyukov at google dot com
2012-12-02 10:28 ` kcc at gcc dot gnu.org
2012-12-02 21:11 ` jakub at gcc dot gnu.org
2012-12-03  7:42 ` Joost.VandeVondele at mat dot ethz.ch
2012-12-10 12:44 ` Joost.VandeVondele at mat dot ethz.ch
2012-12-10 12:47 ` pinskia at gcc dot gnu.org
2012-12-10 12:53 ` Joost.VandeVondele at mat dot ethz.ch
2012-12-10 12:57 ` dvyukov at google dot com
2012-12-10 12:59 ` Joost.VandeVondele at mat dot ethz.ch
2012-12-10 15:07 ` dvyukov at google dot com [this message]
2012-12-10 15:56 ` Joost.VandeVondele at mat dot ethz.ch
2012-12-11  9:48 ` [Bug sanitizer/55561] TSAN: Fortran/OMP yields false positives Joost.VandeVondele at mat dot ethz.ch
2012-12-25 19:30 ` Joost.VandeVondele at mat dot ethz.ch
2012-12-25 20:23 ` Joost.VandeVondele at mat dot ethz.ch
2012-12-26 19:35 ` Joost.VandeVondele at mat dot ethz.ch
2012-12-29  9:33 ` dvyukov at google dot com
2012-12-29  9:38 ` dvyukov at google dot com
2012-12-29 10:13 ` dvyukov at google dot com
2012-12-29 10:21 ` dvyukov at google dot com
2012-12-30  9:03 ` Joost.VandeVondele at mat dot ethz.ch
2012-12-30  9:58 ` dvyukov at google dot com
2012-12-30 10:11 ` dvyukov at google dot com
2012-12-30 14:53 ` Joost.VandeVondele at mat dot ethz.ch
2012-12-30 17:07 ` dvyukov at google dot com
2012-12-30 19:57 ` Joost.VandeVondele at mat dot ethz.ch
2013-01-01 17:14 ` Joost.VandeVondele at mat dot ethz.ch
2013-01-02  9:09 ` dvyukov at google dot com
2013-01-02  9:44 ` jakub at gcc dot gnu.org
2013-01-02 10:28 ` dvyukov at google dot com
2013-01-07 21:35 ` Joost.VandeVondele at mat dot ethz.ch
2013-01-08  9:17 ` dvyukov at google dot com
2013-01-10 11:27 ` Joost.VandeVondele at mat dot ethz.ch
2013-01-10 11:37 ` jakub at gcc dot gnu.org
2013-01-31  7:43 ` amodra at gmail dot com
2013-01-31 14:29 ` jakub at gcc dot gnu.org
2013-01-31 16:57 ` jakub at gcc dot gnu.org
2013-02-01 20:00 ` dvyukov at google dot com
2013-03-29  8:11 ` [Bug sanitizer/55561] TSAN: provide a TSAN instrumented libgomp Joost.VandeVondele at mat dot ethz.ch
2013-06-03 13:21 ` dvyukov at google dot com
2014-01-21 12:44 ` emil.styrke at gmail dot com
2014-01-22  8:14 ` Joost.VandeVondele at mat dot ethz.ch
2014-05-08 19:49 ` roland at rschulz dot eu
2014-05-09  5:38 ` Joost.VandeVondele at mat dot ethz.ch
2014-05-09 10:26 ` dvyukov at google dot com
2014-05-14 19:17 ` Joost.VandeVondele at mat dot ethz.ch
2014-05-14 19:25 ` dvyukov at google dot com
2014-07-09  6:07 ` roland at rschulz dot eu
2014-07-09  7:12 ` jakub at gcc dot gnu.org
2014-07-09  7:17 ` Joost.VandeVondele at mat dot ethz.ch
2024-02-29 17:27 ` egallager at gcc dot gnu.org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-55561-4-b8jCrBKEdP@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).