12a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson//===- RWMutex.cpp - Reader/Writer Mutual Exclusion Lock --------*- C++ -*-===//
22a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson//
32a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson//                     The LLVM Compiler Infrastructure
42a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson//
52a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson// This file is distributed under the University of Illinois Open Source
62a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson// License. See LICENSE.TXT for details.
72a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson//
82a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson//===----------------------------------------------------------------------===//
92a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson//
102a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson// This file implements the llvm::sys::RWMutex class.
112a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson//
122a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson//===----------------------------------------------------------------------===//
132a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson
142a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#include "llvm/Config/config.h"
151f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/RWMutex.h"
16107a537db1261c09f8c9639ef7827b12f0812125Owen Anderson#include <cstring>
172a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson
182a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson//===----------------------------------------------------------------------===//
192a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson//=== WARNING: Implementation here must contain only TRULY operating system
202a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson//===          independent code.
212a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson//===----------------------------------------------------------------------===//
222a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson
2308b73a30bbb6407c7b48a734a29f65f4c8ddd782Dylan Noblesmith#if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0
242a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson// Define all methods as no-ops if threading is explicitly disabled
252a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Andersonnamespace llvm {
262a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Andersonusing namespace sys;
27b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen AndersonRWMutexImpl::RWMutexImpl() { }
28b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen AndersonRWMutexImpl::~RWMutexImpl() { }
29b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen Andersonbool RWMutexImpl::reader_acquire() { return true; }
30b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen Andersonbool RWMutexImpl::reader_release() { return true; }
31b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen Andersonbool RWMutexImpl::writer_acquire() { return true; }
32b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen Andersonbool RWMutexImpl::writer_release() { return true; }
332a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson}
342a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#else
352a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson
362a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_RWLOCK_INIT)
372a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson
382a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#include <cassert>
392a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#include <pthread.h>
402a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#include <stdlib.h>
412a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson
422a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Andersonnamespace llvm {
432a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Andersonusing namespace sys;
442a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson
452a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson// Construct a RWMutex using pthread calls
46b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen AndersonRWMutexImpl::RWMutexImpl()
472a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson  : data_(0)
482a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson{
4949c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  // Declare the pthread_rwlock data structures
5049c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  pthread_rwlock_t* rwlock =
5149c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie    static_cast<pthread_rwlock_t*>(malloc(sizeof(pthread_rwlock_t)));
52107a537db1261c09f8c9639ef7827b12f0812125Owen Anderson
53107a537db1261c09f8c9639ef7827b12f0812125Owen Anderson#ifdef __APPLE__
5449c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  // Workaround a bug/mis-feature in Darwin's pthread_rwlock_init.
5549c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  bzero(rwlock, sizeof(pthread_rwlock_t));
56107a537db1261c09f8c9639ef7827b12f0812125Owen Anderson#endif
57107a537db1261c09f8c9639ef7827b12f0812125Owen Anderson
5849c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  // Initialize the rwlock
5949c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  int errorcode = pthread_rwlock_init(rwlock, NULL);
6049c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  (void)errorcode;
6149c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  assert(errorcode == 0);
622a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson
6349c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  // Assign the data member
6449c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  data_ = rwlock;
652a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson}
662a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson
672a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson// Destruct a RWMutex
68b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen AndersonRWMutexImpl::~RWMutexImpl()
692a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson{
7049c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
7149c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  assert(rwlock != 0);
7249c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  pthread_rwlock_destroy(rwlock);
7349c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  free(rwlock);
742a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson}
752a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson
762a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Andersonbool
77b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen AndersonRWMutexImpl::reader_acquire()
782a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson{
7949c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
8049c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  assert(rwlock != 0);
8149c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie
8249c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  int errorcode = pthread_rwlock_rdlock(rwlock);
8349c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  return errorcode == 0;
842a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson}
852a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson
862a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Andersonbool
87b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen AndersonRWMutexImpl::reader_release()
882a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson{
8949c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
9049c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  assert(rwlock != 0);
9149c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie
9249c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  int errorcode = pthread_rwlock_unlock(rwlock);
9349c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  return errorcode == 0;
942a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson}
952a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson
962a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Andersonbool
97b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen AndersonRWMutexImpl::writer_acquire()
982a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson{
9949c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
10049c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  assert(rwlock != 0);
10149c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie
10249c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  int errorcode = pthread_rwlock_wrlock(rwlock);
10349c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  return errorcode == 0;
1042a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson}
1052a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson
1062a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Andersonbool
107b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen AndersonRWMutexImpl::writer_release()
1082a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson{
10949c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
11049c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  assert(rwlock != 0);
11149c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie
11249c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  int errorcode = pthread_rwlock_unlock(rwlock);
11349c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie  return errorcode == 0;
1142a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson}
1152a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson
1162a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson}
1172a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson
1182a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#elif defined(LLVM_ON_UNIX)
1192a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#include "Unix/RWMutex.inc"
1202a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#elif defined( LLVM_ON_WIN32)
1211f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "Windows/RWMutex.inc"
1222a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#else
1232c607b665dbeb52e2ade86f0e1f191695290da3bDaniel Dunbar#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in Support/Mutex.cpp
1242a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#endif
1252a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#endif
126