Basic JIT support for Records
[hiphop-php.git] / hphp / runtime / vm / treadmill-inl.h
blobec046bacc2d450d625a2312336a504276a8ce1ee
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present 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_TREADMILL_INL_H_
17 #define incl_HPHP_TREADMILL_INL_H_
19 #include "hphp/runtime/base/rds-local.h"
21 #include <folly/Likely.h>
23 #include <atomic>
24 #include <memory>
25 #include <utility>
27 namespace HPHP { namespace Treadmill {
29 extern std::atomic<int64_t> g_nextThreadIdx;
30 extern RDS_LOCAL_NO_CHECK(int64_t, rl_thisRequestIdx);
32 inline int64_t requestIdx() {
33 if (UNLIKELY(*rl_thisRequestIdx == kInvalidRequestIdx)) {
34 *rl_thisRequestIdx =
35 g_nextThreadIdx.fetch_add(1, std::memory_order_relaxed);
37 return *rl_thisRequestIdx;
40 //////////////////////////////////////////////////////////////////////
42 struct WorkItem;
43 void enqueueInternal(std::unique_ptr<WorkItem>);
45 //////////////////////////////////////////////////////////////////////
47 using GenCount = int64_t;
49 struct WorkItem {
50 WorkItem() = default;
51 WorkItem(const WorkItem&) = delete;
52 WorkItem& operator=(const WorkItem&) = delete;
53 virtual ~WorkItem() {}
55 virtual void run() noexcept = 0;
57 private:
58 friend void finishRequest();
59 friend void enqueueInternal(std::unique_ptr<WorkItem>);
61 private:
62 // Inherently racy. We get a lower bound on the generation;
63 // presumably clients are aware of this, and are creating the
64 // trigger for an object that was reachable strictly in the past.
65 GenCount m_gen{0};
68 template<class F>
69 struct WorkItemImpl final : WorkItem {
70 explicit WorkItemImpl(F&& f) : f(std::forward<F>(f)) {}
72 void run() noexcept override { f(); }
74 private:
75 F f;
78 template<class F>
79 void enqueue(F&& f) {
80 std::unique_ptr<WorkItemImpl<F>> p(new WorkItemImpl<F>(std::forward<F>(f)));
81 enqueueInternal(std::move(p));
84 //////////////////////////////////////////////////////////////////////
88 #endif