Skip to content
Snippets Groups Projects
Commit a07f76c6 authored by nitsanw's avatar nitsanw Committed by Sean Busbey
Browse files

[client] Switch to managing time in nanoseconds in the ClientThread

parent 9ba89cb5
No related branches found
No related tags found
No related merge requests found
...@@ -28,6 +28,7 @@ import java.util.Date; ...@@ -28,6 +28,7 @@ import java.util.Date;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Properties; import java.util.Properties;
import java.util.Vector; import java.util.Vector;
import java.util.concurrent.locks.LockSupport;
import com.yahoo.ycsb.measurements.Measurements; import com.yahoo.ycsb.measurements.Measurements;
import com.yahoo.ycsb.measurements.exporter.MeasurementsExporter; import com.yahoo.ycsb.measurements.exporter.MeasurementsExporter;
...@@ -144,13 +145,14 @@ class ClientThread extends Thread ...@@ -144,13 +145,14 @@ class ClientThread extends Thread
boolean _dotransactions; boolean _dotransactions;
Workload _workload; Workload _workload;
int _opcount; int _opcount;
double _target; double _targetOpsPerMs;
int _opsdone; int _opsdone;
int _threadid; int _threadid;
int _threadcount; int _threadcount;
Object _workloadstate; Object _workloadstate;
Properties _props; Properties _props;
private long _targetOpsTickNs;
/** /**
...@@ -173,7 +175,10 @@ class ClientThread extends Thread ...@@ -173,7 +175,10 @@ class ClientThread extends Thread
_workload=workload; _workload=workload;
_opcount=opcount; _opcount=opcount;
_opsdone=0; _opsdone=0;
_target=targetperthreadperms; if(targetperthreadperms > 0){
_targetOpsPerMs=targetperthreadperms;
_targetOpsTickNs=(long)(1000000/_targetOpsPerMs);
}
_threadid=threadid; _threadid=threadid;
_threadcount=threadcount; _threadcount=threadcount;
_props=props; _props=props;
...@@ -209,26 +214,22 @@ class ClientThread extends Thread ...@@ -209,26 +214,22 @@ class ClientThread extends Thread
return; return;
} }
//spread the thread operations out so they don't all hit the DB at the same time //NOTE: Switching to using nanoTime and parkNanos for time management here such that the measurements
try // and the client thread have the same view on time.
{
//GH issue 4 - throws exception if _target>1 because random.nextInt argument must be >0
//and the sleep() doesn't make sense for granularities < 1 ms anyway
if ( (_target>0) && (_target<=1.0) )
{
sleep(Utils.random().nextInt((int)(1.0/_target)));
}
}
catch (InterruptedException e)
{
// do nothing.
}
//spread the thread operations out so they don't all hit the DB at the same time
// GH issue 4 - throws exception if _target>1 because random.nextInt argument must be >0
// and the sleep() doesn't make sense for granularities < 1 ms anyway
if ((_targetOpsPerMs > 0) && (_targetOpsPerMs <= 1.0))
{
long randomMinorDelay = Utils.random().nextInt((int) _targetOpsTickNs);
sleepUntil(System.nanoTime() + randomMinorDelay);
}
try try
{ {
if (_dotransactions) if (_dotransactions)
{ {
long st=System.currentTimeMillis(); long startTimeNanos = System.nanoTime();
while (((_opcount == 0) || (_opsdone < _opcount)) && !_workload.isStopRequested()) while (((_opcount == 0) || (_opsdone < _opcount)) && !_workload.isStopRequested())
{ {
...@@ -240,13 +241,13 @@ class ClientThread extends Thread ...@@ -240,13 +241,13 @@ class ClientThread extends Thread
_opsdone++; _opsdone++;
throttle(st); throttleNanos(startTimeNanos);
} }
} }
else else
{ {
long st=System.currentTimeMillis(); long startTimeNanos = System.nanoTime();
while (((_opcount == 0) || (_opsdone < _opcount)) && !_workload.isStopRequested()) while (((_opcount == 0) || (_opsdone < _opcount)) && !_workload.isStopRequested())
{ {
...@@ -257,7 +258,7 @@ class ClientThread extends Thread ...@@ -257,7 +258,7 @@ class ClientThread extends Thread
_opsdone++; _opsdone++;
throttle(st); throttleNanos(startTimeNanos);
} }
} }
} }
...@@ -280,27 +281,22 @@ class ClientThread extends Thread ...@@ -280,27 +281,22 @@ class ClientThread extends Thread
} }
} }
private void throttle(long currTimeMillis) { private void sleepUntil(long deadline) {
long now = System.nanoTime();
while((now = System.nanoTime()) < deadline) {
LockSupport.parkNanos(deadline - now);
}
}
private long throttleNanos(long startTimeNanos) {
//throttle the operations //throttle the operations
if (_target>0) if (_targetOpsPerMs > 0)
{ {
//this is more accurate than other throttling approaches we have tried, // delay until next tick
//like sleeping for (1/target throughput)-operation latency, long deadline = startTimeNanos + _opsdone*_targetOpsTickNs;
//because it smooths timing inaccuracies (from sleep() taking an int, sleepUntil(deadline);
//current time in millis) over many operations return deadline;
while (System.currentTimeMillis()-currTimeMillis<((double)_opsdone)/_target)
{
try
{
sleep(1);
}
catch (InterruptedException e)
{
// do nothing.
}
}
} }
return -1;
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment