public inbox for pthreads-win32@sourceware.org
 help / color / mirror / Atom feed
* bug report (with fix): pthread_setschedparam() fails withWindows-CE 3.0 (Pocket PC)
@ 2000-05-23  1:16 Tristan Savatier
  2000-05-23  1:54 ` (more) bug report (with fix): pthread_setschedparam() fails with Windows-CE " Tristan Savatier
  0 siblings, 1 reply; 2+ messages in thread
From: Tristan Savatier @ 2000-05-23  1:16 UTC (permalink / raw)
  To: pthreads-win32; +Cc: rpj, Bok

I just discovered a bug in pthread_win32 that caused
pthread_setschedparam() to fail systematically with
Windows-CE 3.0 (dubbed Pocket PC by microsoft).

The bug stems from the following piece of code that seems
perfectly correct at first sight:

====================================================
int pthread_setschedparam(pthread_t thread, int policy,
			  const struct sched_param *param)
{
[...]

  /* Validate priority level. */
  if (param->sched_priority < sched_get_priority_min(policy) ||
      param->sched_priority > sched_get_priority_max(policy))
    {
      return EINVAL;
    }

[...]
}

int sched_get_priority_min(int policy)
{
  if (policy < SCHED_MIN || policy > SCHED_MAX)
    {
      return EINVAL;
    }

  /* This is independent of scheduling policy in Win32. */
  return THREAD_PRIORITY_LOWEST;
}

int sched_get_priority_max(int policy)
{
  if (policy < SCHED_MIN || policy > SCHED_MAX)
    {
      return EINVAL;
    }

  /* This is independent of scheduling policy in Win32. */
  return THREAD_PRIORITY_HIGHEST;
}

====================================================

On Windows98, THREAD_PRIORITY_LOWEST is (-2) and 
THREAD_PRIORITY_HIGHEST is 2, and everything works just fine.

On WinCE 3.0, it so happen that THREAD_PRIORITY_LOWEST is 5
and THREAD_PRIORITY_HIGHEST is 1 (yes, I know, it is funny:
highest priority use smaller numbers) and the following happens:

sched_get_priority_min() returns 5
sched_get_priority_max() returns 1

and of course:

pthread_setschedparam() always fails to validate priority
level and returns EINVAL!!!

I believe that the correct fix is something like:

====================================================

int sched_get_priority_min(int policy)
{
  if (policy < SCHED_MIN || policy > SCHED_MAX)
    {
      return EINVAL;
    }

  /* This is independent of scheduling policy in Win32. */
  return MIN(THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_HIGHEST);
}

int sched_get_priority_max(int policy)
{
  if (policy < SCHED_MIN || policy > SCHED_MAX)
    {
      return EINVAL;
    }

  /* This is independent of scheduling policy in Win32. */
  return MAX(THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_HIGHEST);
}

====================================================

Of course the question remains whether it is 'legal' or
not to have an inverted priority, where the highest priority
is the smalest value.

The book "Multithreaded Programming with Pthread" by Bill Lewis & al.
says (p. 77):

<< POSIX gives no advice on how to use the
priority levels provided.  All you know is that for any given
policy, the priority level must be between 
sched_get_priority_min(policy) and
sched_get_priority_max(policy). >>

It does not say if sched_get_priority_min(policy) is always
assumed to be (numerically) smaller than
sched_get_priority_max(policy), but I assume that it is the case,
and obviously the posix_win32 implementation of
pthread_setschedparam() makes the same assumption.


-- 
Regards, -- Tristan Savatier (President, MpegTV LLC)

MpegTV: http://www.mpegtv.com - Tel: (415) 864 6466
                                Fax: (415) 704 3224

^ permalink raw reply	[flat|nested] 2+ messages in thread

* (more) bug report (with fix): pthread_setschedparam() fails with Windows-CE 3.0 (Pocket PC)
  2000-05-23  1:16 bug report (with fix): pthread_setschedparam() fails withWindows-CE 3.0 (Pocket PC) Tristan Savatier
@ 2000-05-23  1:54 ` Tristan Savatier
  0 siblings, 0 replies; 2+ messages in thread
From: Tristan Savatier @ 2000-05-23  1:54 UTC (permalink / raw)
  To: pthreads-win32; +Cc: rpj, Bok

In fact I just found another (small) problem:

In winbase.h (for WinCE 2.0 and higher), priorities are defined by:

#define THREAD_PRIORITY_TIME_CRITICAL   0
#define THREAD_PRIORITY_HIGHEST         1
#define THREAD_PRIORITY_ABOVE_NORMAL    2
#define THREAD_PRIORITY_NORMAL          3
#define THREAD_PRIORITY_BELOW_NORMAL    4
#define THREAD_PRIORITY_LOWEST          5
#define THREAD_PRIORITY_ABOVE_IDLE      6
#define THREAD_PRIORITY_IDLE            7

So the highest priority is not THREAD_PRIORITY_HIGHEST
but rather THREAD_PRIORITY_TIME_CRITICAL, and the
lowest is not THREAD_PRIORITY_LOWEST but rather 
THREAD_PRIORITY_IDLE.

I don't see any reason why pthread_setschedparam()
should prevent the user from setting those extreme
priorities.  In fact, setting the
THREAD_PRIORITY_TIME_CRITICAL priority may be very useful
in some special cases, to achieve close-to-real-time
behaviors.

Here is my new proposed fix to the file sched.c:

=========================================================================
/*  minimum & maximum */
#define sched_Max(a,b)	((a)<(b)?(b):(a))
#define sched_Min(a,b)	((a)>(b)?(b):(a))

int sched_get_priority_max(int policy)
{
  if (policy < SCHED_MIN || policy > SCHED_MAX)
    {
      return EINVAL;
    }

#ifdef UNDER_CE
  return sched_Max(THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL);
#else
  /* This is independent of scheduling policy in Win32. */
  return sched_Max(THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_HIGHEST);
#endif
}

int sched_get_priority_min(int policy)
{
  if (policy < SCHED_MIN || policy > SCHED_MAX)
    {
      return EINVAL;
    }

#ifdef UNDER_CE
  return sched_Min(THREAD_PRIORITY_IDLE, THREAD_PRIORITY_TIME_CRITICAL);
#else
  /* This is independent of scheduling policy in Win32. */
  return sched_Min(THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_HIGHEST);
#endif
}
========================================================================

For your information, I have included a copy
the manual page that explains the behavior
of the WinCE scheduler with the various priorities:

-t

-------------------------------------------------------------------------
This is preliminary documentation and subject to change.


SetThreadPriority

This function sets the priority value for the specified thread.


At a Glance


Header file: Winbase.h

Windows CE versions: 1.0 and later



Syntax


BOOL SetThreadPriority( HANDLE hThread, int nPriority);


Parameters


hThread


Handle to the thread whose priority value is to be set.


nPriority


Specifies the priority value for the thread. This parameter can be one
of the following values:


Value Description

THREAD_PRIORITY_TIME_CRITICAL Indicates 3 points above normal priority.

THREAD_PRIORITY_HIGHEST Indicates 2 points above normal priority.

THREAD_PRIORITY_ABOVE_NORMAL Indicates 1 point above normal priority.

THREAD_PRIORITY_NORMAL Indicates normal priority.

THREAD_PRIORITY_BELOW_NORMAL Indicates 1 point below normal priority.

THREAD_PRIORITY_LOWEST Indicates 2 points below normal priority.

THREAD_PRIORITY_ABOVE_IDLE Indicates 3 points below normal priority.

THREAD_PRIORITY_IDLE Indicates 4 points below normal priority.



Return Values


Nonzero indicates success. Zero indicates failure. To get extended error
information, call GetLastError.


Remarks


Windows CE does not support priority classes. The order in which threads
are scheduled is determined only by their thread priorities.


Threads are scheduled in a round-robin fashion at each priority level,
and only when there are no executable threads at a higher level does
scheduling of threads at a lower level take place.


The SetThreadPriority function enables setting the base priority level
of a thread without consideration of priority classes.


All threads initially start at THREAD_PRIORITY_NORMAL. Use the
GetThreadPriority function to get the priority value of a thread.


Use thread priority values to differentiate the relative priorities of
the tasks of a process. For example, a thread that handles input for a
window could have a higher priority level than a thread that performs
intensive calculations for the CPU.


When manipulating priorities, ensure that a high-priority thread does
not consume all of the available CPU time. A thread with a priority
level
of THREAD_PRIORITY_TIME_CRITICAL will execute until it explicitly yields
processing to other threads. Processing of these threads is not yielded
to
other threads with the THREAD_PRIORITY_TIME_CRITICAL priority level.
Such
a thread can interfere with the normal operation of the operating system
if the thread does not explicitly yield processing quickly.


See Also


GetThreadPriority


Built on Wednesday 10/13/1999.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2000-05-23  1:54 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-05-23  1:16 bug report (with fix): pthread_setschedparam() fails withWindows-CE 3.0 (Pocket PC) Tristan Savatier
2000-05-23  1:54 ` (more) bug report (with fix): pthread_setschedparam() fails with Windows-CE " Tristan Savatier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).