New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change clock source to CLOCK_MONOTONIC in 'pthread_cond_timedwait' : Update mono-os-mutex.h #3828

Closed
wants to merge 3 commits into
base: master
from

Conversation

Projects
None yet
5 participants
@jaymin1328
Contributor

jaymin1328 commented Oct 26, 2016

'Wait' functions for Mutex, Semaphore and Condition (like "pthread_cond_timedwait") for 'task' synchronisation in Linux uses CLOCK_REALTIME by default,
this creates many problems where a process changes time. e.g. Command line utility < date -s "desired date and time" >
A thread may be blocked for a more\less time depending upon time change. It is always desirable to use clock source immune to such changes
http://stackoverflow.com/questions/14248033/clock-monotonic-and-pthread-mutex-timedlock-pthread-cond-timedwait
http://stackoverflow.com/a/14397906/7042283

http://stackoverflow.com/questions/3006259/what-time-function-do-i-need-to-use-with-pthread-cond-timedwait
However, it is not possible to change clock source for mutex and semaphore wait functions in Linux. So changing it for condition only

This can be seen by a simple application if you make a simple timer using System.Timers.Timer and print time stamp every regular interval say 2 seconds, now if time shifts in the system for whatever reason ( you can do this in Linux by <sudo date -s "Wed Oct 26 20:25:24 IST 2016"> put desired time in quotes), this print stops coming for the offset time duration.

The reason behind this is the call to 'pthread_cond_timedwait' function, by Timer class which uses it to sleep for timeout duration. Now this function uses CLOCK_REALTIME which can be changed, so if you change this clock, a thread will be blocked for the unexpected time. So using CLOCK_MONOTONIC removes the error.

There are many embedded systems which do not have RTC and rely upon the external time like systems using GPS or set top box. So this fix is inevitable for them, at least for condition variable wait.

This is the sample code

`using System;
using System.Timers;

public class Example
{
private static System.Timers.Timer aTimer;

public static void Main()
{
    SetTimer();

    Console.WriteLine("\nPress the Enter key to exit the application...\n");
    Console.WriteLine("The application started at {0:HH:mm:ss.fff}", DateTime.Now);
    Console.ReadLine();
    aTimer.Stop();
    aTimer.Dispose();

    Console.WriteLine("Terminating the application...");
}

private static void SetTimer()
{
    // Create a timer with a two second interval.
    aTimer = new System.Timers.Timer(2000);
    // Hook up the Elapsed event for the timer. 
    //((System.ComponentModel.ISupportInitialize)(aTimer)).BeginInit();
    aTimer.Elapsed += OnTimedEvent;
    //((System.ComponentModel.ISupportInitialize)(aTimer)).EndInit();
    aTimer.AutoReset = true;
    aTimer.Enabled = true;
}

private static void OnTimedEvent(Object source, ElapsedEventArgs e)
{
    Console.WriteLine("__The Elapsed event was raised at {0:HH:mm:ss.fff}",
                      e.SignalTime);
}

}`

Update mono-os-mutex.h
 Wait functions for Mutex, Semaphore and Condition (like pthread_cond_timedwait) for 'task' synchronisation in Linux uses CLOCK_REALTIME by default, 
this creates many problems where a process changes time. e.g. Command line utility < date -s "desired date and time" >
A thread may be blocked for a more\less time depending upon time change. It is always desirable to use clock source immune to such changes
However, it is not possible to change clock source for mutex and semaphore wait functions in Linux. So changing it for condition only

This can be seen by a simple application if you make a simple timer using System.Timers.Timer and print time stamp every regular interval say 2 seconds, now if time shifts in the system for whatever reason ( you can do this in Linux by <sudo date -s "Wed Oct 26 20:25:24 IST 2016"> put desired time in quotes), this print stops coming for the offset time duration. 

The reason behind this is the call to 'pthread_cond_timedwait' function, by Timer class which uses it to sleep for timeout duration. Now this function uses CLOCK_REALTIME which can be changed, so if you change this clock, a thread will be blocked for the unexpected time. So using CLOCK_MONOTONIC removes the error.

There are many embedded systems which do not have RTC and rely upon the external time like systems using GPS or set top box. So this fix is inevitable for them, at least for condition variable wait.

This is the sample code 
using System;
using System.Timers;

public class Example
{
	private static System.Timers.Timer aTimer;

	public static void Main()
	{
		SetTimer();

		Console.WriteLine("\nPress the Enter key to exit the application...\n");
		Console.WriteLine("The application started at {0:HH:mm:ss.fff}", DateTime.Now);
		Console.ReadLine();
		aTimer.Stop();
		aTimer.Dispose();

		Console.WriteLine("Terminating the application...");
	}

	private static void SetTimer()
	{
		// Create a timer with a two second interval.
		aTimer = new System.Timers.Timer(2000);
		// Hook up the Elapsed event for the timer. 
		//((System.ComponentModel.ISupportInitialize)(aTimer)).BeginInit();
		aTimer.Elapsed += OnTimedEvent;
		//((System.ComponentModel.ISupportInitialize)(aTimer)).EndInit();
		aTimer.AutoReset = true;
		aTimer.Enabled = true;
	}

	private static void OnTimedEvent(Object source, ElapsedEventArgs e)
	{
		Console.WriteLine("__The Elapsed event was raised at {0:HH:mm:ss.fff}",
		                  e.SignalTime);
	}
}
@monojenkins

This comment has been minimized.

Show comment
Hide comment
@monojenkins

monojenkins Oct 26, 2016

Contributor

Hello! I'm the build bot for the Mono project.

I need approval from a Mono team member to build this pull request. A team member should reply with "approve" to approve a build of this pull request, "whitelist" to whitelist this and all future pull requests from this contributor, or "build" to explicitly request a build, even if one has already been done.

Contributors can ignore this message.

Contributor

monojenkins commented Oct 26, 2016

Hello! I'm the build bot for the Mono project.

I need approval from a Mono team member to build this pull request. A team member should reply with "approve" to approve a build of this pull request, "whitelist" to whitelist this and all future pull requests from this contributor, or "build" to explicitly request a build, even if one has already been done.

Contributors can ignore this message.

@dnfclas

This comment has been minimized.

Show comment
Hide comment
@dnfclas

dnfclas Oct 26, 2016

Hi @jaymin1328, I'm your friendly neighborhood .NET Foundation Pull Request Bot (You can call me DNFBOT). Thanks for your contribution!
You've already signed the contribution license agreement. Thanks!

The agreement was validated by .NET Foundation and real humans are currently evaluating your PR.

TTYL, DNFBOT;

dnfclas commented Oct 26, 2016

Hi @jaymin1328, I'm your friendly neighborhood .NET Foundation Pull Request Bot (You can call me DNFBOT). Thanks for your contribution!
You've already signed the contribution license agreement. Thanks!

The agreement was validated by .NET Foundation and real humans are currently evaluating your PR.

TTYL, DNFBOT;

Update mono-os-mutex.h
added comments

@jaymin1328 jaymin1328 changed the title from Update mono-os-mutex.h change clock source in "pthread_cond_timedwait" to Change clock source to CLOCK_MONOTONIC in "pthread_cond_timedwait" : Update mono-os-mutex.h Oct 26, 2016

@jaymin1328 jaymin1328 changed the title from Change clock source to CLOCK_MONOTONIC in "pthread_cond_timedwait" : Update mono-os-mutex.h to Change clock source to CLOCK_MONOTONIC in 'pthread_cond_timedwait' : Update mono-os-mutex.h Oct 26, 2016

Show outdated Hide outdated mono/utils/mono-os-mutex.h Outdated
Show outdated Hide outdated mono/utils/mono-os-mutex.h Outdated
Show outdated Hide outdated mono/utils/mono-os-mutex.h Outdated
Show outdated Hide outdated mono/utils/mono-os-mutex.h Outdated
Show outdated Hide outdated mono/utils/mono-os-mutex.h Outdated
Show outdated Hide outdated mono/utils/mono-os-mutex.h Outdated
Show outdated Hide outdated mono/utils/mono-os-mutex.h Outdated
formatting changes
formatting changes and few changes made but overall logic is same,
@luhenry

This comment has been minimized.

Show comment
Hide comment
@luhenry

luhenry Oct 27, 2016

Member

build

Member

luhenry commented Oct 27, 2016

build

@BrandonLWhite

This comment has been minimized.

Show comment
Hide comment
@BrandonLWhite

BrandonLWhite Jan 25, 2017

Contributor

I really need this bug fixed in 4.8.

Contributor

BrandonLWhite commented Jan 25, 2017

I really need this bug fixed in 4.8.

@jaymin1328

This comment has been minimized.

Show comment
Hide comment
@jaymin1328

jaymin1328 Feb 2, 2017

Contributor

@BrandonLWhite : u can safely use my code, its working fine

Contributor

jaymin1328 commented Feb 2, 2017

@BrandonLWhite : u can safely use my code, its working fine

luhenry added a commit to luhenry/mono that referenced this pull request Feb 28, 2017

Change clock source to CLOCK_MONOTONIC in 'pthread_cond_timedwait'
 Wait functions for Mutex, Semaphore and Condition (like pthread_cond_timedwait) for 'task' synchronisation in Linux uses CLOCK_REALTIME by default,
this creates many problems where a process changes time. e.g. Command line utility < date -s "desired date and time" >
A thread may be blocked for a more\less time depending upon time change. It is always desirable to use clock source immune to such changes
However, it is not possible to change clock source for mutex and semaphore wait functions in Linux. So changing it for condition only

This can be seen by a simple application if you make a simple timer using System.Timers.Timer and print time stamp every regular interval say 2 seconds, now if time shifts in the system for whatever reason ( you can do this in Linux by <sudo date -s "Wed Oct 26 20:25:24 IST 2016"> put desired time in quotes), this print stops coming for the offset time duration.

The reason behind this is the call to 'pthread_cond_timedwait' function, by Timer class which uses it to sleep for timeout duration. Now this function uses CLOCK_REALTIME which can be changed, so if you change this clock, a thread will be blocked for the unexpected time. So using CLOCK_MONOTONIC removes the error.

There are many embedded systems which do not have RTC and rely upon the external time like systems using GPS or set top box. So this fix is inevitable for them, at least for condition variable wait.

This is the sample code
using System;
using System.Timers;

public class Example
{
	private static System.Timers.Timer aTimer;

	public static void Main()
	{
		SetTimer();

		Console.WriteLine("\nPress the Enter key to exit the application...\n");
		Console.WriteLine("The application started at {0:HH:mm:ss.fff}", DateTime.Now);
		Console.ReadLine();
		aTimer.Stop();
		aTimer.Dispose();

		Console.WriteLine("Terminating the application...");
	}

	private static void SetTimer()
	{
		// Create a timer with a two second interval.
		aTimer = new System.Timers.Timer(2000);
		// Hook up the Elapsed event for the timer.
		//((System.ComponentModel.ISupportInitialize)(aTimer)).BeginInit();
		aTimer.Elapsed += OnTimedEvent;
		//((System.ComponentModel.ISupportInitialize)(aTimer)).EndInit();
		aTimer.AutoReset = true;
		aTimer.Enabled = true;
	}

	private static void OnTimedEvent(Object source, ElapsedEventArgs e)
	{
		Console.WriteLine("__The Elapsed event was raised at {0:HH:mm:ss.fff}",
		                  e.SignalTime);
	}
}

This updates and merge mono#3828

luhenry added a commit to luhenry/mono that referenced this pull request Mar 2, 2017

Change clock source to CLOCK_MONOTONIC in 'pthread_cond_timedwait'
 Wait functions for Mutex, Semaphore and Condition (like pthread_cond_timedwait) for 'task' synchronisation in Linux uses CLOCK_REALTIME by default,
this creates many problems where a process changes time. e.g. Command line utility < date -s "desired date and time" >
A thread may be blocked for a more\less time depending upon time change. It is always desirable to use clock source immune to such changes
However, it is not possible to change clock source for mutex and semaphore wait functions in Linux. So changing it for condition only

This can be seen by a simple application if you make a simple timer using System.Timers.Timer and print time stamp every regular interval say 2 seconds, now if time shifts in the system for whatever reason ( you can do this in Linux by <sudo date -s "Wed Oct 26 20:25:24 IST 2016"> put desired time in quotes), this print stops coming for the offset time duration.

The reason behind this is the call to 'pthread_cond_timedwait' function, by Timer class which uses it to sleep for timeout duration. Now this function uses CLOCK_REALTIME which can be changed, so if you change this clock, a thread will be blocked for the unexpected time. So using CLOCK_MONOTONIC removes the error.

There are many embedded systems which do not have RTC and rely upon the external time like systems using GPS or set top box. So this fix is inevitable for them, at least for condition variable wait.

This is the sample code
using System;
using System.Timers;

public class Example
{
	private static System.Timers.Timer aTimer;

	public static void Main()
	{
		SetTimer();

		Console.WriteLine("\nPress the Enter key to exit the application...\n");
		Console.WriteLine("The application started at {0:HH:mm:ss.fff}", DateTime.Now);
		Console.ReadLine();
		aTimer.Stop();
		aTimer.Dispose();

		Console.WriteLine("Terminating the application...");
	}

	private static void SetTimer()
	{
		// Create a timer with a two second interval.
		aTimer = new System.Timers.Timer(2000);
		// Hook up the Elapsed event for the timer.
		//((System.ComponentModel.ISupportInitialize)(aTimer)).BeginInit();
		aTimer.Elapsed += OnTimedEvent;
		//((System.ComponentModel.ISupportInitialize)(aTimer)).EndInit();
		aTimer.AutoReset = true;
		aTimer.Enabled = true;
	}

	private static void OnTimedEvent(Object source, ElapsedEventArgs e)
	{
		Console.WriteLine("__The Elapsed event was raised at {0:HH:mm:ss.fff}",
		                  e.SignalTime);
	}
}

This updates and merge mono#3828
@luhenry

This comment has been minimized.

Show comment
Hide comment
@luhenry

luhenry Mar 2, 2017

Member

This has been merged with #4446

Member

luhenry commented Mar 2, 2017

This has been merged with #4446

@luhenry luhenry closed this Mar 2, 2017

luhenry added a commit that referenced this pull request Mar 2, 2017

Change clock source to CLOCK_MONOTONIC in 'pthread_cond_timedwait'
 Wait functions for Mutex, Semaphore and Condition (like pthread_cond_timedwait) for 'task' synchronisation in Linux uses CLOCK_REALTIME by default,
this creates many problems where a process changes time. e.g. Command line utility < date -s "desired date and time" >
A thread may be blocked for a more\less time depending upon time change. It is always desirable to use clock source immune to such changes
However, it is not possible to change clock source for mutex and semaphore wait functions in Linux. So changing it for condition only

This can be seen by a simple application if you make a simple timer using System.Timers.Timer and print time stamp every regular interval say 2 seconds, now if time shifts in the system for whatever reason ( you can do this in Linux by <sudo date -s "Wed Oct 26 20:25:24 IST 2016"> put desired time in quotes), this print stops coming for the offset time duration.

The reason behind this is the call to 'pthread_cond_timedwait' function, by Timer class which uses it to sleep for timeout duration. Now this function uses CLOCK_REALTIME which can be changed, so if you change this clock, a thread will be blocked for the unexpected time. So using CLOCK_MONOTONIC removes the error.

There are many embedded systems which do not have RTC and rely upon the external time like systems using GPS or set top box. So this fix is inevitable for them, at least for condition variable wait.

This is the sample code
using System;
using System.Timers;

public class Example
{
	private static System.Timers.Timer aTimer;

	public static void Main()
	{
		SetTimer();

		Console.WriteLine("\nPress the Enter key to exit the application...\n");
		Console.WriteLine("The application started at {0:HH:mm:ss.fff}", DateTime.Now);
		Console.ReadLine();
		aTimer.Stop();
		aTimer.Dispose();

		Console.WriteLine("Terminating the application...");
	}

	private static void SetTimer()
	{
		// Create a timer with a two second interval.
		aTimer = new System.Timers.Timer(2000);
		// Hook up the Elapsed event for the timer.
		//((System.ComponentModel.ISupportInitialize)(aTimer)).BeginInit();
		aTimer.Elapsed += OnTimedEvent;
		//((System.ComponentModel.ISupportInitialize)(aTimer)).EndInit();
		aTimer.AutoReset = true;
		aTimer.Enabled = true;
	}

	private static void OnTimedEvent(Object source, ElapsedEventArgs e)
	{
		Console.WriteLine("__The Elapsed event was raised at {0:HH:mm:ss.fff}",
		                  e.SignalTime);
	}
}

This updates and merge #3828
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment