Skip to content

Commit

Permalink
Fix a race reading 'warmingUp' to decide request kind
Browse files Browse the repository at this point in the history
Summary:There was a race reading the global 'warmingUp' flag which could potentially
cause a request to start JITing (and thus marking hot functions and freeing
s_func_counters) while later requests were still profiling (and thus writting to
s_func_counters).  This diff fixes the issue by reading the 'warmingUp' just
once per request to decide its kind.

Reviewed By: swtaarrs

Differential Revision: D3051381

fb-gh-sync-id: e1f2327526064aa9237d528e5dcc8fa787c24981
shipit-source-id: e1f2327526064aa9237d528e5dcc8fa787c24981
  • Loading branch information
ottoni authored and Hhvm Bot committed Mar 15, 2016
1 parent 0180e9d commit df46f65
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 10 deletions.
18 changes: 10 additions & 8 deletions hphp/runtime/vm/type-profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ void profileInit() {
* In server mode, we exclude warmup document requests from profiling, then
* record samples for EvalJitProfileInterpRequests standard requests.
*/
bool __thread profileOn = false;

RequestKind __thread requestKind = RequestKind::Warmup;
static bool warmingUp;
static int64_t numRequests;
bool __thread standardRequest = true;
Expand Down Expand Up @@ -161,17 +162,18 @@ static inline bool doneProfiling() {
!RuntimeOption::EvalJitProfileRecord);
}

static inline bool profileThisRequest() {
if (warmingUp) return false;
if (doneProfiling()) return false;
if (RuntimeOption::ServerExecutionMode()) return true;
return RuntimeOption::EvalJitProfileRecord;
static inline RequestKind getRequestKind() {
if (warmingUp) return RequestKind::Warmup;
if (doneProfiling()) return RequestKind::Standard;
if (RuntimeOption::ServerExecutionMode() ||
RuntimeOption::EvalJitProfileRecord) return RequestKind::Profile;
return RequestKind::Standard;
}

void profileRequestStart() {
profileOn = profileThisRequest();
requestKind = getRequestKind();

bool okToJit = !warmingUp && !profileOn;
bool okToJit = requestKind == RequestKind::Standard;
if (okToJit) {
jit::Lease::mayLock(true);
if (singleJitRequests < RuntimeOption::EvalNumSingleJitRequests) {
Expand Down
10 changes: 8 additions & 2 deletions hphp/runtime/vm/type-profile.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ namespace HPHP {

struct Func;

enum class RequestKind {
Warmup,
Profile,
Standard
};

//////////////////////////////////////////////////////////////////////

void profileInit();
Expand All @@ -43,9 +49,9 @@ int64_t requestCount();
*/
void profileIncrementFuncCounter(const Func*);

extern __thread bool profileOn;
extern __thread RequestKind requestKind;
inline bool isProfileRequest() {
return profileOn;
return requestKind == RequestKind::Profile;
}

extern __thread bool standardRequest;
Expand Down

0 comments on commit df46f65

Please sign in to comment.