Fix spilling bug
[hiphop-php.git] / hphp / runtime / vm / jit / writelease.h
blobd3ed59e9db137db97c36db7613185f69115d3c48
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
16 #ifndef incl_HPHP_WRITELEASE_H_
17 #define incl_HPHP_WRITELEASE_H_
19 #include "hphp/util/base.h"
21 #include <pthread.h>
23 namespace HPHP { namespace Transl {
26 * The write Lease guards write access to the translation caches,
27 * srcDB, and TransDB. The term "lease" is meant to indicate that
28 * the right of ownership is conferred for a long, variable time:
29 * often the entire length of a request. If a request is not
30 * actively translating, it will perform a "hinted drop" of the lease:
31 * the lease is unlocked but all calls to acquire(false) from other
32 * threads will fail for a short period of time.
35 struct Lease {
36 static const int64_t kStandardHintExpireInterval = 750;
37 pthread_t m_owner;
38 pthread_mutex_t m_lock;
39 // m_held: since there's no portable, universally invalid pthread_t,
40 // explicitly represent the held <-> unheld state machine.
41 volatile bool m_held;
42 int64_t m_hintExpire;
43 int64_t m_hintKept;
44 int64_t m_hintGrabbed;
46 Lease() : m_held(false), m_hintExpire(0), m_hintKept(0), m_hintGrabbed(0) {
47 pthread_mutex_init(&m_lock, nullptr);
49 ~Lease() {
50 if (m_held && m_owner == pthread_self()) {
51 // Can happen, e.g., in exception scenarios.
52 pthread_mutex_unlock(&m_lock);
54 pthread_mutex_destroy(&m_lock);
56 bool amOwner() const;
57 // acquire: also returns true if we are already the writer.
58 bool acquire(bool blocking = false);
59 void drop(int64_t hintExpireDelay = 0);
62 * A malevolent entity sometimes takes the write lease out from under us
63 * for debugging purposes.
65 void gremlinLock();
66 void gremlinUnlock() {
67 if (debug) { gremlinUnlockImpl(); }
70 private:
71 void gremlinUnlockImpl();
74 enum class LeaseAcquire {
75 ACQUIRE,
76 NO_ACQUIRE,
79 struct LeaseHolderBase {
80 protected:
81 LeaseHolderBase(Lease& l, LeaseAcquire acquire, bool blocking);
83 public:
84 ~LeaseHolderBase();
85 explicit operator bool() const { return m_haveLock; }
86 bool acquire();
88 private:
89 Lease& m_lease;
90 bool m_haveLock;
91 bool m_acquired;
93 struct LeaseHolder : public LeaseHolderBase {
94 explicit LeaseHolder(Lease& l, LeaseAcquire acquire = LeaseAcquire::ACQUIRE)
95 : LeaseHolderBase(l, acquire, false) {}
97 struct BlockingLeaseHolder : public LeaseHolderBase {
98 explicit BlockingLeaseHolder(Lease& l)
99 : LeaseHolderBase(l, LeaseAcquire::ACQUIRE, true) {}
102 }} // HPHP::Transl
104 #endif /* incl_HPHP_WRITELEASE_H_ */