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
This commit is contained in:
		@@ -142,17 +142,36 @@ void
 | 
				
			|||||||
msSleep (unsigned long Milliseconds)
 | 
					msSleep (unsigned long Milliseconds)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  struct timespec rq, rm;
 | 
					  struct timespec rq, rm;
 | 
				
			||||||
 | 
					  struct timeval  start, end;
 | 
				
			||||||
 | 
					  unsigned long  MicroSec;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  rq.tv_sec = Milliseconds / 1000;
 | 
					  rq.tv_sec = Milliseconds / 1000;
 | 
				
			||||||
  rq.tv_nsec = (Milliseconds % 1000) * 1000000;
 | 
					  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) {
 | 
					    if (errno != EINTR) {
 | 
				
			||||||
      break;
 | 
					      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;
 | 
					    rq = rm;
 | 
				
			||||||
  } 
 | 
					  } 
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user