Compare commits

...

10 commits

Author SHA1 Message Date
0e1fbc94a2 Set up to compile for FreeChainXenon (random system at the moment, just need to compile GCC stage 2)
Some checks are pending
cygwin / Fedora cross x86_64-pc-cygwin (push) Waiting to run
cygwin / Windows native x86_64 (push) Waiting to run
2025-02-26 21:58:24 +00:00
Jeff Johnston
5e5e51f1dc Changes for 4.5.0 snapshot
- bump up release to 4.5.0
2024-12-31 20:35:33 -05:00
Corinna Vinschen
363357c023 Cygwin: pinfo: raise MAX_PID to 4194304
Reportedly, the maximum pid of 65536 is much too small in bigger
environments.  Raise the maximum PID to 4194304, whihc is the maximum
pid on Linux (PID_MAX_LIMIT defined in include/linux/threads.h).

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
2024-12-19 20:08:18 +01:00
Ken Brown
67bef16f7e Cygwin: mmap_list::try_map: fix a condition in a test of an mmap request
In testing whether the requested area is contained in an existing
mapped region, an incorrect condition was used due to a
misinterpretation of the u_addr and u_len variables.

Addresses: https://cygwin.com/pipermail/cygwin/2024-December/256913.html
Fixes: c68de3a262 ("* mmap.cc (class mmap_record):
Declare new map_pages method with address parameter.")
Signed-off-by: Ken Brown <kbrown@cornell.edu>
2024-12-19 10:40:18 -05:00
Ken Brown
677e315090 Cygwin: mmap: fix protection when unused pages are recycled
Previously, when unused pages from an mmap_record were recycled, they
were given the protection of the mmap_record rather than the
protection requested in the mmap call.  Fix this by adding a
"new_prot" parameter to mmap_list::try_map() and
mmap_record::map_pages() to keep track of the requested protection.
Then use new_prot in the calls to VirtualProtect().

Addresses: https://cygwin.com/pipermail/cygwin/2024-December/256911.html
Fixes: f90e23f271 ("*autoload.cc (NtCreateSection): Define.")
Signed-off-by: Ken Brown <kbrown@cornell.edu>
2024-12-19 10:25:53 -05:00
Christian Franke
efa5401ea9 Cygwin: /proc/<PID>/stat: set field (18) according to scheduling policy
If a realtime policy is selected, set the '(18) priority' field to the
negated sched_priority minus one.  If SCHED_IDLE is selected, set it to
the lowest priority 39.  Also set '(19) nice' to the originally requested
nice value.  Ensure consistence with the current Windows priority in all
cases.  Move the sched_priority from/to Windows priority mapping from
sched_get/setparam() to new functions in miscfuncs.cc.

Signed-off-by: Christian Franke <christian.franke@t-online.de>
2024-12-17 17:39:00 +01:00
Christian Franke
14dda1f598 Cygwin: doc: add SCHED_BATCH, SCHED_IDLE and SCHED_RESET_ON_FORK
Signed-off-by: Christian Franke <christian.franke@t-online.de>
2024-12-16 12:26:28 +01:00
Stafford Horne
8e53c58759 or1k: Fix compiler warnings
In my build the below are treated as error now and causing failures.  I
have described the fixes of each warning below.

In newlib/libc/sys/or1k/mlock.c:

      CC       libc/sys/or1k/libc_a-mlock.o
    newlib/libc/sys/or1k/mlock.c: In function ‘__malloc_lock’:
    newlib/libc/sys/or1k/mlock.c:56:19: warning: implicit declaration of function ‘or1k_critical_begin’ [-Wimplicit-function-declaration]
       56 |         restore = or1k_critical_begin();
	  |                   ^~~~~~~~~~~~~~~~~~~
    newlib/libc/sys/or1k/mlock.c: In function ‘__malloc_unlock’:
    newlib/libc/sys/or1k/mlock.c:93:17: warning: implicit declaration of function ‘or1k_critical_end’ [-Wimplicit-function-declaration]
       93 |                 or1k_critical_end(restore);
	  |                 ^~~~~~~~~~~~~~~~~

This patch adds prototypes for functions or1k_critical_begin and
or1k_critical_end to suppress the warning, inline with what we do for
or1k_sync_cas.

In libgloss/or1k/or1k_uart.c:

    libgloss/or1k/or1k_uart.c: In function ‘or1k_uart_set_read_cb’:
    libgloss/or1k/or1k_uart.c:163:25: warning: passing argument 2 of ‘or1k_interrupt_handler_add’ from incompatible pointer type [-Wincompatible-pointer-types]
      163 |                         _or1k_uart_interrupt_handler, 0);
	  |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
	  |                         |
	  |                         void (*)(uint32_t) {aka void (*)(long unsigned int)}
    In file included from libgloss/or1k/or1k_uart.c:19:
    libgloss/or1k/include/or1k-support.h:97:45: note: expected ‘or1k_interrupt_handler_fptr’ {aka ‘void (*)(void *)’} but argument is of type ‘void (*)(uint32_t)’ {aka ‘void (*)(long unsigned int)’}
       97 |                 or1k_interrupt_handler_fptr handler,
	  |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~

The public API is ‘void (*)(void *)' for our interrupt handlers.  The
function _or1k_uart_interrupt_hander is the internal default
implementation of the uart IRQ handler and it doesn't use the data
argument.

This patch updates the _or1k_uart_interrupt_handler argument type from
uint32_t to void* allowing the function prototype to match the required
prototype.

If we did have a 64-bit implementation it would be an ABI issue. But,
there never has been one, or1k is only 32-bit.

In libgloss/or1k/interrupts.c:

    libgloss/or1k/interrupts.c: In function ‘or1k_interrupt_handler_add’:
    libgloss/or1k/interrupts.c:41:52: warning: assignment to ‘void *’ from ‘long unsigned int’ makes pointer from integer without a cast [-Wint-conversion]
       41 |         _or1k_interrupt_handler_data_ptr_table[id] = (uint32_t) data_ptr;
	  |                                                    ^

The table _or1k_interrupt_handler_data_ptr_table is an array of void*
and data_ptr is void*.  There is no need for the cast so remove it.

In libgloss/or1k/sbrk.c:

    libgloss/or1k/sbrk.c:23:29: warning: initialization of ‘uint32_t’ {aka ‘long unsigned int’} from ‘uint32_t *’ {aka ‘long unsigned int *’} makes integer from pointer without a cast [-Wint-conversion]
       23 | uint32_t _or1k_heap_start = &end;
	  |

This patch adds a cast, which is safe in or1k as the architecture in
32-bit only.  But this code would not be 64-compatible.

Signed-off-by: Stafford Horne <shorne@gmail.com>
2024-12-16 10:24:53 +01:00
Takashi Yano
1f74e7e71a Cygwin: signal: Fix typo in the comment added by previous commit
Fixes: 1d1451ccd2 ("Cygwin: signal: Fix high load when retrying to process pending signal")
Reported-by: Jon Turney <jon.turney@dronecode.org.uk>
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
2024-12-13 20:56:52 +09:00
Takashi Yano
1d1451ccd2 Cygwin: signal: Fix high load when retrying to process pending signal
The commit e10f822a2b has a problem that CPU load gets high if
pending signal is not processed successfully for a long time.
With this patch, wait_sig() calls Sleep(1), rather than yield(),
if the pending signal has not been processed successfully for a
predetermined time to prevent CPU from high load.

Addresses: https://cygwin.com/pipermail/cygwin/2024-December/256884.html
Fixes: e10f822a2b ("Cygwin: signal: Handle queued signal without explicit __SIGFLUSH")
Reported-by: 凯夏 <walkerxk@gmail.com>
Reviewed-by: Corinna Vinschen <corinna@vinschen.de>
Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>
2024-12-12 21:38:20 +09:00
24 changed files with 201 additions and 105 deletions

2
config.sub vendored
View file

@ -1749,7 +1749,7 @@ case $os in
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
| nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
| fiwix* )
| fiwix* | xenon* )
;;
# This one is extra strict with allowed versions
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)

View file

@ -35,10 +35,10 @@ void or1k_interrupt_handler_add(uint32_t id,
{
#ifdef __OR1K_MULTICORE__
_or1k_interrupt_handler_table[or1k_coreid()][id] = handler;
_or1k_interrupt_handler_data_ptr_table[or1k_coreid()][id] = (uint32_t) data_ptr;
_or1k_interrupt_handler_data_ptr_table[or1k_coreid()][id] = data_ptr;
#else
_or1k_interrupt_handler_table[id] = handler;
_or1k_interrupt_handler_data_ptr_table[id] = (uint32_t) data_ptr;
_or1k_interrupt_handler_data_ptr_table[id] = data_ptr;
#endif
}

View file

@ -90,7 +90,7 @@ void (*_or1k_uart_read_cb)(char c);
* This is the interrupt handler that is registered for the callback
* function.
*/
void _or1k_uart_interrupt_handler(uint32_t data)
void _or1k_uart_interrupt_handler(void *data)
{
uint8_t iir = REG8(IIR);

View file

@ -30,7 +30,7 @@ extern void (*_or1k_uart_read_cb)(char c);
/**
* The UART interrupt handler
*/
void _or1k_uart_interrupt_handler(uint32_t data);
void _or1k_uart_interrupt_handler(void *data);
/**
* Initialize UART

View file

@ -20,7 +20,7 @@
#include "include/or1k-support.h"
extern uint32_t end; /* Set by linker. */
uint32_t _or1k_heap_start = &end;
uint32_t _or1k_heap_start = (uint32_t) &end;
uint32_t _or1k_heap_end;
void *

View file

@ -1,3 +1,19 @@
*** Major changes in newlib version 4.5.0:
- major clean-up of libgloss build including merging a number of platforms
into top-level Makefile (moxie, v850, i960, msp430, frv, i386, ...) and
removal of dead platforms such as xc16x
- strverscmp fixed for comparison of digit sequence with non-digits
- proper locking added from amdgcn
- numerous improvements to arc support including support of 16-entry
register file
- long double complex functions are now skipped if long double != double
- support for POSIX.1-2024 added to features.h
- arc64: port added for Synopsys Designware ARCv3 ISA
- sys/xtensa removed and replaced by machine/xtensa and libgloss
- fixes to powf
- fixes for building with gcc-15
*** Major changes in newlib version 4.4.0:
- long double support for i386, aarch64, and x86_64 added from FreeBSD

View file

@ -1,4 +1,4 @@
README for newlib-4.2.0 release
README for newlib-4.5.0 release
(mostly cribbed from the README in the gdb-4.13 release)
This is `newlib', a simple ANSI C library, math library, and collection
@ -20,8 +20,8 @@ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
Unpacking and Installation -- quick overview
==========================
When you unpack the newlib-4.2.0.tar.gz file, you'll find a directory
called `newlib-4.2.0', which contains many files. Interesting ones:
When you unpack the newlib-4.5.0.tar.gz file, you'll find a directory
called `newlib-4.5.0', which contains many files. Interesting ones:
COPYING* - License files for the sources
README - A common overview of all GNU development projects
configure - The build script for configuring the source tree
@ -94,13 +94,13 @@ directory. If the path to `configure' would be the same as the
argument to `--srcdir', you can leave out the `--srcdir' option; it
will be assumed.)
For example, with version 4.2.0, you can build NEWLIB in a separate
For example, with version 4.5.0, you can build NEWLIB in a separate
directory for a Sun 4 cross m68k-aout environment like this:
cd newlib-4.2.0
cd newlib-4.5.0
mkdir ../newlib-m68k-aout
cd ../newlib-m68k-aout
../newlib-4.2.0/configure --host=sun4 --target=m68k-aout
../newlib-4.5.0/configure --host=sun4 --target=m68k-aout
make
When `configure' builds a configuration using a remote source
@ -116,8 +116,8 @@ called `configure' (or one of its subdirectories).
The `Makefile' that `configure' generates in each source directory
also runs recursively. If you type `make' in a source directory such
as `newlib-4.2.0' (or in a separate configured directory configured with
`--srcdir=PATH/newlib-4.2.0'), you will build all the required libraries.
as `newlib-4.5.0' (or in a separate configured directory configured with
`--srcdir=PATH/newlib-4.5.0'), you will build all the required libraries.
When you have multiple hosts or targets configured in separate
directories, you can run `make' on them in parallel (for example, if
@ -530,7 +530,7 @@ Reporting Bugs
The correct address for reporting bugs found in NEWLIB is
"newlib@sourceware.org". Please email all bug reports to that
address. Please include the NEWLIB version number (e.g., newlib-4.2.0),
address. Please include the NEWLIB version number (e.g., newlib-4.5.0),
and how you configured it (e.g., "sun4 host and m68k-aout target").
Since NEWLIB supports many different configurations, it is important
that you be precise about this.

View file

@ -2,7 +2,7 @@ dnl This provides configure definitions used by all the newlib
dnl configure.in files.
AC_DEFUN([DEF_NEWLIB_MAJOR_VERSION],m4_define([NEWLIB_MAJOR_VERSION],[4]))
AC_DEFUN([DEF_NEWLIB_MINOR_VERSION],m4_define([NEWLIB_MINOR_VERSION],[4]))
AC_DEFUN([DEF_NEWLIB_MINOR_VERSION],m4_define([NEWLIB_MINOR_VERSION],[5]))
AC_DEFUN([DEF_NEWLIB_PATCHLEVEL_VERSION],m4_define([NEWLIB_PATCHLEVEL_VERSION],[0]))
AC_DEFUN([DEF_NEWLIB_VERSION],m4_define([NEWLIB_VERSION],[NEWLIB_MAJOR_VERSION.NEWLIB_MINOR_VERSION.NEWLIB_PATCHLEVEL_VERSION]))

24
newlib/configure vendored
View file

@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for newlib 4.4.0.
# Generated by GNU Autoconf 2.69 for newlib 4.5.0.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@ -576,8 +576,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='newlib'
PACKAGE_TARNAME='newlib'
PACKAGE_VERSION='4.4.0'
PACKAGE_STRING='newlib 4.4.0'
PACKAGE_VERSION='4.5.0'
PACKAGE_STRING='newlib 4.5.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@ -1563,7 +1563,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures newlib 4.4.0 to adapt to many kinds of systems.
\`configure' configures newlib 4.5.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1633,7 +1633,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of newlib 4.4.0:";;
short | recursive ) echo "Configuration of newlib 4.5.0:";;
esac
cat <<\_ACEOF
@ -1765,7 +1765,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
newlib configure 4.4.0
newlib configure 4.5.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@ -1857,7 +1857,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by newlib $as_me 4.4.0, which was
It was created by newlib $as_me 4.5.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@ -4870,7 +4870,7 @@ fi
# Define the identity of the package.
PACKAGE='newlib'
VERSION='4.4.0'
VERSION='4.5.0'
# Some tools Automake needs.
@ -6501,13 +6501,13 @@ fi
$as_echo "#define _NEWLIB_VERSION \"4.4.0\"" >>confdefs.h
$as_echo "#define _NEWLIB_VERSION \"4.5.0\"" >>confdefs.h
$as_echo "#define __NEWLIB__ 4" >>confdefs.h
$as_echo "#define __NEWLIB_MINOR__ 4" >>confdefs.h
$as_echo "#define __NEWLIB_MINOR__ 5" >>confdefs.h
$as_echo "#define __NEWLIB_PATCHLEVEL__ 0" >>confdefs.h
@ -8460,7 +8460,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by newlib $as_me 4.4.0, which was
This file was extended by newlib $as_me 4.5.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -8526,7 +8526,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
newlib config.status 4.4.0
newlib config.status 4.5.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

View file

@ -455,6 +455,9 @@ case "${host}" in
newlib_cflags="${newlib_cflags} -DHAVE_FCNTL -DHAVE_BLKSIZE -DHAVE_OPENDIR -DHAVE_RENAME"
newlib_cflags="${newlib_cflags} -DGETREENT_PROVIDED -DSIGNAL_PROVIDED"
;;
*-fcx-*)
sys_dir=amdgcn # Just use a random one for now, we don't use this yet.
;;
a29k-*-*)
sys_dir=a29khif
signal_dir=

View file

@ -69,8 +69,8 @@ into another language, under the above conditions for modified versions.
@title The Red Hat newlib C Library
@subtitle Full Configuration
@sp 1
@subtitle @code{libc} 4.4.0
@subtitle December 2023
@subtitle @code{libc} 4.5.0
@subtitle December 2024
@author Steve Chamberlain
@author Roland Pesch
@author Red Hat Support

View file

@ -38,6 +38,9 @@ volatile uint32_t _or1k_malloc_lock_restore;
extern uint32_t or1k_sync_cas(void *address, uint32_t compare, uint32_t swap);
extern uint32_t or1k_critical_begin();
extern void or1k_critical_end(uint32_t restore);
/**
* Recursive lock of the malloc
*/

View file

@ -46,8 +46,8 @@ into another language, under the above conditions for modified versions.
@titlepage
@title The Red Hat newlib C Math Library
@sp 1
@subtitle @code{libm} 4.4.0
@subtitle December 2023
@subtitle @code{libm} 4.5.0
@subtitle December 2024
@author Steve Chamberlain
@author Roland Pesch
@author Red Hat Support

View file

@ -1098,7 +1098,6 @@ format_process_stat (void *data, char *&destbuf)
unsigned long fault_count = 0UL,
vmsize = 0UL, vmrss = 0UL, vmmaxrss = 0UL;
uint64_t utime = 0ULL, stime = 0ULL, start_time = 0ULL;
int nice = 0;
/* ctty maj is 31:16, min is 15:0; tty_nr s/b maj 15:8, min 31:20, 7:0;
maj is 31:16 >> 16 & fff << 8; min is 15:0 >> 8 & ff << 20 | & ff */
int tty_nr = 0;
@ -1131,6 +1130,8 @@ format_process_stat (void *data, char *&destbuf)
else
state = get_process_state (p->dwProcessId);
int nice = 0, prio = 0;
NTSTATUS status;
HANDLE hProcess;
VM_COUNTERS vmc = { 0 };
@ -1168,7 +1169,26 @@ format_process_stat (void *data, char *&destbuf)
if (!NT_SUCCESS (status))
debug_printf ("NtQueryInformationProcess(ProcessQuotaLimits): "
"status %y", status);
nice = winprio_to_nice (GetPriorityClass (hProcess));
nice = p->nice;
DWORD winprio = GetPriorityClass (hProcess);
if (p->sched_policy == SCHED_FIFO || p->sched_policy == SCHED_RR)
/* Linux proc_pid_stat(5): (18) priority - For processes running a
real-time scheduling policy ..., this is the negated scheduling
priority, minus one. */
prio = - winprio_to_schedprio (winprio) - 1; /* -33(high)...-2(low) */
else if (p->sched_policy == SCHED_IDLE)
/* Return the lowest priority unless no longer consistent. */
prio = NZERO + (winprio == IDLE_PRIORITY_CLASS ? NZERO - 1 :
winprio_to_nice (winprio));
else
{
/* Use originally requested nice value unless no longer consistent. */
bool batch = (p->sched_policy == SCHED_BATCH);
if (winprio != nice_to_winprio (nice, batch))
nice = winprio_to_nice (winprio, batch);
prio = NZERO + nice; /* 0(high)...39(low) */
}
CloseHandle (hProcess);
}
status = NtQuerySystemInformation (SystemTimeOfDayInformation,
@ -1201,7 +1221,7 @@ format_process_stat (void *data, char *&destbuf)
p->ppid, p->pgid, p->sid, tty_nr,
-1, 0, fault_count, fault_count, 0, 0,
utime, stime, utime, stime,
NZERO + nice, nice, 0, 0,
prio, nice, 0, 0,
start_time,
vmsize, vmrss, vmmaxrss
);

View file

@ -46,6 +46,8 @@ is_alt_numpad_event (PINPUT_RECORD pirec)
int winprio_to_nice (DWORD prio, bool batch = false);
DWORD nice_to_winprio (int &nice, bool batch = false);
int winprio_to_schedprio (DWORD prio);
DWORD schedprio_to_winprio (int schedprio);
bool set_and_check_winprio (HANDLE proc, DWORD prio, bool set = true);
bool create_pipe (PHANDLE, PHANDLE, LPSECURITY_ATTRIBUTES, DWORD);

View file

@ -223,7 +223,7 @@ private:
DWORD status_exit (DWORD);
};
#define MAX_PID 65536
#define MAX_PID 4194304
#define ISSTATE(p, f) (!!((p)->process_state & f))
#define NOTSTATE(p, f) (!((p)->process_state & f))

View file

@ -104,7 +104,7 @@ yield ()
}
/*
Mapping of nice value from/to Windows priority
Mapping of nice value or sched_priority from/to Windows priority
('batch' is used for SCHED_BATCH policy).
nice_to_winprio() winprio_to_nice()
@ -115,6 +115,14 @@ yield ()
-12...-5 -13..-19 3 ABOVE_NORMAL_PRIORITY_CLASS -8 -16
-13..-19 -20 4 HIGH_PRIORITY_CLASS -16 -20
-20 - 5 REALTIME_PRIORITY_CLASS -20 -20
schedprio_to_winprio() winprio_to_schedprio()
1....6 0 IDLE_PRIORITY_CLASS 3
7...12 1 BELOW_NORMAL_PRIORITY_CLASS 9
13...18 2 NORMAL_PRIORITY_CLASS 15
19...24 3 ABOVE_NORMAL_PRIORITY_CLASS 21
25...30 4 HIGH_PRIORITY_CLASS 27
31...32 5 REALTIME_PRIORITY_CLASS 32
*/
/* *_PRIORITY_CLASS -> 0...5 */
@ -167,9 +175,25 @@ nice_to_winprio_impl (int nice, bool batch = false)
return level_to_winprio (level);
}
/* *_PRIORITY_CLASS -> sched_priority */
constexpr int
winprio_to_schedprio_impl (DWORD prio)
{
int level = winprio_to_level (prio);
return (level < 5 ? 3 + level * 6 : 32);
}
/* sched_priority -> *_PRIORITY_CLASS */
constexpr DWORD
schedprio_to_winprio_impl (int schedprio)
{
int level = (schedprio <= 1 ? 0 : (schedprio < 32 ? (schedprio - 1) / 6 : 5));
return level_to_winprio (level);
}
/* Check consistency at compile time. */
constexpr bool
check_nice_winprio_mapping ()
check_nice_schedprio_winprio_mapping ()
{
for (int nice = -NZERO; nice < NZERO; nice++)
for (int batch = 0; batch <= 1; batch++) {
@ -179,16 +203,28 @@ check_nice_winprio_mapping ()
if (prio != prio2)
return false;
}
for (int schedprio = 1; schedprio <= 32; schedprio++)
{
DWORD prio = schedprio_to_winprio_impl (schedprio);
int schedprio2 = winprio_to_schedprio_impl (prio);
DWORD prio2 = schedprio_to_winprio_impl (schedprio2);
if (prio != prio2)
return false;
}
return true;
}
static_assert (check_nice_winprio_mapping());
static_assert (check_nice_schedprio_winprio_mapping());
static_assert (nice_to_winprio_impl(NZERO-1, false) == IDLE_PRIORITY_CLASS);
static_assert (nice_to_winprio_impl(0, true) == BELOW_NORMAL_PRIORITY_CLASS);
static_assert (winprio_to_nice_impl(BELOW_NORMAL_PRIORITY_CLASS, true) == 0);
static_assert (nice_to_winprio_impl(0, false) == NORMAL_PRIORITY_CLASS);
static_assert (winprio_to_nice_impl(NORMAL_PRIORITY_CLASS, false) == 0);
static_assert (nice_to_winprio_impl(-NZERO, false) == REALTIME_PRIORITY_CLASS);
static_assert (schedprio_to_winprio_impl(1) == IDLE_PRIORITY_CLASS);
static_assert (schedprio_to_winprio_impl(15) == NORMAL_PRIORITY_CLASS);
static_assert (winprio_to_schedprio_impl(NORMAL_PRIORITY_CLASS) == 15);
static_assert (schedprio_to_winprio_impl(32) == REALTIME_PRIORITY_CLASS);
/* Get a default value for the nice factor. */
int
@ -210,6 +246,20 @@ nice_to_winprio (int &nice, bool batch /* = false */)
return nice_to_winprio_impl (nice, batch);
}
/* Get a default sched_priority from a Win32 priority. */
int
winprio_to_schedprio (DWORD prio)
{
return winprio_to_schedprio_impl (prio);
}
/* Get a Win32 priority matching the sched_priority. */
DWORD
schedprio_to_winprio (int schedprio)
{
return schedprio_to_winprio_impl (schedprio);
}
/* Set Win32 priority or return false on failure. Also return
false and revert to the original priority if a different (lower)
priority is set instead. Always revert to original priority if

View file

@ -339,8 +339,8 @@ class mmap_record
SIZE_T find_unused_pages (SIZE_T pages) const;
bool match (caddr_t addr, SIZE_T len, caddr_t &m_addr, SIZE_T &m_len);
off_t map_pages (SIZE_T len);
bool map_pages (caddr_t addr, SIZE_T len);
off_t map_pages (SIZE_T len, int new_prot);
bool map_pages (caddr_t addr, SIZE_T len, int new_prot);
bool unmap_pages (caddr_t addr, SIZE_T len);
int access (caddr_t address);
@ -373,7 +373,8 @@ class mmap_list
void set (int nfd, struct stat *st);
mmap_record *add_record (mmap_record &r);
bool del_record (mmap_record *rec);
caddr_t try_map (void *addr, size_t len, int flags, off_t off);
caddr_t try_map (void *addr, size_t len, int new_prot, int flags,
off_t off);
};
class mmap_areas
@ -455,14 +456,15 @@ mmap_record::init_page_map (mmap_record &r)
}
off_t
mmap_record::map_pages (SIZE_T len)
mmap_record::map_pages (SIZE_T len, int new_prot)
{
/* Used ONLY if this mapping matches into the chunk of another already
performed mapping in a special case of MAP_ANON|MAP_PRIVATE.
Otherwise it's job is now done by init_page_map(). */
DWORD old_prot;
debug_printf ("map_pages (fd=%d, len=%lu)", get_fd (), len);
debug_printf ("map_pages (fd=%d, len=%lu, new_prot=%y)", get_fd (), len,
new_prot);
len = PAGE_CNT (len);
off_t off = find_unused_pages (len);
@ -470,7 +472,8 @@ mmap_record::map_pages (SIZE_T len)
return (off_t) 0;
if (!noreserve ()
&& !VirtualProtect (get_address () + off * wincap.page_size (),
len * wincap.page_size (), gen_protect (),
len * wincap.page_size (),
::gen_protect (new_prot, get_flags ()),
&old_prot))
{
__seterrno ();
@ -483,9 +486,10 @@ mmap_record::map_pages (SIZE_T len)
}
bool
mmap_record::map_pages (caddr_t addr, SIZE_T len)
mmap_record::map_pages (caddr_t addr, SIZE_T len, int new_prot)
{
debug_printf ("map_pages (addr=%p, len=%lu)", addr, len);
debug_printf ("map_pages (addr=%p, len=%lu, new_prot=%y)", addr, len,
new_prot);
DWORD old_prot;
off_t off = addr - get_address ();
off /= wincap.page_size ();
@ -499,7 +503,8 @@ mmap_record::map_pages (caddr_t addr, SIZE_T len)
}
if (!noreserve ()
&& !VirtualProtect (get_address () + off * wincap.page_size (),
len * wincap.page_size (), gen_protect (),
len * wincap.page_size (),
::gen_protect (new_prot, get_flags ()),
&old_prot))
{
__seterrno ();
@ -614,7 +619,7 @@ mmap_list::del_record (mmap_record *rec)
}
caddr_t
mmap_list::try_map (void *addr, size_t len, int flags, off_t off)
mmap_list::try_map (void *addr, size_t len, int new_prot, int flags, off_t off)
{
mmap_record *rec;
@ -628,7 +633,7 @@ mmap_list::try_map (void *addr, size_t len, int flags, off_t off)
break;
if (rec && rec->compatible_flags (flags))
{
if ((off = rec->map_pages (len)) == (off_t) -1)
if ((off = rec->map_pages (len, new_prot)) == (off_t) -1)
return (caddr_t) MAP_FAILED;
return (caddr_t) rec->get_address () + off;
}
@ -646,7 +651,7 @@ mmap_list::try_map (void *addr, size_t len, int flags, off_t off)
break;
if (rec)
{
if (u_addr > (caddr_t) addr || u_addr + len < (caddr_t) addr + len
if (u_addr > (caddr_t) addr || u_addr + u_len < (caddr_t) addr + len
|| !rec->compatible_flags (flags))
{
/* Partial match only, or access mode doesn't match. */
@ -655,7 +660,7 @@ mmap_list::try_map (void *addr, size_t len, int flags, off_t off)
set_errno (EINVAL);
return (caddr_t) MAP_FAILED;
}
if (!rec->map_pages ((caddr_t) addr, len))
if (!rec->map_pages ((caddr_t) addr, len, new_prot))
return (caddr_t) MAP_FAILED;
return (caddr_t) addr;
}
@ -1051,7 +1056,7 @@ go_ahead:
/* Test if an existing anonymous mapping can be recycled. */
if (map_list && anonymous (flags))
{
caddr_t tried = map_list->try_map (addr, len, flags, off);
caddr_t tried = map_list->try_map (addr, len, prot, flags, off);
/* try_map returns NULL if no map matched, otherwise it returns
a valid address, or MAP_FAILED in case of a fatal error. */
if (tried)

View file

@ -239,7 +239,7 @@ pinfo::exit (DWORD n)
}
# undef self
/* Return next free Cygwin PID between 2 and 65535, round-robin. Each new
/* Return next free Cygwin PID between 2 and MAX_PID, round-robin. Each new
PID is checked that it doesn't collide with an existing PID. For that,
just check if the "cygpid.PID" section exists. */
pid_t

View file

@ -61,3 +61,6 @@ Fixes:
- Fix several problems triggered when a lot of SIGSTOP/SIGCONT signals
are received rapidly.
Addresses: https://cygwin.com/pipermail/cygwin/2024-November/256744.html
- Fix the protection when mmap(2) recycles unused pages.
Addresses: https://cygwin.com/pipermail/cygwin/2024-December/256911.html

View file

@ -69,3 +69,12 @@ What changed:
each child process created with fork(2).
Note: Windows does not offer alternative scheduling policies so
this could only emulate API behavior.
- If SCHED_FIFO or SCHED_RR is selected, the /proc/<PID>/stat field
'(18) priority' is now set to the negated sched_policy minus one.
If SCHED_IDLE is selected, this field is set to 39. The '(19) nice'
field is now set to the originally requested nice value.
- Raise maximum pid from 65536 to 4194304 to account for scenarios
with lots of CPUs and lots of tasks.
Addresses: https://cygwin.com/pipermail/cygwin/2024-December/256927.html

View file

@ -120,29 +120,7 @@ sched_getparam (pid_t pid, struct sched_param *param)
return -1;
}
/* calculate the unix priority. */
switch (pclass)
{
case IDLE_PRIORITY_CLASS:
param->sched_priority = 3;
break;
case BELOW_NORMAL_PRIORITY_CLASS:
param->sched_priority = 9;
break;
case NORMAL_PRIORITY_CLASS:
default:
param->sched_priority = 15;
break;
case ABOVE_NORMAL_PRIORITY_CLASS:
param->sched_priority = 21;
break;
case HIGH_PRIORITY_CLASS:
param->sched_priority = 27;
break;
case REALTIME_PRIORITY_CLASS:
param->sched_priority = 32;
break;
}
param->sched_priority = winprio_to_schedprio (pclass);
return 0;
}
@ -244,18 +222,10 @@ sched_setparam_pinfo (pinfo & p, const struct sched_param *param)
else if (p->sched_policy == SCHED_IDLE && pri == 0)
/* Idle policy, ignore the nice value. */
pclass = IDLE_PRIORITY_CLASS;
else if (1 <= pri && pri <= 6)
pclass = IDLE_PRIORITY_CLASS;
else if (pri <= 12)
pclass = BELOW_NORMAL_PRIORITY_CLASS;
else if (pri <= 18)
pclass = NORMAL_PRIORITY_CLASS;
else if (pri <= 24)
pclass = ABOVE_NORMAL_PRIORITY_CLASS;
else if (pri <= 30)
pclass = HIGH_PRIORITY_CLASS;
else if (pri <= 32)
pclass = REALTIME_PRIORITY_CLASS;
else if ((p->sched_policy == SCHED_FIFO || p->sched_policy == SCHED_RR)
&& valid_sched_parameters (param))
/* Realtime policy, apply requested priority. */
pclass = schedprio_to_winprio (param->sched_priority);
else
{
set_errno (EINVAL);

View file

@ -1345,6 +1345,12 @@ wait_sig (VOID *)
hntdll = GetModuleHandle ("ntdll.dll");
/* GetTickCount() here is enough because GetTickCount() - t0 does
not overflow until 49 days psss. Even if GetTickCount() overflows,
GetTickCount() - t0 returns correct value, since underflow in
unsigned wraps correctly. Pending a signal for more than 49
days makes no sense. */
DWORD t0 = GetTickCount ();
for (;;)
{
DWORD nb;
@ -1354,7 +1360,7 @@ wait_sig (VOID *)
else if (sigq.start.next
&& PeekNamedPipe (my_readsig, NULL, 0, NULL, &nb, NULL) && !nb)
{
yield ();
Sleep (GetTickCount () - t0 > 10 ? 1 : 0);
pack.si.si_signo = __SIGFLUSH;
}
else if (!ReadFile (my_readsig, &pack, sizeof (pack), &nb, NULL))
@ -1364,6 +1370,8 @@ wait_sig (VOID *)
system_printf ("garbled signal pipe data nb %u, sig %d", nb, pack.si.si_signo);
continue;
}
if (pack.si.si_signo != __SIGFLUSH)
t0 = GetTickCount ();
sigq.retry = false;
/* Don't process signals when we start exiting */

View file

@ -1771,25 +1771,32 @@ Over-allocation on sparse files is entirely ignored on Windows.</para>
<para><function>sched_setpolicy</function> only emulates API behavior
because Windows does not offer alternative scheduling policies.
If <literal>SCHED_OTHER</literal> is selected, the Windows priority is
set according to the nice value. If <literal>SCHED_FIFO</literal>
or <literal>SCHED_RR</literal> is selected, the nice value is preserved
and the Windows priority is set according to the
<literal>sched_priority</literal> value.</para>
If <literal>SCHED_OTHER</literal> or <literal>SCHED_BATCH</literal> is
selected, the Windows priority is set according to the nice value.
If <literal>SCHED_IDLE</literal> is selected, the Windows priority is
set to <literal>IDLE_PRIORITY_CLASS</literal>.
If <literal>SCHED_FIFO</literal> or <literal>SCHED_RR</literal> is
selected, the nice value is preserved and the Windows priority is set
according to the <literal>sched_priority</literal> value.
If the <literal>SCHED_RESET_ON_FORK</literal> flag is set, realtime
policies and negative nice values are dropped on
<function>fork</function>.</para>
<para><function>nice</function>, <function>setpriority</function>,
<function>sched_setparam</function> and <function>sched_setpolicy</function>
map the nice value (<literal>SCHED_OTHER</literal>) or the
<literal>sched_priority</literal> (<literal>SCHED_FIFO</literal>,
<literal>SCHED_RR</literal>) to Windows priority classes as follows:</para>
map the nice value (<literal>SCHED_OTHER</literal>,
<literal>SCHED_BATCH</literal>) or the <literal>sched_priority</literal>
(<literal>SCHED_FIFO</literal>, <literal>SCHED_RR</literal>) to Windows
priority classes as follows:</para>
<screen>
nice value sched_priority Windows priority class
12...19 1....6 IDLE_PRIORITY_CLASS
4...11 7...12 BELOW_NORMAL_PRIORITY_CLASS
-4....3 13...18 NORMAL_PRIORITY_CLASS
-12...-5 19...24 ABOVE_NORMAL_PRIORITY_CLASS
-13..-19 25...30 HIGH_PRIORITY_CLASS
-20 31...32 REALTIME_PRIORITY_CLASS
SCHED_OTHER SCHED_BATCH SCHED_FIFO/RR
nice value nice value sched_priority Windows priority class
12...19 4...19 1....6 IDLE_PRIORITY_CLASS
4...11 -4....3 7...12 BELOW_NORMAL_PRIORITY_CLASS
-4....3 -12...-5 13...18 NORMAL_PRIORITY_CLASS
-12...-5 -13..-19 19...24 ABOVE_NORMAL_PRIORITY_CLASS
-13..-19 -20 25...30 HIGH_PRIORITY_CLASS
-20 - 31...32 REALTIME_PRIORITY_CLASS
</screen>
The use of values which are mapped to the
<literal>REALTIME_PRIORITY_CLASS</literal> require administrative