summaryrefslogtreecommitdiffstats
path: root/UnixPkg
diff options
context:
space:
mode:
authorandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>2011-03-22 20:30:35 +0000
committerandrewfish <andrewfish@6f19259b-4bc3-4df7-8a09-765794883524>2011-03-22 20:30:35 +0000
commitb5b1aca92b2793175d3662071fd288d84c6f18c8 (patch)
treec12f1dc0e2891099557a830c4e681939d7e020ed /UnixPkg
parent667bf1e48f1af4e9bba3d6d2805ec2fbb1b145c6 (diff)
downloadedk2-b5b1aca92b2793175d3662071fd288d84c6f18c8.tar.gz
edk2-b5b1aca92b2793175d3662071fd288d84c6f18c8.tar.bz2
edk2-b5b1aca92b2793175d3662071fd288d84c6f18c8.zip
Fix gBS->Stall bug. The current code would only stall for a single timer tick. Fixing this issue exposed another issue with time slip in the stall that was also fixed.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11414 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'UnixPkg')
-rw-r--r--UnixPkg/Sec/UnixThunk.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/UnixPkg/Sec/UnixThunk.c b/UnixPkg/Sec/UnixThunk.c
index f65acab100..eb9e536989 100644
--- a/UnixPkg/Sec/UnixThunk.c
+++ b/UnixPkg/Sec/UnixThunk.c
@@ -142,17 +142,36 @@ void
msSleep (unsigned long Milliseconds)
{
struct timespec rq, rm;
-
+ struct timeval start, end;
+ unsigned long MicroSec;
+
rq.tv_sec = Milliseconds / 1000;
rq.tv_nsec = (Milliseconds % 1000) * 1000000;
- while (nanosleep (&rq, &rm) != -1) {
+ //
+ // nanosleep gets interrupted by our timer tic.
+ // we need to track wall clock time or we will stall for way too long
+ //
+ gettimeofday (&start, NULL);
+ end.tv_sec = start.tv_sec + rq.tv_sec;
+ MicroSec = (start.tv_usec + rq.tv_nsec/1000);
+ end.tv_usec = MicroSec % 1000000;
+ if (MicroSec > 1000000) {
+ end.tv_sec++;
+ }
+
+ while (nanosleep (&rq, &rm) == -1) {
if (errno != EINTR) {
break;
}
+ gettimeofday (&start, NULL);
+ if (start.tv_sec > end.tv_sec) {
+ break;
+ } if ((start.tv_sec == end.tv_sec) && (start.tv_usec > end.tv_usec)) {
+ break;
+ }
rq = rm;
}
-
}
void