blob: 6a34f2d08524fd43a95adf8fdbac734f0f0a446a [file] [log] [blame]
Owen Anderson2a8cf9a2009-06-16 20:19:28 +00001//===- RWMutex.cpp - Reader/Writer Mutual Exclusion Lock --------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the llvm::sys::RWMutex class.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Config/config.h"
Michael J. Spencer1f6efa32010-11-29 18:16:10 +000015#include "llvm/Support/RWMutex.h"
Owen Anderson107a5372009-06-20 00:32:27 +000016#include <cstring>
Owen Anderson2a8cf9a2009-06-16 20:19:28 +000017
18//===----------------------------------------------------------------------===//
19//=== WARNING: Implementation here must contain only TRULY operating system
20//=== independent code.
21//===----------------------------------------------------------------------===//
22
Dylan Noblesmith08b73a32011-11-28 00:48:58 +000023#if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0
Owen Anderson2a8cf9a2009-06-16 20:19:28 +000024// Define all methods as no-ops if threading is explicitly disabled
25namespace llvm {
26using namespace sys;
Owen Andersonb65e9ed2009-06-18 18:26:15 +000027RWMutexImpl::RWMutexImpl() { }
28RWMutexImpl::~RWMutexImpl() { }
29bool RWMutexImpl::reader_acquire() { return true; }
30bool RWMutexImpl::reader_release() { return true; }
31bool RWMutexImpl::writer_acquire() { return true; }
32bool RWMutexImpl::writer_release() { return true; }
Owen Anderson2a8cf9a2009-06-16 20:19:28 +000033}
34#else
35
36#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_RWLOCK_INIT)
37
38#include <cassert>
39#include <pthread.h>
40#include <stdlib.h>
41
42namespace llvm {
43using namespace sys;
44
Owen Anderson2a8cf9a2009-06-16 20:19:28 +000045// Construct a RWMutex using pthread calls
Owen Andersonb65e9ed2009-06-18 18:26:15 +000046RWMutexImpl::RWMutexImpl()
Owen Anderson2a8cf9a2009-06-16 20:19:28 +000047 : data_(0)
48{
David Blaikie49c0a9a2012-01-15 01:09:13 +000049 // Declare the pthread_rwlock data structures
50 pthread_rwlock_t* rwlock =
51 static_cast<pthread_rwlock_t*>(malloc(sizeof(pthread_rwlock_t)));
Owen Anderson107a5372009-06-20 00:32:27 +000052
53#ifdef __APPLE__
David Blaikie49c0a9a2012-01-15 01:09:13 +000054 // Workaround a bug/mis-feature in Darwin's pthread_rwlock_init.
55 bzero(rwlock, sizeof(pthread_rwlock_t));
Owen Anderson107a5372009-06-20 00:32:27 +000056#endif
57
David Blaikie49c0a9a2012-01-15 01:09:13 +000058 // Initialize the rwlock
59 int errorcode = pthread_rwlock_init(rwlock, NULL);
60 (void)errorcode;
61 assert(errorcode == 0);
Owen Anderson2a8cf9a2009-06-16 20:19:28 +000062
David Blaikie49c0a9a2012-01-15 01:09:13 +000063 // Assign the data member
64 data_ = rwlock;
Owen Anderson2a8cf9a2009-06-16 20:19:28 +000065}
66
67// Destruct a RWMutex
Owen Andersonb65e9ed2009-06-18 18:26:15 +000068RWMutexImpl::~RWMutexImpl()
Owen Anderson2a8cf9a2009-06-16 20:19:28 +000069{
David Blaikie49c0a9a2012-01-15 01:09:13 +000070 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
71 assert(rwlock != 0);
72 pthread_rwlock_destroy(rwlock);
73 free(rwlock);
Owen Anderson2a8cf9a2009-06-16 20:19:28 +000074}
75
76bool
Owen Andersonb65e9ed2009-06-18 18:26:15 +000077RWMutexImpl::reader_acquire()
Owen Anderson2a8cf9a2009-06-16 20:19:28 +000078{
David Blaikie49c0a9a2012-01-15 01:09:13 +000079 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
80 assert(rwlock != 0);
Owen Anderson2a8cf9a2009-06-16 20:19:28 +000081
David Blaikie49c0a9a2012-01-15 01:09:13 +000082 int errorcode = pthread_rwlock_rdlock(rwlock);
83 return errorcode == 0;
Owen Anderson2a8cf9a2009-06-16 20:19:28 +000084}
85
86bool
Owen Andersonb65e9ed2009-06-18 18:26:15 +000087RWMutexImpl::reader_release()
Owen Anderson2a8cf9a2009-06-16 20:19:28 +000088{
David Blaikie49c0a9a2012-01-15 01:09:13 +000089 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
90 assert(rwlock != 0);
Owen Anderson2a8cf9a2009-06-16 20:19:28 +000091
David Blaikie49c0a9a2012-01-15 01:09:13 +000092 int errorcode = pthread_rwlock_unlock(rwlock);
93 return errorcode == 0;
Owen Anderson2a8cf9a2009-06-16 20:19:28 +000094}
95
96bool
Owen Andersonb65e9ed2009-06-18 18:26:15 +000097RWMutexImpl::writer_acquire()
Owen Anderson2a8cf9a2009-06-16 20:19:28 +000098{
David Blaikie49c0a9a2012-01-15 01:09:13 +000099 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
100 assert(rwlock != 0);
Owen Anderson2a8cf9a2009-06-16 20:19:28 +0000101
David Blaikie49c0a9a2012-01-15 01:09:13 +0000102 int errorcode = pthread_rwlock_wrlock(rwlock);
103 return errorcode == 0;
Owen Anderson2a8cf9a2009-06-16 20:19:28 +0000104}
105
106bool
Owen Andersonb65e9ed2009-06-18 18:26:15 +0000107RWMutexImpl::writer_release()
Owen Anderson2a8cf9a2009-06-16 20:19:28 +0000108{
David Blaikie49c0a9a2012-01-15 01:09:13 +0000109 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
110 assert(rwlock != 0);
Owen Anderson2a8cf9a2009-06-16 20:19:28 +0000111
David Blaikie49c0a9a2012-01-15 01:09:13 +0000112 int errorcode = pthread_rwlock_unlock(rwlock);
113 return errorcode == 0;
Owen Anderson2a8cf9a2009-06-16 20:19:28 +0000114}
115
116}
117
118#elif defined(LLVM_ON_UNIX)
119#include "Unix/RWMutex.inc"
120#elif defined( LLVM_ON_WIN32)
Michael J. Spencer1f6efa32010-11-29 18:16:10 +0000121#include "Windows/RWMutex.inc"
Owen Anderson2a8cf9a2009-06-16 20:19:28 +0000122#else
Daniel Dunbar2c607b62011-10-11 20:02:52 +0000123#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in Support/Mutex.cpp
Owen Anderson2a8cf9a2009-06-16 20:19:28 +0000124#endif
125#endif