2010-09-07 9 views
25

Gente, en mi aplicación estoy usando clock_gettime(CLOCK_MONOTONIC) para medir el tiempo delta entre fotogramas (un enfoque típico en gamedev) y de vez en cuando estoy frente a un extraño comportamiento de clock_gettime(..) - los valores devueltos ocasionalmente no son monótonos (es decir, el tiempo anterior es mayor que la hora actual).Linux clock_gettime (CLOCK_MONOTONIC) extraño comportamiento no monótono

Actualmente, si ocurre una paradoja, simplemente salteo el marco actual y empiezo a procesar el siguiente.

La pregunta es ¿cómo puede esto ser posible en absoluto? ¿Es un error en la implementación POSIX de Linux de clock_gettime? Estoy usando Ubuntu Server Edition 10.04 (kernel 2.6.32-24, x86_64), gcc-4.4.3.

+0

¿Lo está ejecutando en un entorno virtualizado por casualidad? – caf

+0

No, no hay virtualización involucrada – pachanga

Respuesta

22

man clock_gettime dice:

CLOCK_MONOTONIC_RAW (desde la versión 2.6.28; específica de Linux)

similares a CLOCK_MONOTONIC, sino que proporciona acceso a una época basada en hardware prima que no está sujeta a Ajustes NTP.

Desde CLOCK_MONOTONIC_RAW no es objeto de correcciones de NTP, supongo que podría ser CLOCK_MONOTONIC.

Tuvimos problemas similares con Redhat Enterprise 5.0 con kernel 2.6.18 y algunos procesadores Itanium específicos. No pudimos reproducirlo con otro procesador en el mismo sistema operativo. Se corrigió en RHEL 5.3 con kernel ligeramente nuevo y algunos parches Redhat.

+0

Gracias por el consejo. Otra lección para mí: nunca confíe absolutamente ni siquiera en las bibliotecas más confiables :) – pachanga

+0

Interesante. Pero de acuerdo con http://markmail.org/thread/54bb663vi47kjxnu incluso CLOCK_MONOTONIC se supone que no puede saltar. Entonces, ¿no debería ser siempre al menos cada vez mayor? – Thomas

+0

Dice que el reloj puede girar (puede ir hacia atrás IIUC), por lo que podría estar disminuyendo. –

6

Probar CLOCK_MONOTONIC_RAW.

4

Claro que suena como un error para mí. Quizás deba informarlo en Ubuntu's bug tracker.

+5

Los rastreadores de errores son buenos, al igual que los errores que se envían (que todo el mundo debería hacer), pero no son populares porque los programadores quieren correcciones AHORA. Generalmente, los errores iniciales no se corrigen hasta mucho después de que hayas terminado de codificar la mayor parte del proyecto, y tienes que ayudar a las personas que no actualizaron las librerías ascendentes durante mucho tiempo de todos modos. :( –

+0

Tan triste, tan cierto ... – pachanga

21

Parece que una instancia de

commit 0696b711e4be45fa104c12329f617beb29c03f78 
Author: Lin Ming <[email protected]> 
Date: Tue Nov 17 13:49:50 2009 +0800 

timekeeping: Fix clock_gettime vsyscall time warp 

Since commit 0a544198 "timekeeping: Move NTP adjusted clock 
multiplier to struct timekeeper" the clock multiplier of vsyscall is updated with 
the unmodified clock multiplier of the clock source and not with the 
NTP adjusted multiplier of the timekeeper. 

This causes user space observerable time warps: 
new CLOCK-warp maximum: 120 nsecs, 00000025c337c537 -> 00000025c337c4bf 

Ver here para un parche. Esto se incluyó en 2.6.32.19, pero es posible que el equipo de Debian no lo haya respaldado (?). Usted deberia comprobar esto.

-1

Es un error de Linux. Ningún ajuste en un reloj monótono puede hacer que retroceda. Estás usando un kernel muy antiguo y una distribución muy antigua.

Editar: ¿Está seguro de que necesita saltarse el marco? Si llama de nuevo a clock_gettime, ¿qué ocurre?