Bladeren bron

timer: fix sleep timer misalignment issue

Nick Peng 1 maand geleden
bovenliggende
commit
9563b97a7a
4 gewijzigde bestanden met toevoegingen van 78 en 110 verwijderingen
  1. 24 34
      src/dns_client/dns_client.c
  2. 22 30
      src/dns_server/dns_server.c
  3. 18 23
      src/fast_ping/fast_ping.c
  4. 14 23
      src/lib/timer_wheel.c

+ 24 - 34
src/dns_client/dns_client.c

@@ -556,56 +556,46 @@ static void *_dns_client_work(void *arg)
 	int num = 0;
 	int i = 0;
 	unsigned long now = {0};
-	unsigned long last = {0};
 	unsigned int msec = 0;
 	unsigned int sleep = 100;
 	int sleep_time = 0;
 	unsigned long expect_time = 0;
-	int unused __attribute__((unused));
+	unsigned long start_time = 0;
 
-	sleep_time = sleep;
-	now = get_tick_count() - sleep;
-	last = now;
+	now = get_tick_count();
+	start_time = now;
 	expect_time = now + sleep;
+	
 	while (atomic_read(&client.run)) {
 		now = get_tick_count();
-		if (sleep_time > 0) {
-			sleep_time -= now - last;
-			if (sleep_time <= 0) {
-				sleep_time = 0;
-			}
-
-			int cnt = sleep_time / sleep;
-			msec -= cnt;
-			expect_time -= cnt * sleep;
-			sleep_time -= cnt * sleep;
-		}
-
+		
 		if (now >= expect_time) {
-			msec++;
-			if (last != now) {
-				_dns_client_period_run(msec);
+			unsigned long elapsed_from_start = now - start_time;
+			unsigned int current_period = (elapsed_from_start + sleep / 2) / sleep; 
+			
+			if (current_period > msec) {
+				msec = current_period;
 			}
-
-			sleep_time = sleep - (now - expect_time);
-			if (sleep_time < 0) {
-				sleep_time = 0;
-				expect_time = now;
-			}
-
+			
+			expect_time = start_time + (msec + 1) * sleep;
+			_dns_client_period_run(msec);
+			msec++;
+			
 			/* When client is idle, the sleep time is 1000ms, to reduce CPU usage */
 			pthread_mutex_lock(&client.domain_map_lock);
 			if (list_empty(&client.dns_request_list)) {
-				int cnt = 10 - (msec % 10) - 1;
-				sleep_time += sleep * cnt;
-				msec += cnt;
-				/* sleep to next second */
-				expect_time += sleep * cnt;
+				if (msec % 10 != 0) {
+					msec = ((msec / 10) + 1) * 10;
+					expect_time = start_time + msec * sleep;
+				}
 			}
 			pthread_mutex_unlock(&client.domain_map_lock);
-			expect_time += sleep;
 		}
-		last = now;
+		
+		sleep_time = (int)(expect_time - now);
+		if (sleep_time < 0) {
+			sleep_time = 0;
+		}
 
 		num = epoll_wait(client.epoll_fd, events, DNS_MAX_EVENTS, sleep_time);
 		if (num < 0) {

+ 22 - 30
src/dns_server/dns_server.c

@@ -717,54 +717,46 @@ int dns_server_run(void)
 	int num = 0;
 	int i = 0;
 	unsigned long now = {0};
-	unsigned long last = {0};
 	unsigned int msec = 0;
 	int sleep = 100;
 	int sleep_time = 0;
 	unsigned long expect_time = 0;
+	unsigned long start_time = 0;
 
-	sleep_time = sleep;
-	now = get_tick_count() - sleep;
-	last = now;
+	now = get_tick_count();
+	start_time = now;
 	expect_time = now + sleep;
+
 	while (atomic_read(&server.run)) {
 		now = get_tick_count();
-		if (sleep_time > 0) {
-			sleep_time -= now - last;
-			if (sleep_time <= 0) {
-				sleep_time = 0;
-			}
-
-			int cnt = sleep_time / sleep;
-			msec -= cnt;
-			expect_time -= cnt * sleep;
-			sleep_time -= cnt * sleep;
-		}
 
 		if (now >= expect_time) {
-			msec++;
-			if (last != now) {
-				_dns_server_period_run(msec);
-			}
-			sleep_time = sleep - (now - expect_time);
-			if (sleep_time < 0) {
-				sleep_time = 0;
-				expect_time = now;
+			unsigned long elapsed_from_start = now - start_time;
+			unsigned int current_period = (elapsed_from_start + sleep / 2) / sleep;
+
+			if (current_period > msec) {
+				msec = current_period;
 			}
+			expect_time = start_time + (msec + 1) * sleep;
+
+			_dns_server_period_run(msec);
+			msec++;
 
 			/* When server is idle, the sleep time is 1000ms, to reduce CPU usage */
 			pthread_mutex_lock(&server.request_list_lock);
 			if (list_empty(&server.request_list)) {
-				int cnt = 10 - (msec % 10) - 1;
-				sleep_time += sleep * cnt;
-				msec += cnt;
-				/* sleep to next second */
-				expect_time += sleep * cnt;
+				if (msec % 10 != 0) {
+					msec = ((msec / 10) + 1) * 10;
+					expect_time = start_time + msec * sleep;
+				}
 			}
 			pthread_mutex_unlock(&server.request_list_lock);
-			expect_time += sleep;
 		}
-		last = now;
+
+		sleep_time = (int)(expect_time - now);
+		if (sleep_time < 0) {
+			sleep_time = 0;
+		}
 
 		num = epoll_wait(server.epoll_fd, events, DNS_MAX_EVENTS, sleep_time);
 		if (num < 0) {

+ 18 - 23
src/fast_ping/fast_ping.c

@@ -452,43 +452,36 @@ static void *_fast_ping_work(void *arg)
 	int num = 0;
 	int i = 0;
 	unsigned long now = {0};
-	unsigned long last = {0};
 	struct timeval tvnow = {0};
 	int sleep = 100;
 	int sleep_time = 0;
 	unsigned long expect_time = 0;
+	unsigned long start_time = 0;
 
 	setpriority(PRIO_PROCESS, 0, -5);
 
-	sleep_time = sleep;
-	now = get_tick_count() - sleep;
-	last = now;
+	now = get_tick_count();
+	start_time = now;
 	expect_time = now + sleep;
+	
 	while (atomic_read(&ping.run)) {
 		now = get_tick_count();
-		if (sleep_time > 0) {
-			sleep_time -= now - last;
-			if (sleep_time <= 0) {
-				sleep_time = 0;
-			}
-		}
-
+		
 		if (now >= expect_time) {
-			if (last != now) {
-				_fast_ping_period_run();
-			}
-			sleep_time = sleep - (now - expect_time);
-			if (sleep_time < 0) {
-				sleep_time = 0;
-				expect_time = now;
-			}
-			expect_time += sleep;
+			_fast_ping_period_run();
+			unsigned long elapsed_from_start = now - start_time;
+			unsigned long next_period = (elapsed_from_start / sleep) + 1;
+			expect_time = start_time + next_period * sleep;
+		}
+		
+		sleep_time = (int)(expect_time - now);
+		if (sleep_time < 0) {
+			sleep_time = 0;
 		}
-		last = now;
 
 		pthread_mutex_lock(&ping.map_lock);
 		if (hash_empty(ping.addrmap)) {
-			sleep_time = -1;
+			sleep_time = -1; 
 		}
 		pthread_mutex_unlock(&ping.map_lock);
 
@@ -499,7 +492,9 @@ static void *_fast_ping_work(void *arg)
 		}
 
 		if (sleep_time == -1) {
-			expect_time = get_tick_count();
+			now = get_tick_count();
+			start_time = now;
+			expect_time = now + sleep;
 		}
 
 		if (num == 0) {

+ 14 - 23
src/lib/timer_wheel.c

@@ -295,40 +295,31 @@ static unsigned long _tw_tick_count(void)
 static void *timer_work(void *arg)
 {
 	struct tw_base *base = arg;
-	int sleep = 1000;
+	int sleep = 1000; 
 	int sleep_time = 0;
 	unsigned long now = {0};
-	unsigned long last = {0};
 	unsigned long expect_time = 0;
+	unsigned long start_time = 0;
 
-	sleep_time = sleep;
-	now = _tw_tick_count() - sleep;
-	last = now;
+	now = _tw_tick_count();
+	start_time = now;
 	expect_time = now + sleep;
+	
 	while (1) {
 		run_timers(base);
 
 		now = _tw_tick_count();
-		if (sleep_time > 0) {
-			sleep_time -= now - last;
-			if (sleep_time <= 0) {
-				sleep_time = 0;
-			}
-
-			int cnt = sleep_time / sleep;
-			expect_time -= cnt * sleep;
-			sleep_time -= cnt * sleep;
-		}
-
+		
 		if (now >= expect_time) {
-			sleep_time = sleep - (now - expect_time);
-			if (sleep_time < 0) {
-				sleep_time = 0;
-				expect_time = now;
-			}
-			expect_time += sleep;
+			unsigned long elapsed_from_start = now - start_time;
+			unsigned long next_period = (elapsed_from_start / sleep) + 1;
+			expect_time = start_time + next_period * sleep;
+		}
+		
+		sleep_time = (int)(expect_time - now);
+		if (sleep_time < 0) {
+			sleep_time = 0;
 		}
-		last = now;
 
 		usleep(sleep_time * 1000);
 	}