add `subprocess-group-enabled' for process-group support

and fix problems with places and subprocesses
 and fix some mzrt thread setup and teardown issues
This commit is contained in:
Matthew Flatt 2010-07-05 14:48:16 -06:00
parent ecdd1ebc7a
commit 04fa6c6acd
16 changed files with 1051 additions and 509 deletions

View File

@ -82,9 +82,18 @@ the current custodian (see @secref["custodians"]). The
process or the creation of operating system pipes for process process or the creation of operating system pipes for process
communication. communication.
If the @racket[subprocess-group-enabled] parameter's value is true,
then the new process is created as a new OS-level process group. In
that case, @racket[subprocess-kill] attempts to terminate all
processes within the group, which may include additional processes
created by the subprocess. See @racket[subprocess-kill] for details,
and see @racket[subprocess-group-enabled] for additional caveats.
The @racket[current-subprocess-custodian-mode] parameter determines The @racket[current-subprocess-custodian-mode] parameter determines
whether the subprocess itself is registered with the current whether the subprocess itself is registered with the current
custodian.} @tech{custodian} so that a custodian shutdown calls
@racket[subprocess-kill] for the subprocess.}
@defproc[(subprocess-wait [subproc subprocess?]) void?]{ @defproc[(subprocess-wait [subproc subprocess?]) void?]{
@ -106,21 +115,56 @@ code is non-zero.}
@defproc[(subprocess-kill [subproc subprocess?] [force? any/c]) void?]{ @defproc[(subprocess-kill [subproc subprocess?] [force? any/c]) void?]{
Terminates the subprocess represented by @racket[subproc] if Terminates the subprocess represented by @racket[subproc]. The precise
@racket[force?] is true and if the process still running. If an error action depends on whether @racket[force?] is true, whether the process
occurs during termination, the @exnraise[exn:fail]. was created in its own group by setting the
@racket[subprocess-group-enabled] parameter to a true value, and the
current platform:
If @racket[force?] is @racket[#f] under @|AllUnix|, the subprocess is @itemlist[
sent an interrupt signal instead of a kill signal (and the subprocess
might handle the signal without terminating). Under Windows, no action @item{@racket[force?] is true, not a group, all platforms: Terminates
is taken when @racket[force?] is @racket[#f].} the process if the process still running.}
@item{@racket[force?] is false, not a group, under Unix or Mac OS X:
Sends the process an interrupt signal instead of a kill
signal.}
@item{@racket[force?] is false, not a group, under Windows: No action
is taken.}
@item{@racket[force?] is true, a group, under Unix or Mac OS X:
Terminates all processes in the group, but only if
@racket[subprocess-status] has never produced a
non-@racket['running] result for the subprocess and only if
functions like @racket[subprocess-wait] and @racket[sync] have
not detected the subprocess's completion. Otherwise, no action
is taken (because the immediate process is known to have
terminated while the continued existence of the group is
unknown).}
@item{@racket[force?] is true, a group, under Windows: Terminates
the process if the process still running.}
@item{@racket[force?] is false, a group, under Unix or Mac OS X: The
same as when @racket[force?] is @scheme[#t], but when the group
is sent a signal, it is an interrupt signal instead of a kill
signal.}
@item{@racket[force?] is false, a group, under Windows: All processes
in the group receive a CTRL-BREAK signal (independent of
whether the immediate subprocess has terminated).}
]
If an error occurs during termination, the @exnraise[exn:fail].}
@defproc[(subprocess-pid [subproce subprocess?]) exact-nonnegative-integer?]{ @defproc[(subprocess-pid [subproc subprocess?]) exact-nonnegative-integer?]{
Returns the operating system's numerical ID (if any) for the process Returns the operating system's numerical ID (if any) for the process
represented by @racket[subproc], valid only as long as the process is represented by @racket[subproc]. The result is valid only as long as
running.} the process is running.}
@defproc[(subprocess? [v any/c]) boolean?]{ @defproc[(subprocess? [v any/c]) boolean?]{
@ -131,22 +175,35 @@ otherwise.}
@defparam[current-subprocess-custodian-mode mode (or/c #f 'kill 'interrupt)]{ @defparam[current-subprocess-custodian-mode mode (or/c #f 'kill 'interrupt)]{
Determines whether a subprocess (as created by @racket[subprocess] or A @tech{parameter} that determines whether a subprocess (as created by
wrappers like @racket[process]) is registered with the current @racket[subprocess] or wrappers like @racket[process]) is registered
@tech{custodian}. If the parameter value is @racket[#f], then the subprocess with the current @tech{custodian}. If the parameter value is
is not registered with the custodian---although any created ports are @racket[#f], then the subprocess is not registered with the
registered. If the parameter value is @racket['kill] or custodian---although any created ports are registered. If the
@racket['interrupt], then the subprocess is shut down through parameter value is @racket['kill] or @racket['interrupt], then the
@racket[subprocess-kill], where @racket['kill] supplies a @racket[#t] subprocess is shut down through @racket[subprocess-kill], where
value for the @racket[_force?] argument and @racket['interrupt] @racket['kill] supplies a @racket[#t] value for the @racket[_force?]
supplies a @racket[#f] value. The shutdown may occur either before or argument and @racket['interrupt] supplies a @racket[#f] value. The
after ports created for the subprocess are closed. shutdown may occur either before or after ports created for the
subprocess are closed.
Custodian-triggered shutdown is limited by details of process handling Custodian-triggered shutdown is limited by details of process handling
in the host system. For example, @racket[process] and @racket[system] in the host system. For example, @racket[process] and @racket[system]
may create an intermediate shell process to run a program, in which may create an intermediate shell process to run a program, in which
case custodian-based termination shuts down the shell process and case custodian-based termination shuts down the shell process and
probably not the process started by the shell.} probably not the process started by the shell. See also
@racket[subprocess-kill]. Process groups (see
@racket[subprocess-group-enabled]) can address some limitations, but
not all of them.}
@defboolparam[subprocess-group-enabled on?]{
A @tech{parameter} that determines whether a subprocess is created as
a new process group. See @racket[subprocess-kill] for more information.
Beware that creating a group may interfere with the job control in an
interactive shell, since job control is based on process groups.}
@defproc[(shell-execute [verb (or/c string? #f)] @defproc[(shell-execute [verb (or/c string? #f)]
@ -154,7 +211,7 @@ probably not the process started by the shell.}
[parameters string?] [parameters string?]
[dir path-string?] [dir path-string?]
[show-mode symbol?]) [show-mode symbol?])
#f] #f]{
@index['("ShellExecute")]{Performs} the action specified by @racket[verb] @index['("ShellExecute")]{Performs} the action specified by @racket[verb]
on @racket[target] in Windows. For platforms other than Windows, the on @racket[target] in Windows. For platforms other than Windows, the
@ -246,7 +303,7 @@ the result is @racket[#f].
In future versions of Racket, the result may be a subprocess value if In future versions of Racket, the result may be a subprocess value if
the operating system did returns a process handle (but if a subprocess the operating system did returns a process handle (but if a subprocess
value is returned, its process ID will be @racket[0] instead of the value is returned, its process ID will be @racket[0] instead of the
real process ID). real process ID).}
@; ---------------------------------------------------------------------- @; ----------------------------------------------------------------------
@ -260,7 +317,11 @@ Executes a Unix, Mac OS X, or Windows shell command synchronously
(i.e., the call to @racket[system] does not return until the (i.e., the call to @racket[system] does not return until the
subprocess has ended). The @racket[command] argument is a string subprocess has ended). The @racket[command] argument is a string
containing no nul characters. If the command succeeds, the return containing no nul characters. If the command succeeds, the return
value is @racket[#t], @racket[#f] otherwise.} value is @racket[#t], @racket[#f] otherwise.
See also @racket[current-subprocess-custodian-mode] and
@racket[subprocess-group-enabled], which affect the subprocess used to
implement @racket[system].}
@defproc*[([(system* [command path-string?] [arg string?] ...) boolean?] @defproc*[([(system* [command path-string?] [arg string?] ...) boolean?]
@ -349,7 +410,14 @@ values:
@bold{Important:} All three ports returned from @racket[process] must @bold{Important:} All three ports returned from @racket[process] must
be explicitly closed with @racket[close-input-port] or be explicitly closed with @racket[close-input-port] or
@racket[close-output-port].} @racket[close-output-port].
See also @racket[current-subprocess-custodian-mode] and
@racket[subprocess-group-enabled], which affect the subprocess used to
implement @racket[process]. In particular, the @racket['interrupt] and
@racket['kill] process-control messages are implemented via
@racket[subprocess-kill], so they can affect a process group instead
of a single process.}
@defproc*[([(process* [command path-string?] [arg string?] ...) list?] @defproc*[([(process* [command path-string?] [arg string?] ...) list?]

View File

@ -285,6 +285,45 @@
(parameterize ([current-subprocess-custodian-mode 'interrupt]) (parameterize ([current-subprocess-custodian-mode 'interrupt])
(try (if (eq? 'windows (system-type)) 'running 'done-error)))) (try (if (eq? 'windows (system-type)) 'running 'done-error))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; process groups
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(unless (eq? 'windows (system-type))
(let ([try
(lambda (post-shutdown?)
(let ([l (parameterize ([subprocess-group-enabled (not post-shutdown?)])
(process* self
"-e"
(format "(define l (process* \"~a\" \"-e\" \"(let loop () (loop))\"))" self)
"-e"
"(displayln (list-ref l 2))"
"-e"
"(flush-output)"
"-e"
"(let loop () (loop))"))]
[running? (lambda (sub-pid)
(equal?
(list (number->string sub-pid))
(regexp-match
(format "(?m:^~a(?=[^0-9]))" sub-pid)
(let ([s (open-output-string)])
(parameterize ([current-output-port s])
(system (format "ps x")))
(get-output-string s)))))])
(let ([sub-pid (read (car l))])
(test 'running (list-ref l 4) 'status)
(test #t running? sub-pid)
((list-ref l 4) 'kill)
((list-ref l 4) 'wait)
(test 'done-error (list-ref l 4) 'status)
(test post-shutdown? running? sub-pid)
(when post-shutdown?
(system (format "kill ~a" sub-pid))))))])
(try #t)
(try #f)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(report-errs) (report-errs)

View File

@ -2040,12 +2040,15 @@ static void NewGCMasterInfo_initialize() {
mzrt_sema_create(&MASTERGCINFO->wait_sema, 0); mzrt_sema_create(&MASTERGCINFO->wait_sema, 0);
} }
#if 0
/* Not yet used: */
static void NewGCMasterInfo_cleanup() { static void NewGCMasterInfo_cleanup() {
mzrt_rwlock_destroy(MASTERGCINFO->cangc); mzrt_rwlock_destroy(MASTERGCINFO->cangc);
free(MASTERGCINFO->signal_fds); free(MASTERGCINFO->signal_fds);
free(MASTERGCINFO); free(MASTERGCINFO);
MASTERGCINFO = NULL; MASTERGCINFO = NULL;
} }
#endif
/* signals every place to do a full gc at then end of /* signals every place to do a full gc at then end of
garbage_collect the places will call garbage_collect the places will call

View File

@ -41,7 +41,7 @@ int designate_modified(void *p);
# define THREAD_FLD(x) x # define THREAD_FLD(x) x
#endif #endif
#if defined(MZ_USE_PLACES) && defined (MZ_PRECISE_GC) #if defined(MZ_USE_PLACES)
typedef struct OSXThreadData { typedef struct OSXThreadData {
struct OSXThreadData *next; struct OSXThreadData *next;
mach_port_t thread_port_id; mach_port_t thread_port_id;
@ -97,6 +97,25 @@ static void register_mach_thread() {
pthread_mutex_unlock(&osxthreadsmutex); pthread_mutex_unlock(&osxthreadsmutex);
} }
static void unregister_mach_thread() {
mach_port_t thread_self = mach_thread_self();
int index = thread_self % OSX_THREAD_TABLE_SIZE;
OSXThreadData * thread, *prev = NULL;
thread = osxthreads[index];
while (thread->thread_port_id != thread_self) {
prev = thread;
thread = thread->next;
}
if (thread) {
if (prev)
prev->next = thread->next;
else
osxthreads[index] = thread->next;
free(thread);
}
}
#endif #endif
#if defined(__POWERPC__) #if defined(__POWERPC__)
@ -290,7 +309,7 @@ kern_return_t GC_catch_exception_raise(mach_port_t port,
p = (void *)exc_state. THREAD_FLD(faultvaddr); p = (void *)exc_state. THREAD_FLD(faultvaddr);
#endif #endif
#if defined(MZ_USE_PLACES) && defined (MZ_PRECISE_GC) #if defined(MZ_USE_PLACES)
set_thread_locals_from_mach_thread_id(thread_port); set_thread_locals_from_mach_thread_id(thread_port);
#endif #endif
@ -373,11 +392,18 @@ void GC_attach_current_thread_exceptions_to_handler()
GCPRINT(GCOUTF, "Couldn't set exception ports: %s\n", mach_error_string(retval)); GCPRINT(GCOUTF, "Couldn't set exception ports: %s\n", mach_error_string(retval));
abort(); abort();
} }
#if defined(MZ_USE_PLACES) && defined (MZ_PRECISE_GC) #if defined(MZ_USE_PLACES)
register_mach_thread(); register_mach_thread();
#endif #endif
} }
void GC_detach_current_thread_exceptions_from_handler()
{
#if defined(MZ_USE_PLACES)
unregister_mach_thread();
#endif
}
/* this initializes the subsystem (sets the exception port, starts the /* this initializes the subsystem (sets the exception port, starts the
exception handling thread, etc) */ exception handling thread, etc) */
static void macosx_init_exception_handler(int isMASTERGC) static void macosx_init_exception_handler(int isMASTERGC)

View File

@ -1256,6 +1256,7 @@ enum {
MZCONFIG_THREAD_INIT_STACK_SIZE, MZCONFIG_THREAD_INIT_STACK_SIZE,
MZCONFIG_SUBPROC_CUSTODIAN_MODE, MZCONFIG_SUBPROC_CUSTODIAN_MODE,
MZCONFIG_SUBPROC_GROUP_ENABLED,
MZCONFIG_LOAD_DELAY_ENABLED, MZCONFIG_LOAD_DELAY_ENABLED,
MZCONFIG_DELAY_LOAD_INFO, MZCONFIG_DELAY_LOAD_INFO,

View File

@ -1,5 +1,5 @@
{ {
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,48,46,48,46,54,51,0,0,0,1,0,0,10,0,13,0, SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,48,46,48,46,55,51,0,0,0,1,0,0,10,0,13,0,
22,0,27,0,40,0,47,0,51,0,55,0,58,0,65,0,72,0,77,0,82, 22,0,27,0,40,0,47,0,51,0,55,0,58,0,65,0,72,0,77,0,82,
0,88,0,102,0,116,0,119,0,125,0,129,0,131,0,142,0,144,0,158,0, 0,88,0,102,0,116,0,119,0,125,0,129,0,131,0,142,0,144,0,158,0,
165,0,187,0,189,0,203,0,14,1,43,1,54,1,65,1,75,1,111,1,144, 165,0,187,0,189,0,203,0,14,1,43,1,54,1,65,1,75,1,111,1,144,
@ -61,10 +61,10 @@
110,117,97,116,105,111,110,45,109,97,114,107,45,115,101,116,45,102,105,114,115, 110,117,97,116,105,111,110,45,109,97,114,107,45,115,101,116,45,102,105,114,115,
116,11,2,25,201,250,22,82,2,21,9,248,22,73,203,27,248,22,73,248,22, 116,11,2,25,201,250,22,82,2,21,9,248,22,73,203,27,248,22,73,248,22,
147,4,196,28,248,22,79,193,20,15,159,37,36,37,249,22,140,4,80,158,39, 147,4,196,28,248,22,79,193,20,15,159,37,36,37,249,22,140,4,80,158,39,
36,27,248,22,147,4,248,22,72,197,28,249,22,184,8,62,61,62,248,22,141, 36,27,248,22,147,4,248,22,72,197,28,249,22,185,8,62,61,62,248,22,141,
4,248,22,96,196,250,22,81,2,21,248,22,81,249,22,81,21,93,2,26,248, 4,248,22,96,196,250,22,81,2,21,248,22,81,249,22,81,21,93,2,26,248,
22,72,199,250,22,82,2,4,249,22,81,2,26,249,22,81,248,22,105,203,2, 22,72,199,250,22,82,2,4,249,22,81,2,26,249,22,81,248,22,105,203,2,
26,248,22,73,202,251,22,81,2,17,28,249,22,184,8,248,22,141,4,248,22, 26,248,22,73,202,251,22,81,2,17,28,249,22,185,8,248,22,141,4,248,22,
72,200,64,101,108,115,101,10,248,22,72,197,250,22,82,2,21,9,248,22,73, 72,200,64,101,108,115,101,10,248,22,72,197,250,22,82,2,21,9,248,22,73,
200,249,22,71,2,4,248,22,73,202,100,8,32,8,31,8,30,8,29,8,28, 200,249,22,71,2,4,248,22,73,202,100,8,32,8,31,8,30,8,29,8,28,
16,4,11,11,2,19,3,1,8,101,110,118,49,50,56,54,51,16,4,11,11, 16,4,11,11,2,19,3,1,8,101,110,118,49,50,56,54,51,16,4,11,11,
@ -99,7 +99,7 @@
EVAL_ONE_SIZED_STR((char *)expr, 2024); EVAL_ONE_SIZED_STR((char *)expr, 2024);
} }
{ {
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,48,46,48,46,54,65,0,0,0,1,0,0,8,0,21,0, SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,48,46,48,46,55,65,0,0,0,1,0,0,8,0,21,0,
26,0,43,0,58,0,76,0,92,0,102,0,120,0,140,0,156,0,174,0,205, 26,0,43,0,58,0,76,0,92,0,102,0,120,0,140,0,156,0,174,0,205,
0,234,0,0,1,14,1,20,1,34,1,39,1,49,1,57,1,85,1,117,1, 0,234,0,0,1,14,1,20,1,34,1,39,1,49,1,57,1,85,1,117,1,
123,1,168,1,213,1,237,1,20,2,22,2,188,2,22,4,63,4,136,5,222, 123,1,168,1,213,1,237,1,20,2,22,2,188,2,22,4,63,4,136,5,222,
@ -132,234 +132,234 @@
111,114,32,98,121,116,101,32,115,116,114,105,110,103,6,36,36,99,97,110,110, 111,114,32,98,121,116,101,32,115,116,114,105,110,103,6,36,36,99,97,110,110,
111,116,32,97,100,100,32,97,32,115,117,102,102,105,120,32,116,111,32,97,32, 111,116,32,97,100,100,32,97,32,115,117,102,102,105,120,32,116,111,32,97,32,
114,111,111,116,32,112,97,116,104,58,32,5,0,27,20,14,159,80,159,37,51, 114,111,111,116,32,112,97,116,104,58,32,5,0,27,20,14,159,80,159,37,51,
38,250,80,159,40,52,38,249,22,27,11,80,159,42,51,38,22,157,13,10,248, 38,250,80,159,40,52,38,249,22,27,11,80,159,42,51,38,22,158,13,10,248,
22,175,5,23,196,2,28,248,22,172,6,23,194,2,12,87,94,248,22,190,8, 22,176,5,23,196,2,28,248,22,173,6,23,194,2,12,87,94,248,22,191,8,
23,194,1,27,20,14,159,80,159,38,51,38,250,80,159,41,52,38,249,22,27, 23,194,1,27,20,14,159,80,159,38,51,38,250,80,159,41,52,38,249,22,27,
11,80,159,43,51,38,22,157,13,10,248,22,175,5,23,197,2,28,248,22,172, 11,80,159,43,51,38,22,158,13,10,248,22,176,5,23,197,2,28,248,22,173,
6,23,194,2,12,87,94,248,22,190,8,23,194,1,27,20,14,159,80,159,39, 6,23,194,2,12,87,94,248,22,191,8,23,194,1,27,20,14,159,80,159,39,
51,38,250,80,159,42,52,38,249,22,27,11,80,159,44,51,38,22,157,13,10, 51,38,250,80,159,42,52,38,249,22,27,11,80,159,44,51,38,22,158,13,10,
248,22,175,5,23,198,2,28,248,22,172,6,23,194,2,12,87,94,248,22,190, 248,22,176,5,23,198,2,28,248,22,173,6,23,194,2,12,87,94,248,22,191,
8,23,194,1,248,80,159,40,54,37,197,28,248,22,79,23,195,2,9,27,248, 8,23,194,1,248,80,159,40,54,37,197,28,248,22,79,23,195,2,9,27,248,
22,72,23,196,2,27,28,248,22,141,14,23,195,2,23,194,1,28,248,22,140, 22,72,23,196,2,27,28,248,22,142,14,23,195,2,23,194,1,28,248,22,141,
14,23,195,2,249,22,142,14,23,196,1,250,80,158,43,49,248,22,157,14,2, 14,23,195,2,249,22,143,14,23,196,1,250,80,158,43,49,248,22,158,14,2,
20,11,10,250,80,158,41,49,248,22,157,14,2,20,23,197,1,10,28,23,193, 20,11,10,250,80,158,41,49,248,22,158,14,2,20,23,197,1,10,28,23,193,
2,249,22,71,248,22,144,14,249,22,142,14,23,198,1,247,22,158,14,27,248, 2,249,22,71,248,22,145,14,249,22,143,14,23,198,1,247,22,159,14,27,248,
22,73,23,200,1,28,248,22,79,23,194,2,9,27,248,22,72,23,195,2,27, 22,73,23,200,1,28,248,22,79,23,194,2,9,27,248,22,72,23,195,2,27,
28,248,22,141,14,23,195,2,23,194,1,28,248,22,140,14,23,195,2,249,22, 28,248,22,142,14,23,195,2,23,194,1,28,248,22,141,14,23,195,2,249,22,
142,14,23,196,1,250,80,158,48,49,248,22,157,14,2,20,11,10,250,80,158, 143,14,23,196,1,250,80,158,48,49,248,22,158,14,2,20,11,10,250,80,158,
46,49,248,22,157,14,2,20,23,197,1,10,28,23,193,2,249,22,71,248,22, 46,49,248,22,158,14,2,20,23,197,1,10,28,23,193,2,249,22,71,248,22,
144,14,249,22,142,14,23,198,1,247,22,158,14,248,80,159,46,53,37,248,22, 145,14,249,22,143,14,23,198,1,247,22,159,14,248,80,159,46,53,37,248,22,
73,23,199,1,87,94,23,193,1,248,80,159,44,53,37,248,22,73,23,197,1, 73,23,199,1,87,94,23,193,1,248,80,159,44,53,37,248,22,73,23,197,1,
87,94,23,193,1,27,248,22,73,23,198,1,28,248,22,79,23,194,2,9,27, 87,94,23,193,1,27,248,22,73,23,198,1,28,248,22,79,23,194,2,9,27,
248,22,72,23,195,2,27,28,248,22,141,14,23,195,2,23,194,1,28,248,22, 248,22,72,23,195,2,27,28,248,22,142,14,23,195,2,23,194,1,28,248,22,
140,14,23,195,2,249,22,142,14,23,196,1,250,80,158,46,49,248,22,157,14, 141,14,23,195,2,249,22,143,14,23,196,1,250,80,158,46,49,248,22,158,14,
2,20,11,10,250,80,158,44,49,248,22,157,14,2,20,23,197,1,10,28,23, 2,20,11,10,250,80,158,44,49,248,22,158,14,2,20,23,197,1,10,28,23,
193,2,249,22,71,248,22,144,14,249,22,142,14,23,198,1,247,22,158,14,248, 193,2,249,22,71,248,22,145,14,249,22,143,14,23,198,1,247,22,159,14,248,
80,159,44,53,37,248,22,73,23,199,1,248,80,159,42,53,37,248,22,73,196, 80,159,44,53,37,248,22,73,23,199,1,248,80,159,42,53,37,248,22,73,196,
27,248,22,181,13,23,195,2,28,23,193,2,192,87,94,23,193,1,28,248,22, 27,248,22,182,13,23,195,2,28,23,193,2,192,87,94,23,193,1,28,248,22,
177,6,23,195,2,27,248,22,139,14,195,28,192,192,248,22,140,14,195,11,87, 178,6,23,195,2,27,248,22,140,14,195,28,192,192,248,22,141,14,195,11,87,
94,28,28,248,22,182,13,23,195,2,10,28,248,22,181,13,23,195,2,10,28, 94,28,28,248,22,183,13,23,195,2,10,28,248,22,182,13,23,195,2,10,28,
248,22,177,6,23,195,2,28,248,22,139,14,23,195,2,10,248,22,140,14,23, 248,22,178,6,23,195,2,28,248,22,140,14,23,195,2,10,248,22,141,14,23,
195,2,11,12,250,22,154,9,76,110,111,114,109,97,108,45,112,97,116,104,45, 195,2,11,12,250,22,155,9,76,110,111,114,109,97,108,45,112,97,116,104,45,
99,97,115,101,6,42,42,112,97,116,104,32,40,102,111,114,32,97,110,121,32, 99,97,115,101,6,42,42,112,97,116,104,32,40,102,111,114,32,97,110,121,32,
115,121,115,116,101,109,41,32,111,114,32,118,97,108,105,100,45,112,97,116,104, 115,121,115,116,101,109,41,32,111,114,32,118,97,108,105,100,45,112,97,116,104,
32,115,116,114,105,110,103,23,197,2,28,28,248,22,182,13,23,195,2,249,22, 32,115,116,114,105,110,103,23,197,2,28,28,248,22,183,13,23,195,2,249,22,
184,8,248,22,183,13,23,197,2,2,21,249,22,184,8,247,22,133,8,2,21, 185,8,248,22,184,13,23,197,2,2,21,249,22,185,8,247,22,134,8,2,21,
27,28,248,22,177,6,23,196,2,23,195,2,248,22,187,7,248,22,186,13,23, 27,28,248,22,178,6,23,196,2,23,195,2,248,22,188,7,248,22,187,13,23,
197,2,28,249,22,172,14,0,21,35,114,120,34,94,91,92,92,93,91,92,92, 197,2,28,249,22,173,14,0,21,35,114,120,34,94,91,92,92,93,91,92,92,
93,91,63,93,91,92,92,93,34,23,195,2,28,248,22,177,6,195,248,22,189, 93,91,63,93,91,92,92,93,34,23,195,2,28,248,22,178,6,195,248,22,190,
13,195,194,27,248,22,152,7,23,195,1,249,22,190,13,248,22,190,7,250,22, 13,195,194,27,248,22,153,7,23,195,1,249,22,191,13,248,22,191,7,250,22,
180,14,0,6,35,114,120,34,47,34,28,249,22,172,14,0,22,35,114,120,34, 181,14,0,6,35,114,120,34,47,34,28,249,22,173,14,0,22,35,114,120,34,
91,47,92,92,93,91,46,32,93,43,91,47,92,92,93,42,36,34,23,201,2, 91,47,92,92,93,91,46,32,93,43,91,47,92,92,93,42,36,34,23,201,2,
23,199,1,250,22,180,14,0,19,35,114,120,34,91,32,46,93,43,40,91,47, 23,199,1,250,22,181,14,0,19,35,114,120,34,91,32,46,93,43,40,91,47,
92,92,93,42,41,36,34,23,202,1,6,2,2,92,49,80,159,44,37,38,2, 92,92,93,42,41,36,34,23,202,1,6,2,2,92,49,80,159,44,37,38,2,
21,28,248,22,177,6,194,248,22,189,13,194,193,87,94,28,28,248,22,181,13, 21,28,248,22,178,6,194,248,22,190,13,194,193,87,94,28,28,248,22,182,13,
23,195,2,10,28,248,22,177,6,23,195,2,28,248,22,139,14,23,195,2,10, 23,195,2,10,28,248,22,178,6,23,195,2,28,248,22,140,14,23,195,2,10,
248,22,140,14,23,195,2,11,12,250,22,154,9,23,196,2,2,22,23,197,2, 248,22,141,14,23,195,2,11,12,250,22,155,9,23,196,2,2,22,23,197,2,
28,248,22,139,14,23,195,2,12,248,22,133,12,249,22,139,11,248,22,142,7, 28,248,22,140,14,23,195,2,12,248,22,134,12,249,22,140,11,248,22,143,7,
250,22,161,7,2,23,23,200,1,23,201,1,247,22,23,87,94,28,28,248,22, 250,22,162,7,2,23,23,200,1,23,201,1,247,22,23,87,94,28,28,248,22,
181,13,23,195,2,10,28,248,22,177,6,23,195,2,28,248,22,139,14,23,195, 182,13,23,195,2,10,28,248,22,178,6,23,195,2,28,248,22,140,14,23,195,
2,10,248,22,140,14,23,195,2,11,12,250,22,154,9,23,196,2,2,22,23, 2,10,248,22,141,14,23,195,2,11,12,250,22,155,9,23,196,2,2,22,23,
197,2,28,248,22,139,14,23,195,2,12,248,22,133,12,249,22,139,11,248,22, 197,2,28,248,22,140,14,23,195,2,12,248,22,134,12,249,22,140,11,248,22,
142,7,250,22,161,7,2,23,23,200,1,23,201,1,247,22,23,87,94,87,94, 143,7,250,22,162,7,2,23,23,200,1,23,201,1,247,22,23,87,94,87,94,
28,28,248,22,181,13,23,195,2,10,28,248,22,177,6,23,195,2,28,248,22, 28,28,248,22,182,13,23,195,2,10,28,248,22,178,6,23,195,2,28,248,22,
139,14,23,195,2,10,248,22,140,14,23,195,2,11,12,250,22,154,9,195,2, 140,14,23,195,2,10,248,22,141,14,23,195,2,11,12,250,22,155,9,195,2,
22,23,197,2,28,248,22,139,14,23,195,2,12,248,22,133,12,249,22,139,11, 22,23,197,2,28,248,22,140,14,23,195,2,12,248,22,134,12,249,22,140,11,
248,22,142,7,250,22,161,7,2,23,199,23,201,1,247,22,23,249,22,3,89, 248,22,143,7,250,22,162,7,2,23,199,23,201,1,247,22,23,249,22,3,89,
162,8,44,37,50,9,223,2,33,35,196,87,94,28,28,248,22,181,13,23,194, 162,8,44,37,50,9,223,2,33,35,196,87,94,28,28,248,22,182,13,23,194,
2,10,28,248,22,177,6,23,194,2,28,248,22,139,14,23,194,2,10,248,22, 2,10,28,248,22,178,6,23,194,2,28,248,22,140,14,23,194,2,10,248,22,
140,14,23,194,2,11,12,250,22,154,9,2,7,2,22,23,196,2,28,248,22, 141,14,23,194,2,11,12,250,22,155,9,2,7,2,22,23,196,2,28,248,22,
139,14,23,194,2,12,248,22,133,12,249,22,139,11,248,22,142,7,250,22,161, 140,14,23,194,2,12,248,22,134,12,249,22,140,11,248,22,143,7,250,22,162,
7,2,23,2,7,23,200,1,247,22,23,32,38,89,162,8,44,40,55,2,24, 7,2,23,2,7,23,200,1,247,22,23,32,38,89,162,8,44,40,55,2,24,
222,33,39,28,248,22,79,23,197,2,87,94,23,196,1,248,22,133,12,249,22, 222,33,39,28,248,22,79,23,197,2,87,94,23,196,1,248,22,134,12,249,22,
172,11,251,22,161,7,2,25,2,7,28,248,22,79,23,203,2,87,94,23,202, 173,11,251,22,162,7,2,25,2,7,28,248,22,79,23,203,2,87,94,23,202,
1,23,201,1,250,22,1,22,135,14,23,204,1,23,205,1,23,200,1,247,22, 1,23,201,1,250,22,1,22,136,14,23,204,1,23,205,1,23,200,1,247,22,
23,27,249,22,135,14,248,22,72,23,200,2,23,197,2,28,248,22,130,14,23, 23,27,249,22,136,14,248,22,72,23,200,2,23,197,2,28,248,22,131,14,23,
194,2,27,250,22,1,22,135,14,23,197,1,199,28,248,22,130,14,193,192,251, 194,2,27,250,22,1,22,136,14,23,197,1,199,28,248,22,131,14,193,192,251,
2,38,198,199,200,248,22,73,202,251,2,38,197,198,199,248,22,73,201,87,94, 2,38,198,199,200,248,22,73,202,251,2,38,197,198,199,248,22,73,201,87,94,
87,94,87,94,28,28,248,22,181,13,193,10,28,248,22,177,6,193,28,248,22, 87,94,87,94,28,28,248,22,182,13,193,10,28,248,22,178,6,193,28,248,22,
139,14,193,10,248,22,140,14,193,11,12,250,22,154,9,2,7,2,22,195,28, 140,14,193,10,248,22,141,14,193,11,12,250,22,155,9,2,7,2,22,195,28,
248,22,139,14,193,12,248,22,133,12,249,22,139,11,248,22,142,7,250,22,161, 248,22,140,14,193,12,248,22,134,12,249,22,140,11,248,22,143,7,250,22,162,
7,2,23,2,7,199,247,22,23,249,22,3,32,0,89,162,8,44,37,49,9, 7,2,23,2,7,199,247,22,23,249,22,3,32,0,89,162,8,44,37,49,9,
222,33,37,195,27,247,22,159,14,251,2,38,196,197,198,196,32,41,89,162,44, 222,33,37,195,27,247,22,160,14,251,2,38,196,197,198,196,32,41,89,162,44,
42,59,2,24,222,33,42,28,248,22,79,23,199,2,87,94,23,198,1,248,23, 42,59,2,24,222,33,42,28,248,22,79,23,199,2,87,94,23,198,1,248,23,
196,1,251,22,161,7,2,25,23,199,1,28,248,22,79,23,203,2,87,94,23, 196,1,251,22,162,7,2,25,23,199,1,28,248,22,79,23,203,2,87,94,23,
202,1,23,201,1,250,22,1,22,135,14,23,204,1,23,205,1,23,198,1,27, 202,1,23,201,1,250,22,1,22,136,14,23,204,1,23,205,1,23,198,1,27,
249,22,135,14,248,22,72,23,202,2,23,199,2,28,248,22,130,14,23,194,2, 249,22,136,14,248,22,72,23,202,2,23,199,2,28,248,22,131,14,23,194,2,
27,250,22,1,22,135,14,23,197,1,23,202,2,28,248,22,130,14,23,194,2, 27,250,22,1,22,136,14,23,197,1,23,202,2,28,248,22,131,14,23,194,2,
192,87,94,23,193,1,27,248,22,73,23,202,1,28,248,22,79,23,194,2,87, 192,87,94,23,193,1,27,248,22,73,23,202,1,28,248,22,79,23,194,2,87,
94,23,193,1,248,23,199,1,251,22,161,7,2,25,23,202,1,28,248,22,79, 94,23,193,1,248,23,199,1,251,22,162,7,2,25,23,202,1,28,248,22,79,
23,206,2,87,94,23,205,1,23,204,1,250,22,1,22,135,14,23,207,1,23, 23,206,2,87,94,23,205,1,23,204,1,250,22,1,22,136,14,23,207,1,23,
208,1,23,201,1,27,249,22,135,14,248,22,72,23,197,2,23,202,2,28,248, 208,1,23,201,1,27,249,22,136,14,248,22,72,23,197,2,23,202,2,28,248,
22,130,14,23,194,2,27,250,22,1,22,135,14,23,197,1,204,28,248,22,130, 22,131,14,23,194,2,27,250,22,1,22,136,14,23,197,1,204,28,248,22,131,
14,193,192,253,2,41,203,204,205,206,23,15,248,22,73,201,253,2,41,202,203, 14,193,192,253,2,41,203,204,205,206,23,15,248,22,73,201,253,2,41,202,203,
204,205,206,248,22,73,200,87,94,23,193,1,27,248,22,73,23,201,1,28,248, 204,205,206,248,22,73,200,87,94,23,193,1,27,248,22,73,23,201,1,28,248,
22,79,23,194,2,87,94,23,193,1,248,23,198,1,251,22,161,7,2,25,23, 22,79,23,194,2,87,94,23,193,1,248,23,198,1,251,22,162,7,2,25,23,
201,1,28,248,22,79,23,205,2,87,94,23,204,1,23,203,1,250,22,1,22, 201,1,28,248,22,79,23,205,2,87,94,23,204,1,23,203,1,250,22,1,22,
135,14,23,206,1,23,207,1,23,200,1,27,249,22,135,14,248,22,72,23,197, 136,14,23,206,1,23,207,1,23,200,1,27,249,22,136,14,248,22,72,23,197,
2,23,201,2,28,248,22,130,14,23,194,2,27,250,22,1,22,135,14,23,197, 2,23,201,2,28,248,22,131,14,23,194,2,27,250,22,1,22,136,14,23,197,
1,203,28,248,22,130,14,193,192,253,2,41,202,203,204,205,206,248,22,73,201, 1,203,28,248,22,131,14,193,192,253,2,41,202,203,204,205,206,248,22,73,201,
253,2,41,201,202,203,204,205,248,22,73,200,27,247,22,159,14,253,2,41,198, 253,2,41,201,202,203,204,205,248,22,73,200,27,247,22,160,14,253,2,41,198,
199,200,201,202,198,87,95,28,28,248,22,182,13,23,194,2,10,28,248,22,181, 199,200,201,202,198,87,95,28,28,248,22,183,13,23,194,2,10,28,248,22,182,
13,23,194,2,10,28,248,22,177,6,23,194,2,28,248,22,139,14,23,194,2, 13,23,194,2,10,28,248,22,178,6,23,194,2,28,248,22,140,14,23,194,2,
10,248,22,140,14,23,194,2,11,12,252,22,154,9,23,200,2,2,26,36,23, 10,248,22,141,14,23,194,2,11,12,252,22,155,9,23,200,2,2,26,36,23,
198,2,23,199,2,28,28,248,22,177,6,23,195,2,10,248,22,166,7,23,195, 198,2,23,199,2,28,28,248,22,178,6,23,195,2,10,248,22,167,7,23,195,
2,87,94,23,194,1,12,252,22,154,9,23,200,2,2,27,37,23,198,2,23, 2,87,94,23,194,1,12,252,22,155,9,23,200,2,2,27,37,23,198,2,23,
199,1,91,159,39,11,90,161,39,36,11,248,22,138,14,23,197,2,87,94,23, 199,1,91,159,39,11,90,161,39,36,11,248,22,139,14,23,197,2,87,94,23,
195,1,87,94,28,192,12,250,22,155,9,23,201,1,2,28,23,199,1,249,22, 195,1,87,94,28,192,12,250,22,156,9,23,201,1,2,28,23,199,1,249,22,
7,194,195,91,159,38,11,90,161,38,36,11,87,95,28,28,248,22,182,13,23, 7,194,195,91,159,38,11,90,161,38,36,11,87,95,28,28,248,22,183,13,23,
196,2,10,28,248,22,181,13,23,196,2,10,28,248,22,177,6,23,196,2,28, 196,2,10,28,248,22,182,13,23,196,2,10,28,248,22,178,6,23,196,2,28,
248,22,139,14,23,196,2,10,248,22,140,14,23,196,2,11,12,252,22,154,9, 248,22,140,14,23,196,2,10,248,22,141,14,23,196,2,11,12,252,22,155,9,
2,10,2,26,36,23,200,2,23,201,2,28,28,248,22,177,6,23,197,2,10, 2,10,2,26,36,23,200,2,23,201,2,28,28,248,22,178,6,23,197,2,10,
248,22,166,7,23,197,2,12,252,22,154,9,2,10,2,27,37,23,200,2,23, 248,22,167,7,23,197,2,12,252,22,155,9,2,10,2,27,37,23,200,2,23,
201,2,91,159,39,11,90,161,39,36,11,248,22,138,14,23,199,2,87,94,23, 201,2,91,159,39,11,90,161,39,36,11,248,22,139,14,23,199,2,87,94,23,
195,1,87,94,28,192,12,250,22,155,9,2,10,2,28,23,201,2,249,22,7, 195,1,87,94,28,192,12,250,22,156,9,2,10,2,28,23,201,2,249,22,7,
194,195,27,249,22,191,13,250,22,179,14,0,20,35,114,120,35,34,40,63,58, 194,195,27,249,22,128,14,250,22,180,14,0,20,35,114,120,35,34,40,63,58,
91,46,93,91,94,46,93,42,124,41,36,34,248,22,187,13,23,201,1,28,248, 91,46,93,91,94,46,93,42,124,41,36,34,248,22,188,13,23,201,1,28,248,
22,177,6,23,203,2,249,22,190,7,23,204,1,8,63,23,202,1,28,248,22, 22,178,6,23,203,2,249,22,191,7,23,204,1,8,63,23,202,1,28,248,22,
182,13,23,199,2,248,22,183,13,23,199,1,87,94,23,198,1,247,22,184,13, 183,13,23,199,2,248,22,184,13,23,199,1,87,94,23,198,1,247,22,185,13,
28,248,22,181,13,194,249,22,135,14,195,194,192,91,159,38,11,90,161,38,36, 28,248,22,182,13,194,249,22,136,14,195,194,192,91,159,38,11,90,161,38,36,
11,87,95,28,28,248,22,182,13,23,196,2,10,28,248,22,181,13,23,196,2, 11,87,95,28,28,248,22,183,13,23,196,2,10,28,248,22,182,13,23,196,2,
10,28,248,22,177,6,23,196,2,28,248,22,139,14,23,196,2,10,248,22,140, 10,28,248,22,178,6,23,196,2,28,248,22,140,14,23,196,2,10,248,22,141,
14,23,196,2,11,12,252,22,154,9,2,11,2,26,36,23,200,2,23,201,2, 14,23,196,2,11,12,252,22,155,9,2,11,2,26,36,23,200,2,23,201,2,
28,28,248,22,177,6,23,197,2,10,248,22,166,7,23,197,2,12,252,22,154, 28,28,248,22,178,6,23,197,2,10,248,22,167,7,23,197,2,12,252,22,155,
9,2,11,2,27,37,23,200,2,23,201,2,91,159,39,11,90,161,39,36,11, 9,2,11,2,27,37,23,200,2,23,201,2,91,159,39,11,90,161,39,36,11,
248,22,138,14,23,199,2,87,94,23,195,1,87,94,28,192,12,250,22,155,9, 248,22,139,14,23,199,2,87,94,23,195,1,87,94,28,192,12,250,22,156,9,
2,11,2,28,23,201,2,249,22,7,194,195,27,249,22,191,13,249,22,176,7, 2,11,2,28,23,201,2,249,22,7,194,195,27,249,22,128,14,249,22,177,7,
250,22,180,14,0,9,35,114,120,35,34,91,46,93,34,248,22,187,13,23,203, 250,22,181,14,0,9,35,114,120,35,34,91,46,93,34,248,22,188,13,23,203,
1,6,1,1,95,28,248,22,177,6,23,202,2,249,22,190,7,23,203,1,8, 1,6,1,1,95,28,248,22,178,6,23,202,2,249,22,191,7,23,203,1,8,
63,23,201,1,28,248,22,182,13,23,199,2,248,22,183,13,23,199,1,87,94, 63,23,201,1,28,248,22,183,13,23,199,2,248,22,184,13,23,199,1,87,94,
23,198,1,247,22,184,13,28,248,22,181,13,194,249,22,135,14,195,194,192,249, 23,198,1,247,22,185,13,28,248,22,182,13,194,249,22,136,14,195,194,192,249,
247,22,144,5,194,11,249,80,159,38,47,37,9,9,249,80,159,38,47,37,195, 247,22,145,5,194,11,249,80,159,38,47,37,9,9,249,80,159,38,47,37,195,
9,27,247,22,161,14,249,80,158,39,48,28,23,195,2,27,248,22,131,8,6, 9,27,247,22,162,14,249,80,158,39,48,28,23,195,2,27,248,22,132,8,6,
11,11,80,76,84,67,79,76,76,69,67,84,83,28,192,192,6,0,0,6,0, 11,11,80,76,84,67,79,76,76,69,67,84,83,28,192,192,6,0,0,6,0,
0,27,28,23,196,1,250,22,135,14,248,22,157,14,69,97,100,100,111,110,45, 0,27,28,23,196,1,250,22,136,14,248,22,158,14,69,97,100,100,111,110,45,
100,105,114,247,22,129,8,6,8,8,99,111,108,108,101,99,116,115,11,27,248, 100,105,114,247,22,130,8,6,8,8,99,111,108,108,101,99,116,115,11,27,248,
80,159,42,53,37,250,22,85,23,203,1,248,22,81,248,22,157,14,72,99,111, 80,159,42,53,37,250,22,85,23,203,1,248,22,81,248,22,158,14,72,99,111,
108,108,101,99,116,115,45,100,105,114,23,204,1,28,193,249,22,71,195,194,192, 108,108,101,99,116,115,45,100,105,114,23,204,1,28,193,249,22,71,195,194,192,
32,51,89,162,8,44,39,8,31,2,19,222,33,52,27,249,22,168,14,23,197, 32,51,89,162,8,44,39,8,31,2,19,222,33,52,27,249,22,169,14,23,197,
2,23,198,2,28,23,193,2,87,94,23,196,1,27,248,22,96,23,195,2,27, 2,23,198,2,28,23,193,2,87,94,23,196,1,27,248,22,96,23,195,2,27,
27,248,22,105,23,197,1,27,249,22,168,14,23,201,2,23,196,2,28,23,193, 27,248,22,105,23,197,1,27,249,22,169,14,23,201,2,23,196,2,28,23,193,
2,87,94,23,194,1,27,248,22,96,23,195,2,27,27,248,22,105,23,197,1, 2,87,94,23,194,1,27,248,22,96,23,195,2,27,27,248,22,105,23,197,1,
27,249,22,168,14,23,205,2,23,196,2,28,23,193,2,87,94,23,194,1,27, 27,249,22,169,14,23,205,2,23,196,2,28,23,193,2,87,94,23,194,1,27,
248,22,96,23,195,2,27,27,248,22,105,23,197,1,27,249,22,168,14,23,209, 248,22,96,23,195,2,27,27,248,22,105,23,197,1,27,249,22,169,14,23,209,
2,23,196,2,28,23,193,2,87,94,23,194,1,27,248,22,96,23,195,2,27, 2,23,196,2,28,23,193,2,87,94,23,194,1,27,248,22,96,23,195,2,27,
27,248,22,105,23,197,1,27,249,22,168,14,23,213,2,23,196,2,28,23,193, 27,248,22,105,23,197,1,27,249,22,169,14,23,213,2,23,196,2,28,23,193,
2,87,94,23,194,1,27,248,22,96,23,195,2,27,250,2,51,23,215,2,23, 2,87,94,23,194,1,27,248,22,96,23,195,2,27,250,2,51,23,215,2,23,
216,1,248,22,105,23,199,1,28,249,22,172,7,23,196,2,2,29,249,22,85, 216,1,248,22,105,23,199,1,28,249,22,173,7,23,196,2,2,29,249,22,85,
23,214,2,194,249,22,71,248,22,190,13,23,197,1,194,87,95,23,211,1,23, 23,214,2,194,249,22,71,248,22,191,13,23,197,1,194,87,95,23,211,1,23,
193,1,28,249,22,172,7,23,196,2,2,29,249,22,85,23,212,2,9,249,22, 193,1,28,249,22,173,7,23,196,2,2,29,249,22,85,23,212,2,9,249,22,
71,248,22,190,13,23,197,1,9,28,249,22,172,7,23,196,2,2,29,249,22, 71,248,22,191,13,23,197,1,9,28,249,22,173,7,23,196,2,2,29,249,22,
85,23,210,2,194,249,22,71,248,22,190,13,23,197,1,194,87,94,23,193,1, 85,23,210,2,194,249,22,71,248,22,191,13,23,197,1,194,87,94,23,193,1,
28,249,22,172,7,23,196,2,2,29,249,22,85,23,208,2,9,249,22,71,248, 28,249,22,173,7,23,196,2,2,29,249,22,85,23,208,2,9,249,22,71,248,
22,190,13,23,197,1,9,28,249,22,172,7,23,196,2,2,29,249,22,85,23, 22,191,13,23,197,1,9,28,249,22,173,7,23,196,2,2,29,249,22,85,23,
206,2,194,249,22,71,248,22,190,13,23,197,1,194,87,94,23,193,1,28,249, 206,2,194,249,22,71,248,22,191,13,23,197,1,194,87,94,23,193,1,28,249,
22,172,7,23,196,2,2,29,249,22,85,23,204,2,9,249,22,71,248,22,190, 22,173,7,23,196,2,2,29,249,22,85,23,204,2,9,249,22,71,248,22,191,
13,23,197,1,9,28,249,22,172,7,23,196,2,2,29,249,22,85,23,202,2, 13,23,197,1,9,28,249,22,173,7,23,196,2,2,29,249,22,85,23,202,2,
194,249,22,71,248,22,190,13,23,197,1,194,87,94,23,193,1,28,249,22,172, 194,249,22,71,248,22,191,13,23,197,1,194,87,94,23,193,1,28,249,22,173,
7,23,196,2,2,29,249,22,85,23,200,2,9,249,22,71,248,22,190,13,23, 7,23,196,2,2,29,249,22,85,23,200,2,9,249,22,71,248,22,191,13,23,
197,1,9,28,249,22,172,7,23,196,2,2,29,249,22,85,197,194,87,94,23, 197,1,9,28,249,22,173,7,23,196,2,2,29,249,22,85,197,194,87,94,23,
196,1,249,22,71,248,22,190,13,23,197,1,194,87,94,23,193,1,28,249,22, 196,1,249,22,71,248,22,191,13,23,197,1,194,87,94,23,193,1,28,249,22,
172,7,23,198,2,2,29,249,22,85,195,9,87,94,23,194,1,249,22,71,248, 173,7,23,198,2,2,29,249,22,85,195,9,87,94,23,194,1,249,22,71,248,
22,190,13,23,199,1,9,87,95,28,28,248,22,166,7,194,10,248,22,177,6, 22,191,13,23,199,1,9,87,95,28,28,248,22,167,7,194,10,248,22,178,6,
194,12,250,22,154,9,2,14,6,21,21,98,121,116,101,32,115,116,114,105,110, 194,12,250,22,155,9,2,14,6,21,21,98,121,116,101,32,115,116,114,105,110,
103,32,111,114,32,115,116,114,105,110,103,196,28,28,248,22,80,195,249,22,4, 103,32,111,114,32,115,116,114,105,110,103,196,28,28,248,22,80,195,249,22,4,
22,181,13,196,11,12,250,22,154,9,2,14,6,13,13,108,105,115,116,32,111, 22,182,13,196,11,12,250,22,155,9,2,14,6,13,13,108,105,115,116,32,111,
102,32,112,97,116,104,115,197,250,2,51,197,195,28,248,22,177,6,197,248,22, 102,32,112,97,116,104,115,197,250,2,51,197,195,28,248,22,178,6,197,248,22,
189,7,197,196,32,54,89,162,8,44,39,53,70,102,111,117,110,100,45,101,120, 190,7,197,196,32,54,89,162,8,44,39,53,70,102,111,117,110,100,45,101,120,
101,99,222,33,57,32,55,89,162,8,44,40,58,64,110,101,120,116,222,33,56, 101,99,222,33,57,32,55,89,162,8,44,40,58,64,110,101,120,116,222,33,56,
27,248,22,143,14,23,196,2,28,249,22,186,8,23,195,2,23,197,1,11,28, 27,248,22,144,14,23,196,2,28,249,22,187,8,23,195,2,23,197,1,11,28,
248,22,139,14,23,194,2,27,249,22,135,14,23,197,1,23,196,1,28,23,197, 248,22,140,14,23,194,2,27,249,22,136,14,23,197,1,23,196,1,28,23,197,
2,91,159,39,11,90,161,39,36,11,248,22,138,14,23,197,2,87,95,23,195, 2,91,159,39,11,90,161,39,36,11,248,22,139,14,23,197,2,87,95,23,195,
1,23,194,1,27,28,23,202,2,27,248,22,143,14,23,199,2,28,249,22,186, 1,23,194,1,27,28,23,202,2,27,248,22,144,14,23,199,2,28,249,22,187,
8,23,195,2,23,200,2,11,28,248,22,139,14,23,194,2,250,2,54,23,205, 8,23,195,2,23,200,2,11,28,248,22,140,14,23,194,2,250,2,54,23,205,
2,23,206,2,249,22,135,14,23,200,2,23,198,1,250,2,54,23,205,2,23, 2,23,206,2,249,22,136,14,23,200,2,23,198,1,250,2,54,23,205,2,23,
206,2,23,196,1,11,28,23,193,2,192,87,94,23,193,1,27,28,248,22,181, 206,2,23,196,1,11,28,23,193,2,192,87,94,23,193,1,27,28,248,22,182,
13,23,196,2,27,249,22,135,14,23,198,2,23,205,2,28,28,248,22,130,14, 13,23,196,2,27,249,22,136,14,23,198,2,23,205,2,28,28,248,22,131,14,
193,10,248,22,129,14,193,192,11,11,28,23,193,2,192,87,94,23,193,1,28, 193,10,248,22,130,14,193,192,11,11,28,23,193,2,192,87,94,23,193,1,28,
23,203,2,11,27,248,22,143,14,23,200,2,28,249,22,186,8,23,195,2,23, 23,203,2,11,27,248,22,144,14,23,200,2,28,249,22,187,8,23,195,2,23,
201,1,11,28,248,22,139,14,23,194,2,250,2,54,23,206,1,23,207,1,249, 201,1,11,28,248,22,140,14,23,194,2,250,2,54,23,206,1,23,207,1,249,
22,135,14,23,201,1,23,198,1,250,2,54,205,206,195,192,87,94,23,194,1, 22,136,14,23,201,1,23,198,1,250,2,54,205,206,195,192,87,94,23,194,1,
28,23,196,2,91,159,39,11,90,161,39,36,11,248,22,138,14,23,197,2,87, 28,23,196,2,91,159,39,11,90,161,39,36,11,248,22,139,14,23,197,2,87,
95,23,195,1,23,194,1,27,28,23,201,2,27,248,22,143,14,23,199,2,28, 95,23,195,1,23,194,1,27,28,23,201,2,27,248,22,144,14,23,199,2,28,
249,22,186,8,23,195,2,23,200,2,11,28,248,22,139,14,23,194,2,250,2, 249,22,187,8,23,195,2,23,200,2,11,28,248,22,140,14,23,194,2,250,2,
54,23,204,2,23,205,2,249,22,135,14,23,200,2,23,198,1,250,2,54,23, 54,23,204,2,23,205,2,249,22,136,14,23,200,2,23,198,1,250,2,54,23,
204,2,23,205,2,23,196,1,11,28,23,193,2,192,87,94,23,193,1,27,28, 204,2,23,205,2,23,196,1,11,28,23,193,2,192,87,94,23,193,1,27,28,
248,22,181,13,23,196,2,27,249,22,135,14,23,198,2,23,204,2,28,28,248, 248,22,182,13,23,196,2,27,249,22,136,14,23,198,2,23,204,2,28,28,248,
22,130,14,193,10,248,22,129,14,193,192,11,11,28,23,193,2,192,87,94,23, 22,131,14,193,10,248,22,130,14,193,192,11,11,28,23,193,2,192,87,94,23,
193,1,28,23,202,2,11,27,248,22,143,14,23,200,2,28,249,22,186,8,23, 193,1,28,23,202,2,11,27,248,22,144,14,23,200,2,28,249,22,187,8,23,
195,2,23,201,1,11,28,248,22,139,14,23,194,2,250,2,54,23,205,1,23, 195,2,23,201,1,11,28,248,22,140,14,23,194,2,250,2,54,23,205,1,23,
206,1,249,22,135,14,23,201,1,23,198,1,250,2,54,204,205,195,192,28,23, 206,1,249,22,136,14,23,201,1,23,198,1,250,2,54,204,205,195,192,28,23,
193,2,91,159,39,11,90,161,39,36,11,248,22,138,14,23,199,2,87,95,23, 193,2,91,159,39,11,90,161,39,36,11,248,22,139,14,23,199,2,87,95,23,
195,1,23,194,1,27,28,23,198,2,251,2,55,23,198,2,23,203,2,23,201, 195,1,23,194,1,27,28,23,198,2,251,2,55,23,198,2,23,203,2,23,201,
2,23,202,2,11,28,23,193,2,192,87,94,23,193,1,27,28,248,22,181,13, 2,23,202,2,11,28,23,193,2,192,87,94,23,193,1,27,28,248,22,182,13,
195,27,249,22,135,14,197,200,28,28,248,22,130,14,193,10,248,22,129,14,193, 195,27,249,22,136,14,197,200,28,28,248,22,131,14,193,10,248,22,130,14,193,
192,11,11,28,192,192,28,198,11,251,2,55,198,203,201,202,194,32,58,89,162, 192,11,11,28,192,192,28,198,11,251,2,55,198,203,201,202,194,32,58,89,162,
8,44,40,8,31,2,19,222,33,59,28,248,22,79,23,197,2,11,27,248,22, 8,44,40,8,31,2,19,222,33,59,28,248,22,79,23,197,2,11,27,248,22,
142,14,248,22,72,23,199,2,27,249,22,135,14,23,196,1,23,197,2,28,248, 143,14,248,22,72,23,199,2,27,249,22,136,14,23,196,1,23,197,2,28,248,
22,129,14,23,194,2,250,2,54,198,199,195,87,94,23,193,1,27,248,22,73, 22,130,14,23,194,2,250,2,54,198,199,195,87,94,23,193,1,27,248,22,73,
23,200,1,28,248,22,79,23,194,2,11,27,248,22,142,14,248,22,72,23,196, 23,200,1,28,248,22,79,23,194,2,11,27,248,22,143,14,248,22,72,23,196,
2,27,249,22,135,14,23,196,1,23,200,2,28,248,22,129,14,23,194,2,250, 2,27,249,22,136,14,23,196,1,23,200,2,28,248,22,130,14,23,194,2,250,
2,54,201,202,195,87,94,23,193,1,27,248,22,73,23,197,1,28,248,22,79, 2,54,201,202,195,87,94,23,193,1,27,248,22,73,23,197,1,28,248,22,79,
23,194,2,11,27,248,22,142,14,248,22,72,23,196,2,27,249,22,135,14,23, 23,194,2,11,27,248,22,143,14,248,22,72,23,196,2,27,249,22,136,14,23,
196,1,23,203,2,28,248,22,129,14,23,194,2,250,2,54,204,205,195,87,94, 196,1,23,203,2,28,248,22,130,14,23,194,2,250,2,54,204,205,195,87,94,
23,193,1,27,248,22,73,23,197,1,28,248,22,79,23,194,2,11,27,248,22, 23,193,1,27,248,22,73,23,197,1,28,248,22,79,23,194,2,11,27,248,22,
142,14,248,22,72,23,196,2,27,249,22,135,14,23,196,1,23,206,2,28,248, 143,14,248,22,72,23,196,2,27,249,22,136,14,23,196,1,23,206,2,28,248,
22,129,14,23,194,2,250,2,54,23,15,23,16,195,87,94,23,193,1,27,248, 22,130,14,23,194,2,250,2,54,23,15,23,16,195,87,94,23,193,1,27,248,
22,73,23,197,1,28,248,22,79,23,194,2,11,27,248,22,142,14,248,22,72, 22,73,23,197,1,28,248,22,79,23,194,2,11,27,248,22,143,14,248,22,72,
23,196,2,27,249,22,135,14,23,196,1,23,209,2,28,248,22,129,14,23,194, 23,196,2,27,249,22,136,14,23,196,1,23,209,2,28,248,22,130,14,23,194,
2,250,2,54,23,18,23,19,195,87,94,23,193,1,27,248,22,73,23,197,1, 2,250,2,54,23,18,23,19,195,87,94,23,193,1,27,248,22,73,23,197,1,
28,248,22,79,23,194,2,11,27,248,22,142,14,248,22,72,195,27,249,22,135, 28,248,22,79,23,194,2,11,27,248,22,143,14,248,22,72,195,27,249,22,136,
14,23,196,1,23,19,28,248,22,129,14,193,250,2,54,23,21,23,22,195,251, 14,23,196,1,23,19,28,248,22,130,14,193,250,2,54,23,21,23,22,195,251,
2,58,23,21,23,22,23,23,248,22,73,199,87,95,28,28,248,22,181,13,23, 2,58,23,21,23,22,23,23,248,22,73,199,87,95,28,28,248,22,182,13,23,
195,2,10,28,248,22,177,6,23,195,2,28,248,22,139,14,23,195,2,10,248, 195,2,10,28,248,22,178,6,23,195,2,28,248,22,140,14,23,195,2,10,248,
22,140,14,23,195,2,11,12,250,22,154,9,2,15,6,25,25,112,97,116,104, 22,141,14,23,195,2,11,12,250,22,155,9,2,15,6,25,25,112,97,116,104,
32,111,114,32,115,116,114,105,110,103,32,40,115,97,110,115,32,110,117,108,41, 32,111,114,32,115,116,114,105,110,103,32,40,115,97,110,115,32,110,117,108,41,
23,197,2,28,28,23,195,2,28,28,248,22,181,13,23,196,2,10,28,248,22, 23,197,2,28,28,23,195,2,28,28,248,22,182,13,23,196,2,10,28,248,22,
177,6,23,196,2,28,248,22,139,14,23,196,2,10,248,22,140,14,23,196,2, 178,6,23,196,2,28,248,22,140,14,23,196,2,10,248,22,141,14,23,196,2,
11,248,22,139,14,23,196,2,11,10,12,250,22,154,9,2,15,6,29,29,35, 11,248,22,140,14,23,196,2,11,10,12,250,22,155,9,2,15,6,29,29,35,
102,32,111,114,32,114,101,108,97,116,105,118,101,32,112,97,116,104,32,111,114, 102,32,111,114,32,114,101,108,97,116,105,118,101,32,112,97,116,104,32,111,114,
32,115,116,114,105,110,103,23,198,2,28,28,248,22,139,14,23,195,2,91,159, 32,115,116,114,105,110,103,23,198,2,28,28,248,22,140,14,23,195,2,91,159,
39,11,90,161,39,36,11,248,22,138,14,23,198,2,249,22,184,8,194,68,114, 39,11,90,161,39,36,11,248,22,139,14,23,198,2,249,22,185,8,194,68,114,
101,108,97,116,105,118,101,11,27,248,22,131,8,6,4,4,80,65,84,72,27, 101,108,97,116,105,118,101,11,27,248,22,132,8,6,4,4,80,65,84,72,27,
28,23,194,2,27,249,80,159,41,48,38,23,197,1,9,28,249,22,184,8,247, 28,23,194,2,27,249,80,159,41,48,38,23,197,1,9,28,249,22,185,8,247,
22,133,8,2,21,249,22,71,248,22,190,13,5,1,46,194,192,87,94,23,194, 22,134,8,2,21,249,22,71,248,22,191,13,5,1,46,194,192,87,94,23,194,
1,9,28,248,22,79,23,194,2,11,27,248,22,142,14,248,22,72,23,196,2, 1,9,28,248,22,79,23,194,2,11,27,248,22,143,14,248,22,72,23,196,2,
27,249,22,135,14,23,196,1,23,200,2,28,248,22,129,14,23,194,2,250,2, 27,249,22,136,14,23,196,1,23,200,2,28,248,22,130,14,23,194,2,250,2,
54,201,202,195,87,94,23,193,1,27,248,22,73,23,197,1,28,248,22,79,23, 54,201,202,195,87,94,23,193,1,27,248,22,73,23,197,1,28,248,22,79,23,
194,2,11,27,248,22,142,14,248,22,72,23,196,2,27,249,22,135,14,23,196, 194,2,11,27,248,22,143,14,248,22,72,23,196,2,27,249,22,136,14,23,196,
1,23,203,2,28,248,22,129,14,23,194,2,250,2,54,204,205,195,87,94,23, 1,23,203,2,28,248,22,130,14,23,194,2,250,2,54,204,205,195,87,94,23,
193,1,27,248,22,73,23,197,1,28,248,22,79,23,194,2,11,27,248,22,142, 193,1,27,248,22,73,23,197,1,28,248,22,79,23,194,2,11,27,248,22,143,
14,248,22,72,195,27,249,22,135,14,23,196,1,205,28,248,22,129,14,193,250, 14,248,22,72,195,27,249,22,136,14,23,196,1,205,28,248,22,130,14,193,250,
2,54,23,15,23,16,195,251,2,58,23,15,23,16,23,17,248,22,73,199,27, 2,54,23,15,23,16,195,251,2,58,23,15,23,16,23,17,248,22,73,199,27,
248,22,142,14,23,196,1,28,248,22,129,14,193,250,2,54,198,199,195,11,250, 248,22,143,14,23,196,1,28,248,22,130,14,193,250,2,54,198,199,195,11,250,
80,159,39,49,37,196,197,11,250,80,159,39,49,37,196,11,11,87,94,249,22, 80,159,39,49,37,196,197,11,250,80,159,39,49,37,196,11,11,87,94,249,22,
168,6,247,22,140,5,195,248,22,130,6,249,22,184,3,36,249,22,168,3,197, 169,6,247,22,141,5,195,248,22,131,6,249,22,184,3,36,249,22,168,3,197,
198,27,28,23,197,2,87,95,23,196,1,23,195,1,23,197,1,87,94,23,197, 198,27,28,23,197,2,87,95,23,196,1,23,195,1,23,197,1,87,94,23,197,
1,27,248,22,157,14,2,20,27,249,80,159,41,49,37,23,196,1,11,27,27, 1,27,248,22,158,14,2,20,27,249,80,159,41,49,37,23,196,1,11,27,27,
248,22,187,3,23,200,1,28,192,192,36,27,27,248,22,187,3,23,202,1,28, 248,22,187,3,23,200,1,28,192,192,36,27,27,248,22,187,3,23,202,1,28,
192,192,36,249,22,171,5,23,197,1,83,158,40,20,100,95,89,162,8,44,36, 192,192,36,249,22,172,5,23,197,1,83,158,40,20,100,95,89,162,8,44,36,
48,9,224,3,2,33,63,23,195,1,23,196,1,27,248,22,156,5,23,195,1, 48,9,224,3,2,33,63,23,195,1,23,196,1,27,248,22,157,5,23,195,1,
248,80,159,39,54,37,193,159,36,20,105,159,36,16,1,11,16,0,83,158,42, 248,80,159,39,54,37,193,159,36,20,105,159,36,16,1,11,16,0,83,158,42,
20,103,145,2,1,2,1,29,11,11,11,11,11,10,43,80,158,36,36,20,105, 20,103,145,2,1,2,1,29,11,11,11,11,11,10,43,80,158,36,36,20,105,
159,38,16,17,2,2,2,3,2,4,2,5,2,6,2,7,2,8,2,9,2, 159,38,16,17,2,2,2,3,2,4,2,5,2,6,2,7,2,8,2,9,2,
@ -375,7 +375,7 @@
2,89,162,8,44,37,51,2,19,223,0,33,30,80,159,36,54,37,83,158,36, 2,89,162,8,44,37,51,2,19,223,0,33,30,80,159,36,54,37,83,158,36,
16,2,89,162,8,44,37,56,2,19,223,0,33,31,80,159,36,53,37,83,158, 16,2,89,162,8,44,37,56,2,19,223,0,33,31,80,159,36,53,37,83,158,
36,16,2,32,0,89,162,44,37,45,2,2,222,33,32,80,159,36,36,37,83, 36,16,2,32,0,89,162,44,37,45,2,2,222,33,32,80,159,36,36,37,83,
158,36,16,2,249,22,179,6,7,92,7,92,80,159,36,37,37,83,158,36,16, 158,36,16,2,249,22,180,6,7,92,7,92,80,159,36,37,37,83,158,36,16,
2,89,162,44,37,54,2,4,223,0,33,33,80,159,36,38,37,83,158,36,16, 2,89,162,44,37,54,2,4,223,0,33,33,80,159,36,38,37,83,158,36,16,
2,32,0,89,162,8,44,38,50,2,5,222,33,34,80,159,36,39,37,83,158, 2,32,0,89,162,8,44,38,50,2,5,222,33,34,80,159,36,39,37,83,158,
36,16,2,32,0,89,162,8,44,39,51,2,6,222,33,36,80,159,36,40,37, 36,16,2,32,0,89,162,8,44,39,51,2,6,222,33,36,80,159,36,40,37,
@ -388,8 +388,8 @@
33,47,80,159,36,46,37,83,158,36,16,2,83,158,39,20,99,96,2,13,89, 33,47,80,159,36,46,37,83,158,36,16,2,83,158,39,20,99,96,2,13,89,
162,44,36,44,9,223,0,33,48,89,162,44,37,45,9,223,0,33,49,89,162, 162,44,36,44,9,223,0,33,48,89,162,44,37,45,9,223,0,33,49,89,162,
44,38,55,9,223,0,33,50,80,159,36,47,37,83,158,36,16,2,27,248,22, 44,38,55,9,223,0,33,50,80,159,36,47,37,83,158,36,16,2,27,248,22,
164,14,248,22,189,7,27,28,249,22,184,8,247,22,133,8,2,21,6,1,1, 165,14,248,22,190,7,27,28,249,22,185,8,247,22,134,8,2,21,6,1,1,
59,6,1,1,58,250,22,161,7,6,14,14,40,91,94,126,97,93,42,41,126, 59,6,1,1,58,250,22,162,7,6,14,14,40,91,94,126,97,93,42,41,126,
97,40,46,42,41,23,196,2,23,196,1,89,162,8,44,38,48,2,14,223,0, 97,40,46,42,41,23,196,2,23,196,1,89,162,8,44,38,48,2,14,223,0,
33,53,80,159,36,48,37,83,158,36,16,2,83,158,39,20,99,96,2,15,89, 33,53,80,159,36,48,37,83,158,36,16,2,83,158,39,20,99,96,2,15,89,
162,8,44,39,8,24,9,223,0,33,60,89,162,44,38,47,9,223,0,33,61, 162,8,44,39,8,24,9,223,0,33,60,89,162,44,38,47,9,223,0,33,61,
@ -400,7 +400,7 @@
EVAL_ONE_SIZED_STR((char *)expr, 6245); EVAL_ONE_SIZED_STR((char *)expr, 6245);
} }
{ {
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,48,46,48,46,54,9,0,0,0,1,0,0,10,0,16,0, SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,48,46,48,46,55,9,0,0,0,1,0,0,10,0,16,0,
29,0,44,0,58,0,72,0,86,0,128,0,0,0,57,1,0,0,69,35,37, 29,0,44,0,58,0,72,0,86,0,128,0,0,0,57,1,0,0,69,35,37,
98,117,105,108,116,105,110,65,113,117,111,116,101,29,94,2,2,67,35,37,117, 98,117,105,108,116,105,110,65,113,117,111,116,101,29,94,2,2,67,35,37,117,
116,105,108,115,11,29,94,2,2,69,35,37,110,101,116,119,111,114,107,11,29, 116,105,108,115,11,29,94,2,2,69,35,37,110,101,116,119,111,114,107,11,29,
@ -420,7 +420,7 @@
EVAL_ONE_SIZED_STR((char *)expr, 352); EVAL_ONE_SIZED_STR((char *)expr, 352);
} }
{ {
SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,48,46,48,46,54,74,0,0,0,1,0,0,7,0,18,0, SHARED_OK static MZCOMPILED_STRING_FAR unsigned char expr[] = {35,126,7,53,46,48,46,48,46,55,74,0,0,0,1,0,0,7,0,18,0,
45,0,51,0,64,0,73,0,80,0,102,0,124,0,150,0,162,0,180,0,200, 45,0,51,0,64,0,73,0,80,0,102,0,124,0,150,0,162,0,180,0,200,
0,212,0,228,0,251,0,7,1,38,1,45,1,50,1,55,1,60,1,65,1, 0,212,0,228,0,251,0,7,1,38,1,45,1,50,1,55,1,60,1,65,1,
70,1,79,1,84,1,88,1,94,1,101,1,107,1,115,1,124,1,145,1,166, 70,1,79,1,84,1,88,1,94,1,101,1,107,1,115,1,124,1,145,1,166,
@ -446,47 +446,47 @@
109,101,5,3,46,122,111,5,3,46,122,111,6,6,6,110,97,116,105,118,101, 109,101,5,3,46,122,111,5,3,46,122,111,6,6,6,110,97,116,105,118,101,
64,108,111,111,112,63,108,105,98,6,3,3,46,115,115,6,4,4,46,114,107, 64,108,111,111,112,63,108,105,98,6,3,3,46,115,115,6,4,4,46,114,107,
116,5,4,46,114,107,116,67,105,103,110,111,114,101,100,249,22,14,195,80,159, 116,5,4,46,114,107,116,67,105,103,110,111,114,101,100,249,22,14,195,80,159,
38,46,38,250,22,135,14,23,197,1,23,199,1,249,80,159,43,39,38,23,198, 38,46,38,250,22,136,14,23,197,1,23,199,1,249,80,159,43,39,38,23,198,
1,2,23,250,22,135,14,23,197,1,23,199,1,249,80,159,43,39,38,23,198, 1,2,23,250,22,136,14,23,197,1,23,199,1,249,80,159,43,39,38,23,198,
1,2,24,252,22,135,14,23,199,1,23,201,1,2,25,247,22,134,8,249,80, 1,2,24,252,22,136,14,23,199,1,23,201,1,2,25,247,22,135,8,249,80,
159,45,39,38,23,200,1,80,159,45,36,38,252,22,135,14,23,199,1,23,201, 159,45,39,38,23,200,1,80,159,45,36,38,252,22,136,14,23,199,1,23,201,
1,2,25,247,22,134,8,249,80,159,45,39,38,23,200,1,80,159,45,36,38, 1,2,25,247,22,135,8,249,80,159,45,39,38,23,200,1,80,159,45,36,38,
27,252,22,135,14,23,200,1,23,202,1,2,25,247,22,134,8,249,80,159,46, 27,252,22,136,14,23,200,1,23,202,1,2,25,247,22,135,8,249,80,159,46,
39,38,23,201,1,80,159,46,36,38,27,250,22,152,14,196,11,32,0,89,162, 39,38,23,201,1,80,159,46,36,38,27,250,22,153,14,196,11,32,0,89,162,
8,44,36,41,9,222,11,28,192,249,22,71,195,194,11,27,252,22,135,14,23, 8,44,36,41,9,222,11,28,192,249,22,71,195,194,11,27,252,22,136,14,23,
200,1,23,202,1,2,25,247,22,134,8,249,80,159,46,39,38,23,201,1,80, 200,1,23,202,1,2,25,247,22,135,8,249,80,159,46,39,38,23,201,1,80,
159,46,36,38,27,250,22,152,14,196,11,32,0,89,162,8,44,36,41,9,222, 159,46,36,38,27,250,22,153,14,196,11,32,0,89,162,8,44,36,41,9,222,
11,28,192,249,22,71,195,194,11,27,250,22,135,14,23,198,1,23,200,1,249, 11,28,192,249,22,71,195,194,11,27,250,22,136,14,23,198,1,23,200,1,249,
80,159,44,39,38,23,199,1,2,23,27,250,22,152,14,196,11,32,0,89,162, 80,159,44,39,38,23,199,1,2,23,27,250,22,153,14,196,11,32,0,89,162,
8,44,36,41,9,222,11,28,192,249,22,71,195,194,11,27,250,22,135,14,23, 8,44,36,41,9,222,11,28,192,249,22,71,195,194,11,27,250,22,136,14,23,
198,1,23,200,1,249,80,159,44,39,38,23,199,1,2,24,27,250,22,152,14, 198,1,23,200,1,249,80,159,44,39,38,23,199,1,2,24,27,250,22,153,14,
196,11,32,0,89,162,8,44,36,41,9,222,11,28,192,249,22,71,195,194,11, 196,11,32,0,89,162,8,44,36,41,9,222,11,28,192,249,22,71,195,194,11,
87,94,28,248,80,159,37,38,38,23,195,2,12,250,22,154,9,77,108,111,97, 87,94,28,248,80,159,37,38,38,23,195,2,12,250,22,155,9,77,108,111,97,
100,47,117,115,101,45,99,111,109,112,105,108,101,100,6,25,25,112,97,116,104, 100,47,117,115,101,45,99,111,109,112,105,108,101,100,6,25,25,112,97,116,104,
32,111,114,32,118,97,108,105,100,45,112,97,116,104,32,115,116,114,105,110,103, 32,111,114,32,118,97,108,105,100,45,112,97,116,104,32,115,116,114,105,110,103,
23,197,2,91,159,46,11,90,161,37,36,11,28,248,22,141,14,23,205,2,23, 23,197,2,91,159,46,11,90,161,37,36,11,28,248,22,142,14,23,205,2,23,
204,2,27,247,22,145,5,28,23,193,2,249,22,142,14,23,207,2,23,195,1, 204,2,27,247,22,146,5,28,23,193,2,249,22,143,14,23,207,2,23,195,1,
23,205,2,90,161,39,37,11,248,22,138,14,23,205,1,87,94,23,196,1,90, 23,205,2,90,161,39,37,11,248,22,139,14,23,205,1,87,94,23,196,1,90,
161,38,40,11,28,23,205,2,27,248,22,186,13,23,197,2,27,248,22,169,7, 161,38,40,11,28,23,205,2,27,248,22,187,13,23,197,2,27,248,22,170,7,
23,195,2,28,28,249,22,180,3,23,195,2,40,249,22,172,7,5,4,46,114, 23,195,2,28,28,249,22,180,3,23,195,2,40,249,22,173,7,5,4,46,114,
107,116,249,22,175,7,23,198,2,249,22,168,3,23,199,2,40,11,249,22,7, 107,116,249,22,176,7,23,198,2,249,22,168,3,23,199,2,40,11,249,22,7,
23,199,2,248,22,190,13,249,22,176,7,250,22,175,7,23,202,1,36,249,22, 23,199,2,248,22,191,13,249,22,177,7,250,22,176,7,23,202,1,36,249,22,
168,3,23,203,1,40,5,3,46,115,115,249,22,7,23,199,2,11,249,22,7, 168,3,23,203,1,40,5,3,46,115,115,249,22,7,23,199,2,11,249,22,7,
23,197,2,11,90,161,37,42,11,28,249,22,184,8,23,199,2,23,197,2,23, 23,197,2,11,90,161,37,42,11,28,249,22,185,8,23,199,2,23,197,2,23,
193,2,249,22,135,14,23,196,2,23,199,2,90,161,37,43,11,28,23,198,2, 193,2,249,22,136,14,23,196,2,23,199,2,90,161,37,43,11,28,23,198,2,
28,249,22,184,8,23,200,2,23,197,1,23,193,1,87,94,23,193,1,249,22, 28,249,22,185,8,23,200,2,23,197,1,23,193,1,87,94,23,193,1,249,22,
135,14,23,196,2,23,200,2,87,94,23,195,1,11,90,161,37,44,11,28,249, 136,14,23,196,2,23,200,2,87,94,23,195,1,11,90,161,37,44,11,28,249,
22,184,8,23,196,2,68,114,101,108,97,116,105,118,101,87,94,23,194,1,2, 22,185,8,23,196,2,68,114,101,108,97,116,105,118,101,87,94,23,194,1,2,
22,23,194,1,90,161,37,45,11,247,22,160,14,27,27,250,22,152,14,23,204, 22,23,194,1,90,161,37,45,11,247,22,161,14,27,27,250,22,153,14,23,204,
2,11,32,0,89,162,8,44,36,41,9,222,11,28,192,249,22,71,23,203,2, 2,11,32,0,89,162,8,44,36,41,9,222,11,28,192,249,22,71,23,203,2,
194,11,27,28,23,202,2,28,23,194,2,11,27,250,22,152,14,23,206,2,11, 194,11,27,28,23,202,2,28,23,194,2,11,27,250,22,153,14,23,206,2,11,
32,0,89,162,8,44,36,41,9,222,11,28,192,249,22,71,23,205,2,194,11, 32,0,89,162,8,44,36,41,9,222,11,28,192,249,22,71,23,205,2,194,11,
11,27,28,23,195,2,23,195,2,23,194,2,27,89,162,44,37,50,62,122,111, 11,27,28,23,195,2,23,195,2,23,194,2,27,89,162,44,37,50,62,122,111,
225,14,12,8,33,33,27,89,162,44,37,50,66,97,108,116,45,122,111,225,15, 225,14,12,8,33,33,27,89,162,44,37,50,66,97,108,116,45,122,111,225,15,
13,10,33,34,27,89,162,44,37,52,9,225,16,14,10,33,35,27,89,162,44, 13,10,33,34,27,89,162,44,37,52,9,225,16,14,10,33,35,27,89,162,44,
37,52,9,225,17,15,12,33,36,27,28,23,200,2,23,200,2,248,22,182,8, 37,52,9,225,17,15,12,33,36,27,28,23,200,2,23,200,2,248,22,183,8,
23,200,2,27,28,23,207,2,28,23,200,2,87,94,23,201,1,23,200,2,248, 23,200,2,27,28,23,207,2,28,23,200,2,87,94,23,201,1,23,200,2,248,
22,182,8,23,202,1,11,27,28,23,195,2,28,23,197,1,27,249,22,5,89, 22,183,8,23,202,1,11,27,28,23,195,2,28,23,197,1,27,249,22,5,89,
162,8,44,37,53,9,225,23,21,17,33,37,23,215,2,27,28,23,202,2,11, 162,8,44,37,53,9,225,23,21,17,33,37,23,215,2,27,28,23,202,2,11,
193,28,192,192,28,193,28,23,202,2,28,249,22,180,3,248,22,73,196,248,22, 193,28,192,192,28,193,28,23,202,2,28,249,22,180,3,248,22,73,196,248,22,
73,23,205,2,193,11,11,11,11,87,94,23,197,1,11,28,23,193,2,87,105, 73,23,205,2,193,11,11,11,11,87,94,23,197,1,11,28,23,193,2,87,105,
@ -494,8 +494,8 @@
23,199,1,23,198,1,23,196,1,23,195,1,23,194,1,20,14,159,80,159,56, 23,199,1,23,198,1,23,196,1,23,195,1,23,194,1,20,14,159,80,159,56,
40,38,250,80,159,59,41,38,249,22,27,11,80,159,8,25,40,38,22,168,4, 40,38,250,80,159,59,41,38,249,22,27,11,80,159,8,25,40,38,22,168,4,
11,20,14,159,80,159,56,40,38,250,80,159,59,41,38,249,22,27,11,80,159, 11,20,14,159,80,159,56,40,38,250,80,159,59,41,38,249,22,27,11,80,159,
8,25,40,38,22,145,5,28,248,22,181,13,23,215,2,23,214,1,87,94,23, 8,25,40,38,22,146,5,28,248,22,182,13,23,215,2,23,214,1,87,94,23,
214,1,247,22,158,14,249,247,22,163,14,248,22,72,195,23,24,87,94,23,193, 214,1,247,22,159,14,249,247,22,164,14,248,22,72,195,23,24,87,94,23,193,
1,27,28,23,195,2,28,23,197,1,27,249,22,5,89,162,8,44,37,53,9, 1,27,28,23,195,2,28,23,197,1,27,249,22,5,89,162,8,44,37,53,9,
225,24,22,19,33,38,23,216,2,27,28,23,204,2,11,193,28,192,192,28,193, 225,24,22,19,33,38,23,216,2,27,28,23,204,2,11,193,28,192,192,28,193,
28,203,28,249,22,180,3,248,22,73,196,248,22,73,206,193,11,11,11,11,87, 28,203,28,249,22,180,3,248,22,73,196,248,22,73,206,193,11,11,11,11,87,
@ -503,8 +503,8 @@
208,1,23,201,1,23,200,1,23,199,1,23,196,1,23,195,1,20,14,159,80, 208,1,23,201,1,23,200,1,23,199,1,23,196,1,23,195,1,20,14,159,80,
159,57,40,38,250,80,159,8,24,41,38,249,22,27,11,80,159,8,26,40,38, 159,57,40,38,250,80,159,8,24,41,38,249,22,27,11,80,159,8,26,40,38,
22,168,4,23,214,1,20,14,159,80,159,57,40,38,250,80,159,8,24,41,38, 22,168,4,23,214,1,20,14,159,80,159,57,40,38,250,80,159,8,24,41,38,
249,22,27,11,80,159,8,26,40,38,22,145,5,28,248,22,181,13,23,216,2, 249,22,27,11,80,159,8,26,40,38,22,146,5,28,248,22,182,13,23,216,2,
23,215,1,87,94,23,215,1,247,22,158,14,249,247,22,163,14,248,22,72,195, 23,215,1,87,94,23,215,1,247,22,159,14,249,247,22,164,14,248,22,72,195,
23,25,87,94,23,193,1,27,28,23,197,2,28,23,201,1,27,249,22,5,83, 23,25,87,94,23,193,1,27,28,23,197,2,28,23,201,1,27,249,22,5,83,
158,40,20,100,94,89,162,8,44,37,51,9,225,25,23,19,33,39,23,212,1, 158,40,20,100,94,89,162,8,44,37,51,9,225,25,23,19,33,39,23,212,1,
23,217,2,27,28,23,204,2,11,193,28,192,192,28,193,28,23,204,2,28,249, 23,217,2,27,28,23,204,2,11,193,28,192,192,28,193,28,23,204,2,28,249,
@ -513,8 +513,8 @@
211,1,23,210,1,23,202,1,23,200,1,23,197,1,23,196,1,20,14,159,80, 211,1,23,210,1,23,202,1,23,200,1,23,197,1,23,196,1,20,14,159,80,
159,58,40,38,250,80,159,8,25,41,38,249,22,27,11,80,159,8,27,40,38, 159,58,40,38,250,80,159,8,25,41,38,249,22,27,11,80,159,8,27,40,38,
22,168,4,11,20,14,159,80,159,58,40,38,250,80,159,8,25,41,38,249,22, 22,168,4,11,20,14,159,80,159,58,40,38,250,80,159,8,25,41,38,249,22,
27,11,80,159,8,27,40,38,22,145,5,28,248,22,181,13,23,217,2,23,216, 27,11,80,159,8,27,40,38,22,146,5,28,248,22,182,13,23,217,2,23,216,
1,87,94,23,216,1,247,22,158,14,249,247,22,143,5,248,22,72,195,23,26, 1,87,94,23,216,1,247,22,159,14,249,247,22,144,5,248,22,72,195,23,26,
87,94,23,193,1,27,28,23,197,1,28,23,201,1,27,249,22,5,83,158,40, 87,94,23,193,1,27,28,23,197,1,28,23,201,1,27,249,22,5,83,158,40,
20,100,94,89,162,8,44,37,51,9,225,26,24,21,33,40,23,214,1,23,218, 20,100,94,89,162,8,44,37,51,9,225,26,24,21,33,40,23,214,1,23,218,
1,27,28,23,205,2,11,193,28,192,192,28,193,28,204,28,249,22,180,3,248, 1,27,28,23,205,2,11,193,28,192,192,28,193,28,204,28,249,22,180,3,248,
@ -522,21 +522,21 @@
87,94,23,201,1,11,28,23,193,2,87,95,23,212,1,23,198,1,20,14,159, 87,94,23,201,1,11,28,23,193,2,87,95,23,212,1,23,198,1,20,14,159,
80,159,59,40,38,250,80,159,8,26,41,38,249,22,27,11,80,159,8,28,40, 80,159,59,40,38,250,80,159,8,26,41,38,249,22,27,11,80,159,8,28,40,
38,22,168,4,23,216,1,20,14,159,80,159,59,40,38,250,80,159,8,26,41, 38,22,168,4,23,216,1,20,14,159,80,159,59,40,38,250,80,159,8,26,41,
38,249,22,27,11,80,159,8,28,40,38,22,145,5,28,248,22,181,13,23,218, 38,249,22,27,11,80,159,8,28,40,38,22,146,5,28,248,22,182,13,23,218,
2,23,217,1,87,94,23,217,1,247,22,158,14,249,247,22,143,5,248,22,72, 2,23,217,1,87,94,23,217,1,247,22,159,14,249,247,22,144,5,248,22,72,
195,23,27,87,94,23,193,1,27,28,23,199,2,87,94,23,214,1,23,213,1, 195,23,27,87,94,23,193,1,27,28,23,199,2,87,94,23,214,1,23,213,1,
87,94,23,213,1,23,214,1,20,14,159,80,159,8,24,40,38,250,80,159,8, 87,94,23,213,1,23,214,1,20,14,159,80,159,8,24,40,38,250,80,159,8,
27,41,38,249,22,27,11,80,159,8,29,40,38,22,168,4,28,23,29,28,23, 27,41,38,249,22,27,11,80,159,8,29,40,38,22,168,4,28,23,29,28,23,
202,1,11,195,87,94,23,202,1,11,20,14,159,80,159,8,24,40,38,250,80, 202,1,11,195,87,94,23,202,1,11,20,14,159,80,159,8,24,40,38,250,80,
159,8,27,41,38,249,22,27,11,80,159,8,29,40,38,22,145,5,28,248,22, 159,8,27,41,38,249,22,27,11,80,159,8,29,40,38,22,146,5,28,248,22,
181,13,23,219,2,23,218,1,87,94,23,218,1,247,22,158,14,249,247,22,143, 182,13,23,219,2,23,218,1,87,94,23,218,1,247,22,159,14,249,247,22,144,
5,194,23,28,0,17,35,114,120,34,94,40,46,42,63,41,47,40,46,42,41, 5,194,23,28,0,17,35,114,120,34,94,40,46,42,63,41,47,40,46,42,41,
36,34,32,43,89,162,8,44,37,59,2,26,222,33,44,27,249,22,168,14,2, 36,34,32,43,89,162,8,44,37,59,2,26,222,33,44,27,249,22,169,14,2,
42,23,196,2,28,23,193,2,87,94,23,194,1,249,22,71,248,22,96,23,196, 42,23,196,2,28,23,193,2,87,94,23,194,1,249,22,71,248,22,96,23,196,
2,27,248,22,105,23,197,1,27,249,22,168,14,2,42,23,196,2,28,23,193, 2,27,248,22,105,23,197,1,27,249,22,169,14,2,42,23,196,2,28,23,193,
2,87,94,23,194,1,249,22,71,248,22,96,23,196,2,27,248,22,105,23,197, 2,87,94,23,194,1,249,22,71,248,22,96,23,196,2,27,248,22,105,23,197,
1,27,249,22,168,14,2,42,23,196,2,28,23,193,2,87,94,23,194,1,249, 1,27,249,22,169,14,2,42,23,196,2,28,23,193,2,87,94,23,194,1,249,
22,71,248,22,96,23,196,2,27,248,22,105,23,197,1,27,249,22,168,14,2, 22,71,248,22,96,23,196,2,27,248,22,105,23,197,1,27,249,22,169,14,2,
42,23,196,2,28,23,193,2,87,94,23,194,1,249,22,71,248,22,96,23,196, 42,23,196,2,28,23,193,2,87,94,23,194,1,249,22,71,248,22,96,23,196,
2,248,2,43,248,22,105,23,197,1,248,22,81,194,248,22,81,194,248,22,81, 2,248,2,43,248,22,105,23,197,1,248,22,81,194,248,22,81,194,248,22,81,
194,248,22,81,194,32,45,89,162,44,37,55,2,26,222,33,46,28,248,22,79, 194,248,22,81,194,32,45,89,162,44,37,55,2,26,222,33,46,28,248,22,79,
@ -546,12 +546,12 @@
79,248,22,73,23,195,2,249,22,7,9,248,22,72,195,91,159,38,11,90,161, 79,248,22,73,23,195,2,249,22,7,9,248,22,72,195,91,159,38,11,90,161,
38,36,11,248,2,45,248,22,73,196,249,22,7,249,22,71,248,22,72,199,196, 38,36,11,248,2,45,248,22,73,196,249,22,7,249,22,71,248,22,72,199,196,
195,249,22,7,249,22,71,248,22,72,199,196,195,249,22,7,249,22,71,248,22, 195,249,22,7,249,22,71,248,22,72,199,196,195,249,22,7,249,22,71,248,22,
72,199,196,195,27,27,249,22,168,14,2,42,23,197,2,28,23,193,2,87,94, 72,199,196,195,27,27,249,22,169,14,2,42,23,197,2,28,23,193,2,87,94,
23,195,1,249,22,71,248,22,96,23,196,2,27,248,22,105,23,197,1,27,249, 23,195,1,249,22,71,248,22,96,23,196,2,27,248,22,105,23,197,1,27,249,
22,168,14,2,42,23,196,2,28,23,193,2,87,94,23,194,1,249,22,71,248, 22,169,14,2,42,23,196,2,28,23,193,2,87,94,23,194,1,249,22,71,248,
22,96,23,196,2,27,248,22,105,23,197,1,27,249,22,168,14,2,42,23,196, 22,96,23,196,2,27,248,22,105,23,197,1,27,249,22,169,14,2,42,23,196,
2,28,23,193,2,87,94,23,194,1,249,22,71,248,22,96,23,196,2,27,248, 2,28,23,193,2,87,94,23,194,1,249,22,71,248,22,96,23,196,2,27,248,
22,105,23,197,1,27,249,22,168,14,2,42,23,196,2,28,23,193,2,87,94, 22,105,23,197,1,27,249,22,169,14,2,42,23,196,2,28,23,193,2,87,94,
23,194,1,249,22,71,248,22,96,23,196,2,248,2,43,248,22,105,23,197,1, 23,194,1,249,22,71,248,22,96,23,196,2,248,2,43,248,22,105,23,197,1,
248,22,81,194,248,22,81,194,248,22,81,194,248,22,81,195,28,23,195,1,192, 248,22,81,194,248,22,81,194,248,22,81,194,248,22,81,195,28,23,195,1,192,
28,248,22,79,248,22,73,23,195,2,249,22,7,9,248,22,72,195,91,159,38, 28,248,22,79,248,22,73,23,195,2,249,22,7,9,248,22,72,195,91,159,38,
@ -560,69 +560,69 @@
196,28,248,22,79,248,22,73,23,195,2,249,22,7,9,248,22,72,195,91,159, 196,28,248,22,79,248,22,73,23,195,2,249,22,7,9,248,22,72,195,91,159,
38,11,90,161,38,36,11,248,2,45,248,22,73,196,249,22,7,249,22,71,248, 38,11,90,161,38,36,11,248,2,45,248,22,73,196,249,22,7,249,22,71,248,
22,72,199,196,195,249,22,7,249,22,71,248,22,72,199,196,195,249,22,7,249, 22,72,199,196,195,249,22,7,249,22,71,248,22,72,199,196,195,249,22,7,249,
22,71,248,22,72,199,196,195,87,95,28,248,22,186,4,195,12,250,22,154,9, 22,71,248,22,72,199,196,195,87,95,28,248,22,186,4,195,12,250,22,155,9,
2,18,6,20,20,114,101,115,111,108,118,101,100,45,109,111,100,117,108,101,45, 2,18,6,20,20,114,101,115,111,108,118,101,100,45,109,111,100,117,108,101,45,
112,97,116,104,197,28,24,193,2,248,24,194,1,195,87,94,23,193,1,12,27, 112,97,116,104,197,28,24,193,2,248,24,194,1,195,87,94,23,193,1,12,27,
27,250,22,150,2,80,159,42,43,38,248,22,129,15,247,22,161,12,11,28,23, 27,250,22,150,2,80,159,42,43,38,248,22,130,15,247,22,162,12,11,28,23,
193,2,192,87,94,23,193,1,27,247,22,130,2,87,94,250,22,148,2,80,159, 193,2,192,87,94,23,193,1,27,247,22,130,2,87,94,250,22,148,2,80,159,
43,43,38,248,22,129,15,247,22,161,12,195,192,250,22,148,2,195,198,66,97, 43,43,38,248,22,130,15,247,22,162,12,195,192,250,22,148,2,195,198,66,97,
116,116,97,99,104,251,211,197,198,199,10,28,192,250,22,153,9,11,196,195,248, 116,116,97,99,104,251,211,197,198,199,10,28,192,250,22,154,9,11,196,195,248,
22,151,9,194,32,51,89,162,44,37,52,2,26,222,33,52,28,248,22,79,248, 22,152,9,194,32,51,89,162,44,37,52,2,26,222,33,52,28,248,22,79,248,
22,73,23,195,2,249,22,7,9,248,22,72,195,91,159,38,11,90,161,38,36, 22,73,23,195,2,249,22,7,9,248,22,72,195,91,159,38,11,90,161,38,36,
11,27,248,22,73,196,28,248,22,79,248,22,73,23,195,2,249,22,7,9,248, 11,27,248,22,73,196,28,248,22,79,248,22,73,23,195,2,249,22,7,9,248,
22,72,195,91,159,38,11,90,161,38,36,11,248,2,51,248,22,73,196,249,22, 22,72,195,91,159,38,11,90,161,38,36,11,248,2,51,248,22,73,196,249,22,
7,249,22,71,248,22,72,199,196,195,249,22,7,249,22,71,248,22,72,199,196, 7,249,22,71,248,22,72,199,196,195,249,22,7,249,22,71,248,22,72,199,196,
195,32,53,89,162,8,44,37,55,2,26,222,33,54,27,249,22,168,14,2,42, 195,32,53,89,162,8,44,37,55,2,26,222,33,54,27,249,22,169,14,2,42,
23,196,2,28,23,193,2,87,94,23,194,1,249,22,71,248,22,96,23,196,2, 23,196,2,28,23,193,2,87,94,23,194,1,249,22,71,248,22,96,23,196,2,
27,248,22,105,23,197,1,27,249,22,168,14,2,42,23,196,2,28,23,193,2, 27,248,22,105,23,197,1,27,249,22,169,14,2,42,23,196,2,28,23,193,2,
87,94,23,194,1,249,22,71,248,22,96,23,196,2,27,248,22,105,23,197,1, 87,94,23,194,1,249,22,71,248,22,96,23,196,2,27,248,22,105,23,197,1,
27,249,22,168,14,2,42,23,196,2,28,23,193,2,87,94,23,194,1,249,22, 27,249,22,169,14,2,42,23,196,2,28,23,193,2,87,94,23,194,1,249,22,
71,248,22,96,23,196,2,248,2,53,248,22,105,23,197,1,248,22,81,194,248, 71,248,22,96,23,196,2,248,2,53,248,22,105,23,197,1,248,22,81,194,248,
22,81,194,248,22,81,194,32,55,89,162,44,37,52,2,26,222,33,56,28,248, 22,81,194,248,22,81,194,32,55,89,162,44,37,52,2,26,222,33,56,28,248,
22,79,248,22,73,23,195,2,249,22,7,9,248,22,72,195,91,159,38,11,90, 22,79,248,22,73,23,195,2,249,22,7,9,248,22,72,195,91,159,38,11,90,
161,38,36,11,27,248,22,73,196,28,248,22,79,248,22,73,23,195,2,249,22, 161,38,36,11,27,248,22,73,196,28,248,22,79,248,22,73,23,195,2,249,22,
7,9,248,22,72,195,91,159,38,11,90,161,38,36,11,248,2,55,248,22,73, 7,9,248,22,72,195,91,159,38,11,90,161,38,36,11,248,2,55,248,22,73,
196,249,22,7,249,22,71,248,22,72,199,196,195,249,22,7,249,22,71,248,22, 196,249,22,7,249,22,71,248,22,72,199,196,195,249,22,7,249,22,71,248,22,
72,199,196,195,32,57,89,162,8,44,37,55,2,26,222,33,58,27,249,22,168, 72,199,196,195,32,57,89,162,8,44,37,55,2,26,222,33,58,27,249,22,169,
14,2,42,23,196,2,28,23,193,2,87,94,23,194,1,249,22,71,248,22,96, 14,2,42,23,196,2,28,23,193,2,87,94,23,194,1,249,22,71,248,22,96,
23,196,2,27,248,22,105,23,197,1,27,249,22,168,14,2,42,23,196,2,28, 23,196,2,27,248,22,105,23,197,1,27,249,22,169,14,2,42,23,196,2,28,
23,193,2,87,94,23,194,1,249,22,71,248,22,96,23,196,2,27,248,22,105, 23,193,2,87,94,23,194,1,249,22,71,248,22,96,23,196,2,27,248,22,105,
23,197,1,27,249,22,168,14,2,42,23,196,2,28,23,193,2,87,94,23,194, 23,197,1,27,249,22,169,14,2,42,23,196,2,28,23,193,2,87,94,23,194,
1,249,22,71,248,22,96,23,196,2,248,2,57,248,22,105,23,197,1,248,22, 1,249,22,71,248,22,96,23,196,2,248,2,57,248,22,105,23,197,1,248,22,
81,194,248,22,81,194,248,22,81,194,28,249,22,183,6,194,6,1,1,46,2, 81,194,248,22,81,194,248,22,81,194,28,249,22,184,6,194,6,1,1,46,2,
22,28,249,22,183,6,194,6,2,2,46,46,62,117,112,192,0,11,35,114,120, 22,28,249,22,184,6,194,6,2,2,46,46,62,117,112,192,0,11,35,114,120,
34,91,46,93,115,115,36,34,32,61,89,162,44,37,52,2,26,222,33,62,28, 34,91,46,93,115,115,36,34,32,61,89,162,44,37,52,2,26,222,33,62,28,
248,22,79,248,22,73,23,195,2,249,22,7,9,248,22,72,195,91,159,38,11, 248,22,79,248,22,73,23,195,2,249,22,7,9,248,22,72,195,91,159,38,11,
90,161,38,36,11,27,248,22,73,196,28,248,22,79,248,22,73,23,195,2,249, 90,161,38,36,11,27,248,22,73,196,28,248,22,79,248,22,73,23,195,2,249,
22,7,9,248,22,72,195,91,159,38,11,90,161,38,36,11,248,2,61,248,22, 22,7,9,248,22,72,195,91,159,38,11,90,161,38,36,11,248,2,61,248,22,
73,196,249,22,7,249,22,71,248,22,72,199,196,195,249,22,7,249,22,71,248, 73,196,249,22,7,249,22,71,248,22,72,199,196,195,249,22,7,249,22,71,248,
22,72,199,196,195,32,63,89,162,8,44,37,55,2,26,222,33,64,27,249,22, 22,72,199,196,195,32,63,89,162,8,44,37,55,2,26,222,33,64,27,249,22,
168,14,2,42,23,196,2,28,23,193,2,87,94,23,194,1,249,22,71,248,22, 169,14,2,42,23,196,2,28,23,193,2,87,94,23,194,1,249,22,71,248,22,
96,23,196,2,27,248,22,105,23,197,1,27,249,22,168,14,2,42,23,196,2, 96,23,196,2,27,248,22,105,23,197,1,27,249,22,169,14,2,42,23,196,2,
28,23,193,2,87,94,23,194,1,249,22,71,248,22,96,23,196,2,27,248,22, 28,23,193,2,87,94,23,194,1,249,22,71,248,22,96,23,196,2,27,248,22,
105,23,197,1,27,249,22,168,14,2,42,23,196,2,28,23,193,2,87,94,23, 105,23,197,1,27,249,22,169,14,2,42,23,196,2,28,23,193,2,87,94,23,
194,1,249,22,71,248,22,96,23,196,2,248,2,63,248,22,105,23,197,1,248, 194,1,249,22,71,248,22,96,23,196,2,248,2,63,248,22,105,23,197,1,248,
22,81,194,248,22,81,194,248,22,81,194,32,65,89,162,8,44,37,55,2,26, 22,81,194,248,22,81,194,248,22,81,194,32,65,89,162,8,44,37,55,2,26,
222,33,66,27,249,22,168,14,2,42,23,196,2,28,23,193,2,87,94,23,194, 222,33,66,27,249,22,169,14,2,42,23,196,2,28,23,193,2,87,94,23,194,
1,249,22,71,248,22,96,23,196,2,27,248,22,105,23,197,1,27,249,22,168, 1,249,22,71,248,22,96,23,196,2,27,248,22,105,23,197,1,27,249,22,169,
14,2,42,23,196,2,28,23,193,2,87,94,23,194,1,249,22,71,248,22,96, 14,2,42,23,196,2,28,23,193,2,87,94,23,194,1,249,22,71,248,22,96,
23,196,2,27,248,22,105,23,197,1,27,249,22,168,14,2,42,23,196,2,28, 23,196,2,27,248,22,105,23,197,1,27,249,22,169,14,2,42,23,196,2,28,
23,193,2,87,94,23,194,1,249,22,71,248,22,96,23,196,2,248,2,65,248, 23,193,2,87,94,23,194,1,249,22,71,248,22,96,23,196,2,248,2,65,248,
22,105,23,197,1,248,22,81,194,248,22,81,194,248,22,81,194,27,248,2,65, 22,105,23,197,1,248,22,81,194,248,22,81,194,248,22,81,194,27,248,2,65,
23,195,1,192,28,249,22,186,8,248,22,73,23,200,2,23,197,1,28,249,22, 23,195,1,192,28,249,22,187,8,248,22,73,23,200,2,23,197,1,28,249,22,
184,8,248,22,72,23,200,2,23,196,1,251,22,151,9,2,18,6,26,26,99, 185,8,248,22,72,23,200,2,23,196,1,251,22,152,9,2,18,6,26,26,99,
121,99,108,101,32,105,110,32,108,111,97,100,105,110,103,32,97,116,32,126,101, 121,99,108,101,32,105,110,32,108,111,97,100,105,110,103,32,97,116,32,126,101,
58,32,126,101,23,200,1,249,22,2,22,73,248,22,86,249,22,71,23,206,1, 58,32,126,101,23,200,1,249,22,2,22,73,248,22,86,249,22,71,23,206,1,
23,202,1,12,12,247,192,20,14,159,80,159,40,45,38,249,22,71,248,22,129, 23,202,1,12,12,247,192,20,14,159,80,159,40,45,38,249,22,71,248,22,130,
15,247,22,161,12,23,197,1,20,14,159,80,159,40,40,38,250,80,159,43,41, 15,247,22,162,12,23,197,1,20,14,159,80,159,40,40,38,250,80,159,43,41,
38,249,22,27,11,80,159,45,40,38,22,167,4,23,196,1,249,247,22,144,5, 38,249,22,27,11,80,159,45,40,38,22,167,4,23,196,1,249,247,22,145,5,
23,198,1,248,22,59,248,22,185,13,23,198,1,87,94,28,28,248,22,181,13, 23,198,1,248,22,59,248,22,186,13,23,198,1,87,94,28,28,248,22,182,13,
23,196,2,10,248,22,130,5,23,196,2,12,28,23,197,2,250,22,153,9,11, 23,196,2,10,248,22,130,5,23,196,2,12,28,23,197,2,250,22,154,9,11,
6,15,15,98,97,100,32,109,111,100,117,108,101,32,112,97,116,104,23,200,2, 6,15,15,98,97,100,32,109,111,100,117,108,101,32,112,97,116,104,23,200,2,
250,22,154,9,2,18,6,19,19,109,111,100,117,108,101,45,112,97,116,104,32, 250,22,155,9,2,18,6,19,19,109,111,100,117,108,101,45,112,97,116,104,32,
111,114,32,112,97,116,104,23,198,2,28,28,248,22,69,23,196,2,249,22,184, 111,114,32,112,97,116,104,23,198,2,28,28,248,22,69,23,196,2,249,22,185,
8,248,22,72,23,198,2,2,4,11,248,22,187,4,248,22,96,196,28,28,248, 8,248,22,72,23,198,2,2,4,11,248,22,187,4,248,22,96,196,28,28,248,
22,69,23,196,2,249,22,184,8,248,22,72,23,198,2,66,112,108,97,110,101, 22,69,23,196,2,249,22,185,8,248,22,72,23,198,2,66,112,108,97,110,101,
116,11,87,94,28,207,12,20,14,159,80,159,37,52,38,80,158,37,50,90,161, 116,11,87,94,28,207,12,20,14,159,80,159,37,52,38,80,158,37,50,90,161,
37,36,10,249,22,169,4,21,94,2,27,6,19,19,112,108,97,110,101,116,47, 37,36,10,249,22,169,4,21,94,2,27,6,19,19,112,108,97,110,101,116,47,
114,101,115,111,108,118,101,114,46,114,107,116,1,27,112,108,97,110,101,116,45, 114,101,115,111,108,118,101,114,46,114,107,116,1,27,112,108,97,110,101,116,45,
@ -630,93 +630,93 @@
252,212,199,200,201,202,80,158,42,50,87,94,23,193,1,27,89,162,8,44,37, 252,212,199,200,201,202,80,158,42,50,87,94,23,193,1,27,89,162,8,44,37,
46,79,115,104,111,119,45,99,111,108,108,101,99,116,105,111,110,45,101,114,114, 46,79,115,104,111,119,45,99,111,108,108,101,99,116,105,111,110,45,101,114,114,
223,5,33,50,27,28,248,22,56,23,198,2,27,250,22,150,2,80,159,43,44, 223,5,33,50,27,28,248,22,56,23,198,2,27,250,22,150,2,80,159,43,44,
38,249,22,71,23,203,2,247,22,159,14,11,28,23,193,2,192,87,94,23,193, 38,249,22,71,23,203,2,247,22,160,14,11,28,23,193,2,192,87,94,23,193,
1,91,159,38,11,90,161,38,36,11,27,248,22,62,23,202,2,248,2,51,248, 1,91,159,38,11,90,161,38,36,11,27,248,22,62,23,202,2,248,2,51,248,
2,53,23,195,1,27,251,80,159,47,54,38,2,18,23,202,1,28,248,22,79, 2,53,23,195,1,27,251,80,159,47,54,38,2,18,23,202,1,28,248,22,79,
23,199,2,23,199,2,248,22,72,23,199,2,28,248,22,79,23,199,2,9,248, 23,199,2,23,199,2,248,22,72,23,199,2,28,248,22,79,23,199,2,9,248,
22,73,23,199,2,249,22,135,14,23,195,1,28,248,22,79,23,197,1,87,94, 22,73,23,199,2,249,22,136,14,23,195,1,28,248,22,79,23,197,1,87,94,
23,197,1,6,8,8,109,97,105,110,46,114,107,116,249,22,136,7,23,199,1, 23,197,1,6,8,8,109,97,105,110,46,114,107,116,249,22,137,7,23,199,1,
6,4,4,46,114,107,116,28,248,22,177,6,23,198,2,87,94,23,194,1,27, 6,4,4,46,114,107,116,28,248,22,178,6,23,198,2,87,94,23,194,1,27,
27,28,23,200,2,28,249,22,184,8,23,202,2,80,158,43,47,80,158,41,48, 27,28,23,200,2,28,249,22,185,8,23,202,2,80,158,43,47,80,158,41,48,
27,248,22,188,4,23,202,2,28,248,22,181,13,23,194,2,91,159,39,11,90, 27,248,22,188,4,23,202,2,28,248,22,182,13,23,194,2,91,159,39,11,90,
161,39,36,11,248,22,138,14,23,197,1,87,95,83,160,38,11,80,158,45,47, 161,39,36,11,248,22,139,14,23,197,1,87,95,83,160,38,11,80,158,45,47,
23,204,2,83,160,38,11,80,158,45,48,192,192,11,11,28,23,193,2,192,87, 23,204,2,83,160,38,11,80,158,45,48,192,192,11,11,28,23,193,2,192,87,
94,23,193,1,27,247,22,145,5,28,23,193,2,192,87,94,23,193,1,247,22, 94,23,193,1,27,247,22,146,5,28,23,193,2,192,87,94,23,193,1,247,22,
158,14,27,250,22,150,2,80,159,44,44,38,249,22,71,23,204,2,23,199,2, 159,14,27,250,22,150,2,80,159,44,44,38,249,22,71,23,204,2,23,199,2,
11,28,23,193,2,192,87,94,23,193,1,91,159,38,11,90,161,38,36,11,248, 11,28,23,193,2,192,87,94,23,193,1,91,159,38,11,90,161,38,36,11,248,
2,55,248,2,57,23,203,2,250,22,1,22,135,14,23,199,1,249,22,85,249, 2,55,248,2,57,23,203,2,250,22,1,22,136,14,23,199,1,249,22,85,249,
22,2,32,0,89,162,8,44,37,44,9,222,33,59,23,200,1,248,22,81,27, 22,2,32,0,89,162,8,44,37,44,9,222,33,59,23,200,1,248,22,81,27,
248,22,180,6,23,202,2,28,249,22,180,3,194,39,28,249,22,183,6,2,28, 248,22,181,6,23,202,2,28,249,22,180,3,194,39,28,249,22,184,6,2,28,
249,22,135,7,204,249,22,168,3,198,39,249,22,136,7,250,22,135,7,205,36, 249,22,136,7,204,249,22,168,3,198,39,249,22,137,7,250,22,136,7,205,36,
249,22,168,3,199,39,2,29,200,200,28,248,22,181,13,23,198,2,87,94,23, 249,22,168,3,199,39,2,29,200,200,28,248,22,182,13,23,198,2,87,94,23,
194,1,28,248,22,140,14,23,198,2,27,248,22,144,14,23,199,2,91,159,39, 194,1,28,248,22,141,14,23,198,2,27,248,22,145,14,23,199,2,91,159,39,
11,90,161,39,36,11,248,22,138,14,23,197,2,87,95,23,195,1,23,193,1, 11,90,161,39,36,11,248,22,139,14,23,197,2,87,95,23,195,1,23,193,1,
28,249,22,168,14,2,60,248,22,186,13,23,197,1,249,80,159,45,53,38,23, 28,249,22,169,14,2,60,248,22,187,13,23,197,1,249,80,159,45,53,38,23,
198,1,2,30,195,248,22,81,6,26,26,32,40,97,32,112,97,116,104,32,109, 198,1,2,30,195,248,22,81,6,26,26,32,40,97,32,112,97,116,104,32,109,
117,115,116,32,98,101,32,97,98,115,111,108,117,116,101,41,28,249,22,184,8, 117,115,116,32,98,101,32,97,98,115,111,108,117,116,101,41,28,249,22,185,8,
248,22,72,23,200,2,2,27,27,250,22,150,2,80,159,43,44,38,249,22,71, 248,22,72,23,200,2,2,27,27,250,22,150,2,80,159,43,44,38,249,22,71,
23,203,2,247,22,159,14,11,28,23,193,2,192,87,94,23,193,1,91,159,39, 23,203,2,247,22,160,14,11,28,23,193,2,192,87,94,23,193,1,91,159,39,
11,90,161,38,36,11,27,248,22,96,23,203,2,248,2,61,248,2,63,23,195, 11,90,161,38,36,11,27,248,22,96,23,203,2,248,2,61,248,2,63,23,195,
1,90,161,37,38,11,28,248,22,79,248,22,98,23,203,2,28,248,22,79,23, 1,90,161,37,38,11,28,248,22,79,248,22,98,23,203,2,28,248,22,79,23,
194,2,249,22,172,14,0,8,35,114,120,34,91,46,93,34,23,196,2,11,10, 194,2,249,22,173,14,0,8,35,114,120,34,91,46,93,34,23,196,2,11,10,
27,27,28,23,197,2,249,22,85,28,248,22,79,248,22,98,23,207,2,21,93, 27,27,28,23,197,2,249,22,85,28,248,22,79,248,22,98,23,207,2,21,93,
6,5,5,109,122,108,105,98,249,22,1,22,85,249,22,2,32,0,89,162,8, 6,5,5,109,122,108,105,98,249,22,1,22,85,249,22,2,32,0,89,162,8,
44,37,44,9,222,33,67,248,22,98,23,210,2,23,197,2,28,248,22,79,23, 44,37,44,9,222,33,67,248,22,98,23,210,2,23,197,2,28,248,22,79,23,
196,2,248,22,81,23,197,2,23,195,2,251,80,159,49,54,38,2,18,23,204, 196,2,248,22,81,23,197,2,23,195,2,251,80,159,49,54,38,2,18,23,204,
1,248,22,72,23,198,2,248,22,73,23,198,1,249,22,135,14,23,195,1,28, 1,248,22,72,23,198,2,248,22,73,23,198,1,249,22,136,14,23,195,1,28,
23,198,1,87,94,23,196,1,27,248,22,180,6,23,199,2,28,249,22,180,3, 23,198,1,87,94,23,196,1,27,248,22,181,6,23,199,2,28,249,22,180,3,
194,39,28,249,22,183,6,2,28,249,22,135,7,201,249,22,168,3,198,39,249, 194,39,28,249,22,184,6,2,28,249,22,136,7,201,249,22,168,3,198,39,249,
22,136,7,250,22,135,7,202,36,249,22,168,3,199,39,2,29,197,197,28,248, 22,137,7,250,22,136,7,202,36,249,22,168,3,199,39,2,29,197,197,28,248,
22,79,23,197,1,87,94,23,197,1,6,8,8,109,97,105,110,46,114,107,116, 22,79,23,197,1,87,94,23,197,1,6,8,8,109,97,105,110,46,114,107,116,
28,249,22,172,14,0,8,35,114,120,34,91,46,93,34,23,199,2,27,248,22, 28,249,22,173,14,0,8,35,114,120,34,91,46,93,34,23,199,2,27,248,22,
180,6,23,199,2,28,249,22,180,3,194,39,28,249,22,183,6,2,28,249,22, 181,6,23,199,2,28,249,22,180,3,194,39,28,249,22,184,6,2,28,249,22,
135,7,201,249,22,168,3,198,39,249,22,136,7,250,22,135,7,202,36,249,22, 136,7,201,249,22,168,3,198,39,249,22,137,7,250,22,136,7,202,36,249,22,
168,3,199,39,2,29,197,197,249,22,136,7,23,199,1,6,4,4,46,114,107, 168,3,199,39,2,29,197,197,249,22,137,7,23,199,1,6,4,4,46,114,107,
116,28,249,22,184,8,248,22,72,23,200,2,64,102,105,108,101,27,248,22,144, 116,28,249,22,185,8,248,22,72,23,200,2,64,102,105,108,101,27,248,22,145,
14,249,22,142,14,248,22,146,14,248,22,96,23,203,2,27,28,23,203,2,28, 14,249,22,143,14,248,22,147,14,248,22,96,23,203,2,27,28,23,203,2,28,
249,22,184,8,23,205,2,80,158,46,47,80,158,44,48,27,248,22,188,4,23, 249,22,185,8,23,205,2,80,158,46,47,80,158,44,48,27,248,22,188,4,23,
205,2,28,248,22,181,13,23,194,2,91,159,39,11,90,161,39,36,11,248,22, 205,2,28,248,22,182,13,23,194,2,91,159,39,11,90,161,39,36,11,248,22,
138,14,23,197,1,87,95,83,160,38,11,80,158,48,47,23,207,2,83,160,38, 139,14,23,197,1,87,95,83,160,38,11,80,158,48,47,23,207,2,83,160,38,
11,80,158,48,48,192,192,11,11,28,23,193,2,192,87,94,23,193,1,27,247, 11,80,158,48,48,192,192,11,11,28,23,193,2,192,87,94,23,193,1,27,247,
22,145,5,28,23,193,2,192,87,94,23,193,1,247,22,158,14,91,159,39,11, 22,146,5,28,23,193,2,192,87,94,23,193,1,247,22,159,14,91,159,39,11,
90,161,39,36,11,248,22,138,14,23,197,2,87,95,23,195,1,23,193,1,28, 90,161,39,36,11,248,22,139,14,23,197,2,87,95,23,195,1,23,193,1,28,
249,22,168,14,2,60,248,22,186,13,23,197,1,249,80,159,45,53,38,23,198, 249,22,169,14,2,60,248,22,187,13,23,197,1,249,80,159,45,53,38,23,198,
1,2,30,195,12,87,94,28,28,248,22,181,13,23,194,2,10,248,22,136,8, 1,2,30,195,12,87,94,28,28,248,22,182,13,23,194,2,10,248,22,137,8,
23,194,2,87,94,23,199,1,12,28,23,199,2,250,22,153,9,67,114,101,113, 23,194,2,87,94,23,199,1,12,28,23,199,2,250,22,154,9,67,114,101,113,
117,105,114,101,249,22,161,7,6,17,17,98,97,100,32,109,111,100,117,108,101, 117,105,114,101,249,22,162,7,6,17,17,98,97,100,32,109,111,100,117,108,101,
32,112,97,116,104,126,97,28,23,198,2,248,22,72,23,199,2,6,0,0,23, 32,112,97,116,104,126,97,28,23,198,2,248,22,72,23,199,2,6,0,0,23,
202,1,87,94,23,199,1,250,22,154,9,2,18,249,22,161,7,6,13,13,109, 202,1,87,94,23,199,1,250,22,155,9,2,18,249,22,162,7,6,13,13,109,
111,100,117,108,101,32,112,97,116,104,126,97,28,23,198,2,248,22,72,23,199, 111,100,117,108,101,32,112,97,116,104,126,97,28,23,198,2,248,22,72,23,199,
2,6,0,0,23,200,2,27,28,248,22,136,8,23,195,2,249,22,141,8,23, 2,6,0,0,23,200,2,27,28,248,22,137,8,23,195,2,249,22,142,8,23,
196,2,36,249,22,144,14,248,22,145,14,23,197,2,11,27,28,248,22,136,8, 196,2,36,249,22,145,14,248,22,146,14,23,197,2,11,27,28,248,22,137,8,
23,196,2,249,22,141,8,23,197,2,37,248,80,159,42,55,38,23,195,2,91, 23,196,2,249,22,142,8,23,197,2,37,248,80,159,42,55,38,23,195,2,91,
159,39,11,90,161,39,36,11,28,248,22,136,8,23,199,2,250,22,7,2,31, 159,39,11,90,161,39,36,11,28,248,22,137,8,23,199,2,250,22,7,2,31,
249,22,141,8,23,203,2,38,2,31,248,22,138,14,23,198,2,87,95,23,195, 249,22,142,8,23,203,2,38,2,31,248,22,139,14,23,198,2,87,95,23,195,
1,23,193,1,27,28,248,22,136,8,23,200,2,249,22,141,8,23,201,2,39, 1,23,193,1,27,28,248,22,137,8,23,200,2,249,22,142,8,23,201,2,39,
249,80,159,47,53,38,23,197,2,5,0,27,28,248,22,136,8,23,201,2,249, 249,80,159,47,53,38,23,197,2,5,0,27,28,248,22,137,8,23,201,2,249,
22,141,8,23,202,2,40,248,22,187,4,23,200,2,27,27,250,22,150,2,80, 22,142,8,23,202,2,40,248,22,187,4,23,200,2,27,27,250,22,150,2,80,
159,51,43,38,248,22,129,15,247,22,161,12,11,28,23,193,2,192,87,94,23, 159,51,43,38,248,22,130,15,247,22,162,12,11,28,23,193,2,192,87,94,23,
193,1,27,247,22,130,2,87,94,250,22,148,2,80,159,52,43,38,248,22,129, 193,1,27,247,22,130,2,87,94,250,22,148,2,80,159,52,43,38,248,22,130,
15,247,22,161,12,195,192,87,95,28,23,208,1,27,250,22,150,2,23,197,2, 15,247,22,162,12,195,192,87,95,28,23,208,1,27,250,22,150,2,23,197,2,
197,11,28,23,193,1,12,87,95,27,27,28,248,22,17,80,159,51,46,38,80, 197,11,28,23,193,1,12,87,95,27,27,28,248,22,17,80,159,51,46,38,80,
159,50,46,38,247,22,19,250,22,25,248,22,23,23,197,2,80,159,53,45,38, 159,50,46,38,247,22,19,250,22,25,248,22,23,23,197,2,80,159,53,45,38,
23,196,1,27,248,22,129,15,247,22,161,12,249,22,3,83,158,40,20,100,94, 23,196,1,27,248,22,130,15,247,22,162,12,249,22,3,83,158,40,20,100,94,
89,162,8,44,37,55,9,226,12,11,2,3,33,68,23,195,1,23,196,1,248, 89,162,8,44,37,55,9,226,12,11,2,3,33,68,23,195,1,23,196,1,248,
28,248,22,17,80,159,50,46,38,32,0,89,162,44,37,42,9,222,33,69,80, 28,248,22,17,80,159,50,46,38,32,0,89,162,44,37,42,9,222,33,69,80,
159,49,59,37,89,162,44,36,51,9,227,13,9,8,4,3,33,70,250,22,148, 159,49,59,37,89,162,44,36,51,9,227,13,9,8,4,3,33,70,250,22,148,
2,23,197,1,197,10,12,28,28,248,22,136,8,23,202,1,11,28,248,22,177, 2,23,197,1,197,10,12,28,28,248,22,137,8,23,202,1,11,28,248,22,178,
6,23,206,2,10,28,248,22,56,23,206,2,10,28,248,22,69,23,206,2,249, 6,23,206,2,10,28,248,22,56,23,206,2,10,28,248,22,69,23,206,2,249,
22,184,8,248,22,72,23,208,2,2,27,11,250,22,148,2,80,159,50,44,38, 22,185,8,248,22,72,23,208,2,2,27,11,250,22,148,2,80,159,50,44,38,
28,248,22,177,6,23,209,2,249,22,71,23,210,1,27,28,23,212,2,28,249, 28,248,22,178,6,23,209,2,249,22,71,23,210,1,27,28,23,212,2,28,249,
22,184,8,23,214,2,80,158,55,47,87,94,23,212,1,80,158,53,48,27,248, 22,185,8,23,214,2,80,158,55,47,87,94,23,212,1,80,158,53,48,27,248,
22,188,4,23,214,2,28,248,22,181,13,23,194,2,91,159,39,11,90,161,39, 22,188,4,23,214,2,28,248,22,182,13,23,194,2,91,159,39,11,90,161,39,
36,11,248,22,138,14,23,197,1,87,95,83,160,38,11,80,158,57,47,23,23, 36,11,248,22,139,14,23,197,1,87,95,83,160,38,11,80,158,57,47,23,23,
83,160,38,11,80,158,57,48,192,192,11,11,28,23,193,2,192,87,94,23,193, 83,160,38,11,80,158,57,48,192,192,11,11,28,23,193,2,192,87,94,23,193,
1,27,247,22,145,5,28,23,193,2,192,87,94,23,193,1,247,22,158,14,249, 1,27,247,22,146,5,28,23,193,2,192,87,94,23,193,1,247,22,159,14,249,
22,71,23,210,1,247,22,159,14,252,22,138,8,23,208,1,23,207,1,23,205, 22,71,23,210,1,247,22,160,14,252,22,139,8,23,208,1,23,207,1,23,205,
1,23,203,1,201,12,193,87,96,83,160,38,11,80,158,36,50,248,80,159,37, 1,23,203,1,201,12,193,87,96,83,160,38,11,80,158,36,50,248,80,159,37,
58,38,249,22,27,11,80,159,39,52,38,248,22,166,4,80,159,37,51,38,248, 58,38,249,22,27,11,80,159,39,52,38,248,22,166,4,80,159,37,51,38,248,
22,144,5,80,159,37,37,37,248,22,152,13,80,159,37,42,37,83,160,38,11, 22,145,5,80,159,37,37,37,248,22,153,13,80,159,37,42,37,83,160,38,11,
80,158,36,50,248,80,159,37,58,38,249,22,27,11,80,159,39,52,38,159,36, 80,158,36,50,248,80,159,37,58,38,249,22,27,11,80,159,39,52,38,159,36,
20,105,159,36,16,1,11,16,0,83,158,42,20,103,145,2,1,2,1,29,11, 20,105,159,36,16,1,11,16,0,83,158,42,20,103,145,2,1,2,1,29,11,
11,11,11,11,10,38,80,158,36,36,20,105,159,37,16,23,2,2,2,3,30, 11,11,11,11,10,38,80,158,36,36,20,105,159,37,16,23,2,2,2,3,30,
@ -734,7 +734,7 @@
16,2,2,20,2,21,38,38,37,11,11,11,16,0,16,0,16,0,36,36,11, 16,2,2,20,2,21,38,38,37,11,11,11,16,0,16,0,16,0,36,36,11,
11,11,11,16,0,16,0,16,0,36,36,16,0,16,15,83,158,36,16,2,89, 11,11,11,16,0,16,0,16,0,36,36,16,0,16,15,83,158,36,16,2,89,
162,44,37,45,9,223,0,33,32,80,159,36,59,37,83,158,36,16,2,248,22, 162,44,37,45,9,223,0,33,32,80,159,36,59,37,83,158,36,16,2,248,22,
133,8,69,115,111,45,115,117,102,102,105,120,80,159,36,36,37,83,158,36,16, 134,8,69,115,111,45,115,117,102,102,105,120,80,159,36,36,37,83,158,36,16,
2,89,162,44,38,8,37,2,3,223,0,33,41,80,159,36,37,37,83,158,36, 2,89,162,44,38,8,37,2,3,223,0,33,41,80,159,36,37,37,83,158,36,
16,2,32,0,89,162,8,44,37,42,2,9,222,192,80,159,36,42,37,83,158, 16,2,32,0,89,162,8,44,37,42,2,9,222,192,80,159,36,42,37,83,158,
36,16,2,247,22,133,2,80,159,36,43,37,83,158,36,16,2,247,22,132,2, 36,16,2,247,22,133,2,80,159,36,43,37,83,158,36,16,2,247,22,132,2,

View File

@ -357,9 +357,11 @@ Scheme_Env *scheme_engine_instance_init() {
#endif #endif
make_kernel_env(); make_kernel_env();
#if defined(MZ_PRECISE_GC) && defined(MZ_USE_PLACES) #if defined(MZ_PLACES_WAITPID)
scheme_places_block_child_signal(); scheme_places_start_child_signal_handler();
#endif
#if defined(MZ_PRECISE_GC) && defined(MZ_USE_PLACES)
GC_switch_out_master_gc(); GC_switch_out_master_gc();
scheme_spawn_master_place(); scheme_spawn_master_place();

View File

@ -160,12 +160,22 @@ void *mzrt_thread_stub(void *data){
mzrt_thread_stub_data *stub_data = (mzrt_thread_stub_data*) data; mzrt_thread_stub_data *stub_data = (mzrt_thread_stub_data*) data;
mz_proc_thread_start start_proc = stub_data->start_proc; mz_proc_thread_start start_proc = stub_data->start_proc;
void *start_proc_data = stub_data->data; void *start_proc_data = stub_data->data;
void* res;
scheme_init_os_thread(); scheme_init_os_thread();
proc_thread_self = stub_data->thread;
proc_thread_self = stub_data->thread;
free(data); free(data);
return start_proc(start_proc_data); res = start_proc(start_proc_data);
if (proc_thread_self->refcount)
free(proc_thread_self);
scheme_done_os_thread();
return res;
} }
#ifdef WIN32 #ifdef WIN32
@ -196,11 +206,14 @@ mz_proc_thread* mzrt_proc_first_thread_init() {
thread->mbox = pt_mbox_create(); thread->mbox = pt_mbox_create();
thread->threadid = mz_proc_thread_self(); thread->threadid = mz_proc_thread_self();
proc_thread_self = thread; proc_thread_self = thread;
thread->refcount = 1;
return thread; return thread;
} }
mz_proc_thread* mz_proc_thread_create_w_stacksize(mz_proc_thread_start start_proc, void* data, long stacksize) { mz_proc_thread* mz_proc_thread_create_w_stacksize(mz_proc_thread_start start_proc, void* data, long stacksize) {
mz_proc_thread *thread = (mz_proc_thread*)malloc(sizeof(mz_proc_thread)); mz_proc_thread *thread = (mz_proc_thread*)malloc(sizeof(mz_proc_thread));
mzrt_thread_stub_data *stub_data;
# ifndef WIN32 # ifndef WIN32
pthread_attr_t *attr; pthread_attr_t *attr;
pthread_attr_t attr_storage; pthread_attr_t attr_storage;
@ -213,7 +226,10 @@ mz_proc_thread* mz_proc_thread_create_w_stacksize(mz_proc_thread_start start_pro
attr = NULL; attr = NULL;
# endif # endif
mzrt_thread_stub_data *stub_data = (mzrt_thread_stub_data*)malloc(sizeof(mzrt_thread_stub_data)); thread->refcount = 2;
stub_data = (mzrt_thread_stub_data*)malloc(sizeof(mzrt_thread_stub_data));
thread->mbox = pt_mbox_create(); thread->mbox = pt_mbox_create();
stub_data->start_proc = start_proc; stub_data->start_proc = start_proc;
stub_data->data = data; stub_data->data = data;
@ -221,7 +237,11 @@ mz_proc_thread* mz_proc_thread_create_w_stacksize(mz_proc_thread_start start_pro
# ifdef WIN32 # ifdef WIN32
thread->threadid = CreateThread(NULL, stacksize, mzrt_win_thread_stub, stub_data, 0, NULL); thread->threadid = CreateThread(NULL, stacksize, mzrt_win_thread_stub, stub_data, 0, NULL);
# else # else
# ifdef MZ_PRECISE_GC
pthread_create(&thread->threadid, attr, mzrt_thread_stub, stub_data); pthread_create(&thread->threadid, attr, mzrt_thread_stub, stub_data);
# else
GC_pthread_create(&thread->threadid, attr, mzrt_thread_stub, stub_data);
# endif
# endif # endif
return thread; return thread;
@ -240,34 +260,43 @@ mz_proc_thread* mz_proc_thread_create(mz_proc_thread_start start_proc, void* dat
} }
void * mz_proc_thread_wait(mz_proc_thread *thread) { void * mz_proc_thread_wait(mz_proc_thread *thread) {
#ifdef WIN32
DWORD rc;
WaitForSingleObject(thread->threadid,INFINITE);
GetExitCodeThread(thread->threadid, &rc);
return (void *) rc;
#else
void *rc; void *rc;
#ifdef WIN32
DWORD rcw;
WaitForSingleObject(thread->threadid,INFINITE);
GetExitCodeThread(thread->threadid, &rcw);
rc = (void *)rcw;
CloseHandle(thread->threadid);
#else
# ifndef MZ_PRECISE_GC # ifndef MZ_PRECISE_GC
GC_pthread_join(thread->threadid, &rc); GC_pthread_join(thread->threadid, &rc);
# else # else
pthread_join(thread->threadid, &rc); pthread_join(thread->threadid, &rc);
# endif # endif
return rc;
#endif #endif
if (!--thread->refcount)
free(thread);
return rc;
} }
int mz_proc_thread_detach(mz_proc_thread *thread) { int mz_proc_thread_detach(mz_proc_thread *thread) {
#ifdef WIN32
return CloseHandle(thread->threadid);
#else
int rc; int rc;
#ifdef WIN32
rc = CloseHandle(thread->threadid);
#else
# ifndef MZ_PRECISE_GC # ifndef MZ_PRECISE_GC
rc = GC_pthread_detach(thread->threadid); rc = GC_pthread_detach(thread->threadid);
# else # else
rc = pthread_detach(thread->threadid); rc = pthread_detach(thread->threadid);
# endif # endif
return rc;
#endif #endif
if (!--thread->refcount)
free(thread);
return rc;
} }
void mz_proc_thread_exit(void *rc) { void mz_proc_thread_exit(void *rc) {

View File

@ -34,6 +34,7 @@ typedef pthread_t mzrt_thread_id;
typedef struct mz_proc_thread { typedef struct mz_proc_thread {
mzrt_thread_id threadid; mzrt_thread_id threadid;
int refcount;
struct pt_mbox *mbox; struct pt_mbox *mbox;
} mz_proc_thread; } mz_proc_thread;

View File

@ -6,6 +6,9 @@
#ifdef MZ_USE_PLACES #ifdef MZ_USE_PLACES
#include "mzrt.h" #include "mzrt.h"
#ifdef UNIX_PROCESSES
# include <unistd.h>
#endif
READ_ONLY static Scheme_Object *scheme_def_place_exit_proc; READ_ONLY static Scheme_Object *scheme_def_place_exit_proc;
@ -202,147 +205,393 @@ Scheme_Object *scheme_place(int argc, Scheme_Object *args[]) {
return (Scheme_Object*) place; return (Scheme_Object*) place;
} }
# ifdef MZ_PRECISE_GC # if defined(MZ_PLACES_WAITPID)
/*============= SIGNAL HANDLER =============*/ /*============= SIGCHLD SIGNAL HANDLING =============*/
/* If SIGCHLD is unblocked, it gets delivered to a random thread
--- not necessarily on in the right place for the subprocess.
To avoid that problem, we centralize SIGCHLD handling here, and
then dispatch back out to specific places as they request
information. */
#include <signal.h> #include <signal.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <errno.h> #include <errno.h>
static void error_info() {
char *erstr;
erstr = strerror(errno);
printf("errno %i %s\n", errno, erstr);
}
typedef struct Child_Status { typedef struct Child_Status {
int pid; int pid;
int status; int status;
char done;
char unneeded; /* not in a group; result not needed */
char is_group;
void *signal_fd; void *signal_fd;
struct Child_Status *next; struct Child_Status *next;
struct Child_Status *next_group; /* see child_group_statuses */
} Child_Status; } Child_Status;
SHARED_OK static Child_Status *child_statuses = NULL; SHARED_OK static Child_Status *child_statuses = NULL;
SHARED_OK static mzrt_mutex* child_status_lock = NULL; SHARED_OK static mzrt_mutex* child_status_lock = NULL;
SHARED_OK static mzrt_mutex* child_wait_lock = NULL; /* ordered before status lock */
/* When a process for a process group becomes unreachable
before a waitpid() on the process, then we need to keep
waiting on it to let the OS gc the process. Otherwise,
we wait only on processes in the same group as Racket.
This list is protect by the wait lock. */
SHARED_OK static Child_Status *child_group_statuses = NULL;
static void add_group_signal_fd(void *signal_fd);
static void remove_group_signal_fd(void *signal_fd);
static void do_group_signal_fds();
static void add_child_status(int pid, int status) { static void add_child_status(int pid, int status) {
Child_Status *st; Child_Status *st;
st = malloc(sizeof(Child_Status));
st->pid = pid;
st->signal_fd = NULL;
st->status = status;
/* Search for existing record, which will have a signal_fd: */
mzrt_mutex_lock(child_status_lock); mzrt_mutex_lock(child_status_lock);
st->next = child_statuses; for (st = child_statuses; st; st = st->next) {
child_statuses = st; if (st->pid == pid)
break;
}
if (!st) {
/* must have terminated before it was registered
(and since we detected it, it must not be a group) */
st = malloc(sizeof(Child_Status));
st->pid = pid;
st->signal_fd = NULL;
st->next = child_statuses;
child_statuses = st;
st->next_group = NULL;
st->unneeded = 0;
st->is_group = 0;
}
st->status = status;
st->done = 1;
if (st->signal_fd && st->is_group)
remove_group_signal_fd(st->signal_fd);
mzrt_mutex_unlock(child_status_lock); mzrt_mutex_unlock(child_status_lock);
if (st->signal_fd)
scheme_signal_received_at(st->signal_fd);
if (st->unneeded)
(void)scheme_get_child_status(st->pid, 0, NULL);
} }
static int raw_get_child_status(int pid, int *status) { static int raw_get_child_status(int pid, int *status, int done_only, int do_remove, int do_free) {
Child_Status *st; Child_Status *st;
Child_Status *prev; Child_Status *prev;
int found = 0; int found = 0;
for (st = child_statuses, prev = NULL; st; prev = st, st = st->next) { for (st = child_statuses, prev = NULL; st; prev = st, st = st->next) {
if (st->pid == pid) { if (st->pid == pid) {
*status = st->status; if (!done_only || st->done) {
found = 1; if (status)
if (prev) { *status = st->status;
prev->next = st->next; found = 1;
if (do_remove) {
if (prev)
prev->next = st->next;
else
child_statuses = st->next;
}
if (do_free)
free(st);
} }
else {
child_statuses = st->next;
}
free(st);
break; break;
} }
} }
return found; return found;
} }
int scheme_get_child_status(int pid, int *status) { int scheme_get_child_status(int pid, int is_group, int *status) {
int found = 0; int found = 0;
if (is_group) {
/* need to specifically try the pid, since we don't
wait on other process groups in the background thread */
pid_t pid2;
int status;
do {
pid2 = waitpid((pid_t)pid, &status, WNOHANG);
} while ((pid2 == -1) && (errno == EINTR));
if (pid2 > 0)
add_child_status(pid, status);
}
mzrt_mutex_lock(child_status_lock); mzrt_mutex_lock(child_status_lock);
found = raw_get_child_status(pid, status); found = raw_get_child_status(pid, status, 1, 1, 1);
mzrt_mutex_unlock(child_status_lock); mzrt_mutex_unlock(child_status_lock);
/* printf("scheme_get_child_status found %i pid %i status %i\n", found, pid, *status); */ /* printf("scheme_get_child_status found %i pid %i status %i\n", found, pid, *status); */
return found; return found;
} }
int scheme_places_register_child(int pid, void *signal_fd, int *status) { int scheme_places_register_child(int pid, int is_group, void *signal_fd, int *status)
{
int found = 0; int found = 0;
mzrt_mutex_lock(child_status_lock); mzrt_mutex_lock(child_status_lock);
found = raw_get_child_status(pid, status);
/* The child may have terminated already: */
found = raw_get_child_status(pid, status, 0, 0, 0);
if (!found) { if (!found) {
/* Create a record for the child: */
Child_Status *st; Child_Status *st;
st = malloc(sizeof(Child_Status)); st = malloc(sizeof(Child_Status));
st->pid = pid; st->pid = pid;
st->signal_fd = signal_fd; st->signal_fd = signal_fd;
st->status = 0; st->status = 0;
st->unneeded = 0;
st->done = 0;
st->is_group = is_group;
st->next = child_statuses; st->next = child_statuses;
child_statuses = st; child_statuses = st;
st->next_group = NULL;
if (is_group)
add_group_signal_fd(signal_fd);
} }
mzrt_mutex_unlock(child_status_lock); mzrt_mutex_unlock(child_status_lock);
return found; return found;
} }
static void *mz_proc_thread_signal_worker(void *data) { static void *mz_proc_thread_signal_worker(void *data) {
int status; int status;
int pid; int pid, check_pid, is_group;
sigset_t set; sigset_t set;
//GC_CAN_IGNORE siginfo_t info; Child_Status *group_status, *prev_group;
{
sigemptyset(&set);
sigaddset(&set, SIGCHLD);
pthread_sigmask(SIG_UNBLOCK, &set, NULL);
}
while(1) { sigemptyset(&set);
sigaddset(&set, SIGCHLD);
while (1) {
int rc; int rc;
int signalid; int signalid;
do { do {
rc = sigwait(&set, &signalid); rc = sigwait(&set, &signalid);
if (rc == -1) { if (rc == -1) {
if (errno != EINTR ) { if (errno != EINTR) {
error_info(); fprintf(stderr, "unexpected error from sigwait(): %d\n", errno);
} }
} }
} while (rc == -1 && errno == EINTR); } while (rc == -1 && errno == EINTR);
pid = waitpid((pid_t)-1, &status, WNOHANG); mzrt_mutex_lock(child_status_lock);
if (pid == -1) { do_group_signal_fds();
char *erstr; mzrt_mutex_unlock(child_status_lock);
erstr = strerror(errno);
/* printf("errno %i %s\n", errno, erstr); */ mzrt_mutex_lock(child_wait_lock);
}
else { group_status = child_group_statuses;
/* printf("SIGCHILD pid %i with status %i %i\n", pid, status, WEXITSTATUS(status)); */ prev_group = NULL;
add_child_status(pid, status);
} do {
}; if (group_status) {
check_pid = group_status->pid;
is_group = 1;
} else {
check_pid = 0; /* => processes in the same group as Racket */
is_group = 0;
}
pid = waitpid(check_pid, &status, WNOHANG);
if (pid == -1) {
if (errno == EINTR) {
/* try again */
pid = 1;
} else if (!is_group && (errno == ECHILD)) {
/* no more to check */
} else {
fprintf(stderr, "unexpected error from waitpid(%d[%d]): %d\n",
check_pid, is_group, errno);
if (is_group) {
prev_group = group_status;
group_status = group_status->next;
}
}
} else if (pid > 0) {
/* printf("SIGCHILD pid %i with status %i %i\n", pid, status, WEXITSTATUS(status)); */
if (is_group) {
group_status = group_status->next;
if (prev_group)
prev_group->next_group = group_status;
else
child_group_statuses = group_status;
} else
add_child_status(pid, status);
} else {
if (is_group) {
prev_group = group_status;
group_status = group_status->next;
}
}
} while ((pid > 0) || is_group);
mzrt_mutex_unlock(child_wait_lock);
}
return NULL; return NULL;
} }
void scheme_done_with_process_id(int pid, int is_group)
{
Child_Status *st;
void scheme_places_block_child_signal() { mzrt_mutex_lock(child_wait_lock); /* protects child_group_statuses */
{ mzrt_mutex_lock(child_status_lock);
sigset_t set;
sigemptyset(&set); for (st = child_statuses; st; st = st->next) {
sigaddset(&set, SIGCHLD); if (st->pid == pid) {
pthread_sigmask(SIG_BLOCK, &set, NULL); if (!st->done) {
if (is_group) {
st->next_group = child_group_statuses;
child_group_statuses = st;
if (st->signal_fd)
remove_group_signal_fd(st->signal_fd);
} else
st->unneeded = 1;
st->signal_fd = NULL;
}
break;
}
} }
{ if (st && (is_group || st->done)) {
mz_proc_thread *signal_thread; /* remove it from normal list: */
mzrt_mutex_create(&child_status_lock); raw_get_child_status(pid, NULL, 0, 1, !st->done);
signal_thread = mz_proc_thread_create(mz_proc_thread_signal_worker, NULL); }
mz_proc_thread_detach(signal_thread);
mzrt_mutex_unlock(child_status_lock);
mzrt_mutex_unlock(child_wait_lock);
}
static void got_sigchld() XFORM_SKIP_PROC
{
write(2, "SIGCHLD handler called (some thread has SIGCHLD unblocked)\n", 59);
}
void scheme_places_block_child_signal() XFORM_SKIP_PROC
{
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGCHLD);
sigprocmask(SIG_BLOCK, &set, NULL);
/* Mac OS X seems to need a handler installed for SIGCHLD to be
delivered, since the default is to drop the signal. Also, this
handler serves as a back-up alert if some thread is created that
does not block SIGCHLD. */
MZ_SIGSET(SIGCHLD, got_sigchld);
}
void scheme_places_start_child_signal_handler()
{
mz_proc_thread *signal_thread;
mzrt_mutex_create(&child_status_lock);
mzrt_mutex_create(&child_wait_lock);
signal_thread = mz_proc_thread_create(mz_proc_thread_signal_worker, NULL);
mz_proc_thread_detach(signal_thread);
}
void scheme_wait_suspend()
{
mzrt_mutex_lock(child_wait_lock);
}
void scheme_wait_resume()
{
mzrt_mutex_unlock(child_wait_lock);
}
/* ---------------------------------------------------------------------- */
/* When a place has a process-group that it may be waiting on, the we
need to wake up the place whenever any SIGCHLD is received, since
the SIGDCHLD may apply to one of those places.
The list of signal_fds is protected by the status lock. */
typedef struct Group_Signal_FD {
void *signal_fd;
int refcount;
} Group_Signal_FD;
SHARED_OK static Group_Signal_FD *signal_fds;
SHARED_OK static int signal_fd_count;
static void add_group_signal_fd(void *signal_fd)
{
int i, count = 0;
Group_Signal_FD *a;
for (i = 0; i < signal_fd_count; i++) {
if (signal_fds[i].refcount) {
count++;
if (signal_fds[i].signal_fd == signal_fd) {
signal_fds[i].refcount++;
return;
}
}
}
if (count == signal_fd_count) {
signal_fd_count = (signal_fd_count + 4) * 2;
a = (Group_Signal_FD *)malloc(sizeof(Group_Signal_FD) * signal_fd_count);
memset(a, 0, sizeof(Group_Signal_FD) * signal_fd_count);
memcpy(a, signal_fds, sizeof(Group_Signal_FD) * count);
signal_fds = a;
}
for (i = 0; i < signal_fd_count; i++) {
if (!signal_fds[i].refcount) {
signal_fds[i].signal_fd = signal_fd;
signal_fds[i].refcount = 1;
break;
}
} }
} }
static void remove_group_signal_fd(void *signal_fd)
{
int i;
for (i = 0; i < signal_fd_count; i++) {
if (signal_fds[i].refcount) {
if (signal_fds[i].signal_fd == signal_fd) {
--signal_fds[i].refcount;
return;
}
}
}
}
static void do_group_signal_fds()
{
int i;
for (i = 0; i < signal_fd_count; i++) {
if (signal_fds[i].refcount) {
scheme_signal_received_at(signal_fds[i].signal_fd);
}
}
}
#endif
# if defined(MZ_PRECISE_GC)
/*============= THREAD JOIN HANDLER =============*/ /*============= THREAD JOIN HANDLER =============*/
typedef struct { typedef struct {
mz_proc_thread *proc_thread; mz_proc_thread *proc_thread;

View File

@ -169,7 +169,7 @@ int scheme_stupid_windows_machine;
/******************** Unix Subprocesses ********************/ /******************** Unix Subprocesses ********************/
#if defined(UNIX_PROCESSES) && !(defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC)) #if defined(UNIX_PROCESSES) && !defined(MZ_PLACES_WAITPID)
/* For process & system: */ /* For process & system: */
typedef struct System_Child { typedef struct System_Child {
MZTAG_IF_REQUIRED MZTAG_IF_REQUIRED
@ -186,7 +186,8 @@ typedef struct Scheme_Subprocess {
Scheme_Object so; Scheme_Object so;
void *handle; void *handle;
int pid; int pid;
#if defined(UNIX_PROCESSES) && defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC) int is_group;
#if defined(MZ_PLACES_WAITPID)
short done; short done;
int status; int status;
#endif #endif
@ -374,6 +375,7 @@ static Scheme_Object *subprocess_p(int c, Scheme_Object *args[]);
static Scheme_Object *subprocess_wait(int c, Scheme_Object *args[]); static Scheme_Object *subprocess_wait(int c, Scheme_Object *args[]);
static Scheme_Object *sch_shell_execute(int c, Scheme_Object *args[]); static Scheme_Object *sch_shell_execute(int c, Scheme_Object *args[]);
static Scheme_Object *current_subproc_cust_mode (int, Scheme_Object *[]); static Scheme_Object *current_subproc_cust_mode (int, Scheme_Object *[]);
static Scheme_Object *subproc_group_on (int, Scheme_Object *[]);
static void register_subprocess_wait(); static void register_subprocess_wait();
typedef struct Scheme_Read_Write_Evt { typedef struct Scheme_Read_Write_Evt {
@ -494,7 +496,7 @@ scheme_init_port (Scheme_Env *env)
REGISTER_SO(scheme_null_output_port_type); REGISTER_SO(scheme_null_output_port_type);
REGISTER_SO(scheme_redirect_output_port_type); REGISTER_SO(scheme_redirect_output_port_type);
#if defined(UNIX_PROCESSES) && !(defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC)) #if defined(UNIX_PROCESSES) && !defined(MZ_PLACES_WAITPID)
REGISTER_SO(scheme_system_children); REGISTER_SO(scheme_system_children);
#endif #endif
@ -570,6 +572,7 @@ scheme_init_port (Scheme_Env *env)
scheme_add_global_constant("subprocess?", scheme_make_prim_w_arity(subprocess_p, "subprocess?", 1, 1), env); scheme_add_global_constant("subprocess?", scheme_make_prim_w_arity(subprocess_p, "subprocess?", 1, 1), env);
scheme_add_global_constant("subprocess-wait", scheme_make_prim_w_arity(subprocess_wait, "subprocess-wait", 1, 1), env); scheme_add_global_constant("subprocess-wait", scheme_make_prim_w_arity(subprocess_wait, "subprocess-wait", 1, 1), env);
GLOBAL_PARAMETER("subprocess-group-enabled", subproc_group_on, MZCONFIG_SUBPROC_GROUP_ENABLED, env);
GLOBAL_PARAMETER("current-subprocess-custodian-mode", current_subproc_cust_mode, MZCONFIG_SUBPROC_CUSTODIAN_MODE, env); GLOBAL_PARAMETER("current-subprocess-custodian-mode", current_subproc_cust_mode, MZCONFIG_SUBPROC_CUSTODIAN_MODE, env);
register_subprocess_wait(); register_subprocess_wait();
@ -6784,27 +6787,27 @@ static int MyPipe(int *ph, int near_index) {
/**************** Unix: signal stuff ******************/ /**************** Unix: signal stuff ******************/
#if defined(UNIX_PROCESSES) && !(defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC)) #if defined(UNIX_PROCESSES) && !defined(MZ_PLACES_WAITPID)
# define WAITANY(s) waitpid((pid_t)-1, s, WNOHANG)
#ifndef MZ_PRECISE_GC #ifndef MZ_PRECISE_GC
# define GC_write_barrier(x) /* empty */ # define GC_write_barrier(x) /* empty */
#endif #endif
SHARED_OK static void *unused_groups;
static int need_to_check_children; static int need_to_check_children;
void scheme_block_child_signals(int block) void scheme_block_child_signals(int block)
XFORM_SKIP_PROC XFORM_SKIP_PROC
{ {
#if !(defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC)) #if !defined(MZ_PLACES_WAITPID)
sigset_t sigs; sigset_t sigs;
sigemptyset(&sigs); sigemptyset(&sigs);
sigaddset(&sigs, SIGCHLD); sigaddset(&sigs, SIGCHLD);
#ifdef USE_ITIMER # ifdef USE_ITIMER
sigaddset(&sigs, SIGPROF); sigaddset(&sigs, SIGPROF);
#endif # endif
sigprocmask(block ? SIG_BLOCK : SIG_UNBLOCK, &sigs, NULL); sigprocmask(block ? SIG_BLOCK : SIG_UNBLOCK, &sigs, NULL);
#endif #endif
} }
@ -6824,7 +6827,7 @@ static int sigchld_installed = 0;
static void init_sigchld(void) static void init_sigchld(void)
{ {
#if !(defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC)) #if !defined(MZ_PLACES_WAITPID)
if (!sigchld_installed) { if (!sigchld_installed) {
/* Catch child-done signals */ /* Catch child-done signals */
START_XFORM_SKIP; START_XFORM_SKIP;
@ -6836,21 +6839,39 @@ static void init_sigchld(void)
#endif #endif
} }
static void check_child_done() static void check_child_done(pid_t pid)
{ {
pid_t result; pid_t result, check_pid;
int status; int status, is_group;
System_Child *sc, *prev; System_Child *sc, *prev;
void **unused = (void **)unused_groups, **unused_prev = NULL;
if (scheme_system_children) { if (scheme_system_children) {
do { do {
if (!pid && unused) {
check_pid = (pid_t)(long)unused[0];
is_group = 1;
} else {
check_pid = pid;
is_group = 0;
}
do { do {
START_XFORM_SKIP; START_XFORM_SKIP;
result = WAITANY(&status); result = waitpid(check_pid, &status, WNOHANG);
END_XFORM_SKIP; END_XFORM_SKIP;
} while ((result == -1) && (errno == EINTR)); } while ((result == -1) && (errno == EINTR));
if (result > 0) { if (result > 0) {
if (is_group) {
/* done with an inaccessible group id */
unused = (void **)unused[1];
if (unused_prev)
unused_prev[1] = unused;
else
unused_groups = unused;
}
START_XFORM_SKIP; START_XFORM_SKIP;
if (WIFEXITED(status)) if (WIFEXITED(status))
status = WEXITSTATUS(status); status = WEXITSTATUS(status);
@ -6870,8 +6891,13 @@ static void check_child_done()
scheme_system_children = sc->next; scheme_system_children = sc->next;
} }
} }
} else {
if (is_group) {
unused_prev = unused;
unused = unused[1];
}
} }
} while (result > 0); } while ((result > 0) || is_group);
} }
} }
@ -6879,7 +6905,7 @@ void scheme_check_child_done(void)
{ {
if (need_to_check_children) { if (need_to_check_children) {
need_to_check_children = 0; need_to_check_children = 0;
check_child_done(); check_child_done(0);
} }
} }
@ -7088,11 +7114,11 @@ static int subp_done(Scheme_Object *so)
sp = (Scheme_Subprocess*) so; sp = (Scheme_Subprocess*) so;
#if defined(UNIX_PROCESSES) #if defined(UNIX_PROCESSES)
# if defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC) # if defined(MZ_PLACES_WAITPID)
{ {
int status; int status;
if (!sp->done) { if (!sp->done) {
if (scheme_get_child_status(((Scheme_Subprocess *)sp)->pid, &status)) { if (scheme_get_child_status(sp->pid, sp->is_group, &status)) {
sp->done = 1; sp->done = 1;
sp->status = status; sp->status = status;
child_mref_done(sp); child_mref_done(sp);
@ -7106,8 +7132,8 @@ static int subp_done(Scheme_Object *so)
# else # else
{ {
System_Child *sc; System_Child *sc;
sc = ((System_Child *) ((Scheme_Subprocess *)sp)->handle); sc = (System_Child *)sp->handle;
check_child_done(); check_child_done(sp->is_group ? sp->pid : 0);
if (sc->done) if (sc->done)
child_mref_done(sp); child_mref_done(sp);
return sc->done; return sc->done;
@ -7151,17 +7177,21 @@ static Scheme_Object *subprocess_status(int argc, Scheme_Object **argv)
int going = 0, status = MZ_FAILURE_STATUS; int going = 0, status = MZ_FAILURE_STATUS;
#if defined(UNIX_PROCESSES) #if defined(UNIX_PROCESSES)
# if defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC) # if defined(MZ_PLACES_WAITPID)
if (sp->done) if (sp->done)
status = sp->status; status = sp->status;
else { else {
if(!scheme_get_child_status(((Scheme_Subprocess *)sp)->pid, &status)) { if (!scheme_get_child_status(sp->pid, sp->is_group, &status)) {
going = 1; going = 1;
} else {
child_mref_done(sp);
sp->done = 1;
sp->status = status;
} }
} }
# else # else
System_Child *sc = (System_Child *)sp->handle; System_Child *sc = (System_Child *)sp->handle;
check_child_done(); check_child_done(sp->is_group ? sp->pid : 0);
if (sc->done) { if (sc->done) {
child_mref_done(sp); child_mref_done(sp);
@ -7230,13 +7260,22 @@ static Scheme_Object *do_subprocess_kill(Scheme_Object *_sp, Scheme_Object *kill
Scheme_Subprocess *sp = (Scheme_Subprocess *)_sp; Scheme_Subprocess *sp = (Scheme_Subprocess *)_sp;
#if defined(UNIX_PROCESSES) #if defined(UNIX_PROCESSES)
# if defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC) # if defined(MZ_PLACES_WAITPID)
{ {
int status; int status;
if (sp->done) if (sp->done)
return scheme_void; return scheme_void;
if (scheme_get_child_status(sp->pid, &status)) {
scheme_wait_suspend();
/* Don't pass sp->is_group, because we don't want to wait
on a group if we haven't already: */
if (scheme_get_child_status(sp->pid, 0, &status)) {
sp->status = status;
sp->done = 1;
child_mref_done(sp); child_mref_done(sp);
scheme_wait_resume();
return scheme_void; return scheme_void;
} }
} }
@ -7244,32 +7283,52 @@ static Scheme_Object *do_subprocess_kill(Scheme_Object *_sp, Scheme_Object *kill
{ {
System_Child *sc = (System_Child *)sp->handle; System_Child *sc = (System_Child *)sp->handle;
check_child_done(); /* Don't pass sp->pid, because we don't want to wait
on a group if we haven't already: */
check_child_done(0);
if (sc->done) { if (sc->done) {
child_mref_done(sp); child_mref_done(sp);
return scheme_void; return scheme_void;
} }
} }
# define scheme_wait_resume() /* empty */
# endif # endif
while (1) { while (1) {
if (!kill(sp->pid, SCHEME_TRUEP(killp) ? SIGKILL : SIGINT)) if (sp->is_group) {
return scheme_void; if (!killpg(sp->pid, SCHEME_TRUEP(killp) ? SIGKILL : SIGINT)) {
scheme_wait_resume();
return scheme_void;
}
} else {
if (!kill(sp->pid, SCHEME_TRUEP(killp) ? SIGKILL : SIGINT)) {
scheme_wait_resume();
return scheme_void;
}
}
if (errno != EINTR) if (errno != EINTR)
break; break;
/* Otherwise we were interrupted. Try `kill' again. */ /* Otherwise we were interrupted. Try `kill' again. */
} }
scheme_wait_resume();
#else #else
if (SCHEME_TRUEP(killp)) { if (SCHEME_TRUEP(killp) || sp->is_group) {
DWORD w; DWORD w;
int errid; int errid;
if (!sp->handle) if (!sp->handle)
return scheme_void; return scheme_void;
if (GetExitCodeProcess((HANDLE)sp->handle, &w)) { if (SCHEME_FALSEP(killp)) {
/* must be for a group; we don't care whether the
original process is still running */
if (GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, sp->pid))
return scheme_void;
} else if (GetExitCodeProcess((HANDLE)sp->handle, &w)) {
if (w != STILL_ACTIVE) if (w != STILL_ACTIVE)
return scheme_void; return scheme_void;
if (TerminateProcess((HANDLE)sp->handle, 1)) if (TerminateProcess((HANDLE)sp->handle, 1))
@ -7333,9 +7392,8 @@ static Scheme_Object *subproc_cust_mode_p(int argc, Scheme_Object **argv)
if (SCHEME_FALSEP(argv[0])) if (SCHEME_FALSEP(argv[0]))
return argv[0]; return argv[0];
if (SCHEME_SYMBOLP(argv[0]) && !SCHEME_SYM_WEIRDP(argv[0])) { if (SCHEME_SYMBOLP(argv[0]) && !SCHEME_SYM_WEIRDP(argv[0])) {
if (!strcmp(SCHEME_SYM_VAL(argv[0]), "kill")) if (!strcmp(SCHEME_SYM_VAL(argv[0]), "kill")
return argv[0]; || !strcmp(SCHEME_SYM_VAL(argv[0]), "interrupt"))
if (!strcmp(SCHEME_SYM_VAL(argv[0]), "interrupt"))
return argv[0]; return argv[0];
} }
@ -7349,6 +7407,31 @@ static Scheme_Object *current_subproc_cust_mode (int argc, Scheme_Object *argv[]
-1, subproc_cust_mode_p, "'interrupt, 'kill, or #f", 0); -1, subproc_cust_mode_p, "'interrupt, 'kill, or #f", 0);
} }
static Scheme_Object *subproc_group_on (int argc, Scheme_Object *argv[])
{
return scheme_param_config("subprocess-group-enabled", scheme_make_integer(MZCONFIG_SUBPROC_GROUP_ENABLED),
argc, argv,
-1, NULL, NULL, 1);
}
#ifdef UNIX_PROCESSES
static void unused_process_group(void *_sp, void *ignored)
{
Scheme_Subprocess *sp = (Scheme_Subprocess *)_sp;
# if defined(MZ_PLACES_WAITPID)
if (!sp->done)
scheme_done_with_process_id(sp->pid, sp->is_group);
# else
void **unused_group;
unused_group = malloc(sizeof(void *) * 2);
unused_group[0] = (void *)sp->pid;
unused_group[1] = unused_groups;
need_to_check_children = 1;
# endif
}
#endif
/*********** Windows: command-line construction *************/ /*********** Windows: command-line construction *************/
#ifdef WINDOWS_PROCESSES #ifdef WINDOWS_PROCESSES
@ -7408,7 +7491,8 @@ static char *cmdline_protect(char *s)
} }
static long mz_spawnv(char *command, const char * const *argv, static long mz_spawnv(char *command, const char * const *argv,
int exact_cmdline, int sin, int sout, int serr, int *pid) int exact_cmdline, int sin, int sout, int serr, int *pid,
int new_process_group)
{ {
int i, l, len = 0; int i, l, len = 0;
long cr_flag; long cr_flag;
@ -7451,6 +7535,8 @@ static long mz_spawnv(char *command, const char * const *argv,
cr_flag = CREATE_NO_WINDOW; cr_flag = CREATE_NO_WINDOW;
else else
cr_flag = 0; cr_flag = 0;
if (new_process_group)
cr_flag |= CREATE_NEW_PROCESS_GROUP;
if (CreateProcessW(WIDE_PATH_COPY(command), WIDE_PATH_COPY(cmdline), if (CreateProcessW(WIDE_PATH_COPY(command), WIDE_PATH_COPY(cmdline),
NULL, NULL, 1 /*inherit*/, NULL, NULL, 1 /*inherit*/,
@ -7466,15 +7552,6 @@ static long mz_spawnv(char *command, const char * const *argv,
static void close_subprocess_handle(void *sp, void *ignored) static void close_subprocess_handle(void *sp, void *ignored)
{ {
Scheme_Subprocess *subproc = (Scheme_Subprocess *)sp; Scheme_Subprocess *subproc = (Scheme_Subprocess *)sp;
#if defined(MZ_USE_PLACES) && defined (MZ_PRECISE_GC)
{
int status;
int pid = ((Scheme_Subprocess *)sp)->pid;
scheme_get_child_status(pid, &status)
/* printf("close_subprocess_handle pid %i status %i\n", pid status); */
}
#endif
CloseHandle(subproc->handle); CloseHandle(subproc->handle);
} }
@ -7494,7 +7571,7 @@ static Scheme_Object *subprocess(int c, Scheme_Object *args[])
char **argv; char **argv;
Scheme_Object *in, *out, *err; Scheme_Object *in, *out, *err;
#if defined(UNIX_PROCESSES) #if defined(UNIX_PROCESSES)
# if !(defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC)) # if !defined(MZ_PLACES_WAITPID)
System_Child *sc; System_Child *sc;
# endif # endif
int fork_errno = 0; int fork_errno = 0;
@ -7507,6 +7584,7 @@ static Scheme_Object *subprocess(int c, Scheme_Object *args[])
Scheme_Object *a[4]; Scheme_Object *a[4];
Scheme_Subprocess *subproc; Scheme_Subprocess *subproc;
Scheme_Object *cust_mode; Scheme_Object *cust_mode;
int new_process_group;
#if defined(WINDOWS_PROCESSES) #if defined(WINDOWS_PROCESSES)
int exact_cmdline = 0; int exact_cmdline = 0;
#endif #endif
@ -7647,6 +7725,8 @@ static Scheme_Object *subprocess(int c, Scheme_Object *args[])
if (!inport || !outport || !errport) if (!inport || !outport || !errport)
scheme_custodian_check_available(NULL, name, "file-stream"); scheme_custodian_check_available(NULL, name, "file-stream");
cust_mode = scheme_get_param(scheme_current_config(), MZCONFIG_SUBPROC_GROUP_ENABLED);
new_process_group = SCHEME_TRUEP(cust_mode);
cust_mode = scheme_get_param(scheme_current_config(), MZCONFIG_SUBPROC_CUSTODIAN_MODE); cust_mode = scheme_get_param(scheme_current_config(), MZCONFIG_SUBPROC_CUSTODIAN_MODE);
/*--------------------------------------*/ /*--------------------------------------*/
@ -7706,7 +7786,8 @@ static Scheme_Object *subprocess(int c, Scheme_Object *args[])
to_subprocess[0], to_subprocess[0],
from_subprocess[1], from_subprocess[1],
err_subprocess[1], err_subprocess[1],
&pid); &pid,
new_process_group);
if (spawn_status != -1) if (spawn_status != -1)
sc = (void *)spawn_status; sc = (void *)spawn_status;
@ -7721,7 +7802,7 @@ static Scheme_Object *subprocess(int c, Scheme_Object *args[])
/*--------------------------------------*/ /*--------------------------------------*/
{ {
#if !(defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC)) #if !defined(MZ_PLACES_WAITPID)
init_sigchld(); init_sigchld();
sc = MALLOC_ONE_RT(System_Child); sc = MALLOC_ONE_RT(System_Child);
@ -7737,12 +7818,21 @@ static Scheme_Object *subprocess(int c, Scheme_Object *args[])
pid = fork(); pid = fork();
if (pid > 0) { if (pid > 0) {
#if defined(MZ_USE_PLACES) && defined (MZ_PRECISE_GC) if (new_process_group)
/* there's a race condition between this use and the exec(),
and there's a race condition between the other setpgid() in
the child processand sending signals from the parent
process; so, we set in both, and at least one will
succeed; we could perform better error checking, since
EACCES is the only expected error */
setpgid(pid, pid);
#if defined(MZ_PLACES_WAITPID)
{ {
int *signal_fd; int *signal_fd;
int status; int status;
signal_fd = scheme_get_signal_handle(); signal_fd = scheme_get_signal_handle();
scheme_places_register_child(pid, signal_fd, &status); scheme_places_register_child(pid, new_process_group, signal_fd, &status);
/* printf("SUBPROCESS %i\n", pid); */ /* printf("SUBPROCESS %i\n", pid); */
} }
@ -7780,11 +7870,14 @@ static Scheme_Object *subprocess(int c, Scheme_Object *args[])
} }
END_XFORM_SKIP; END_XFORM_SKIP;
#endif #endif
if (new_process_group)
/* see also setpgid above */
setpgid(getpid(), getpid()); /* setpgid(0, 0) would work on some platforms */
} else { } else {
fork_errno = errno; fork_errno = errno;
} }
#if !(defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC)) #if !defined(MZ_PLACES_WAITPID)
scheme_block_child_signals(0); scheme_block_child_signals(0);
#endif #endif
} }
@ -7934,26 +8027,28 @@ static Scheme_Object *subprocess(int c, Scheme_Object *args[])
subproc = MALLOC_ONE_TAGGED(Scheme_Subprocess); subproc = MALLOC_ONE_TAGGED(Scheme_Subprocess);
subproc->so.type = scheme_subprocess_type; subproc->so.type = scheme_subprocess_type;
#if !(defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC)) #if !defined(MZ_PLACES_WAITPID)
subproc->handle = (void *)sc; subproc->handle = (void *)sc;
#endif #endif
subproc->pid = pid; subproc->pid = pid;
subproc->is_group = new_process_group;
# if defined(WINDOWS_PROCESSES) # if defined(WINDOWS_PROCESSES)
scheme_add_finalizer(subproc, close_subprocess_handle, NULL); scheme_add_finalizer(subproc, close_subprocess_handle, NULL);
# else
if (new_process_group)
scheme_add_finalizer(subproc, unused_process_group, NULL);
# endif # endif
if (SCHEME_TRUEP(cust_mode)) { if (SCHEME_TRUEP(cust_mode)) {
Scheme_Custodian_Reference *mref; Scheme_Custodian_Reference *mref;
Scheme_Close_Custodian_Client *closer;
if (!strcmp(SCHEME_SYM_VAL(cust_mode), "kill")) if (!strcmp(SCHEME_SYM_VAL(cust_mode), "kill"))
mref = scheme_add_managed(NULL, closer = kill_subproc;
(Scheme_Object *)subproc,
(Scheme_Close_Custodian_Client *)kill_subproc,
NULL, 1);
else else
mref = scheme_add_managed(NULL, closer = interrupt_subproc;
(Scheme_Object *)subproc,
(Scheme_Close_Custodian_Client *)interrupt_subproc, mref = scheme_add_managed(NULL, (Scheme_Object *)subproc, closer, NULL, 1);
NULL, 1);
subproc->mref = mref; subproc->mref = mref;
} }
@ -8532,6 +8627,8 @@ static long WINAPI ITimer(void *data)
WaitForSingleObject(itimer_semaphore, INFINITE); WaitForSingleObject(itimer_semaphore, INFINITE);
} }
} }
/* scheme_done_os_thread(); */
} }
static void scheme_start_itimer_thread(long usec) static void scheme_start_itimer_thread(long usec)
@ -8582,6 +8679,7 @@ static void *green_thread_timer(void *data)
while (1) { while (1) {
if (itimer_data->die) { if (itimer_data->die) {
scheme_done_os_thread();
return NULL; return NULL;
} }
usleep(itimer_data->delay); usleep(itimer_data->delay);
@ -8599,6 +8697,7 @@ static void *green_thread_timer(void *data)
} }
pthread_mutex_unlock(&itimer_data->mutex); pthread_mutex_unlock(&itimer_data->mutex);
} }
return NULL; return NULL;
} }
@ -8934,7 +9033,7 @@ static void register_traversers(void)
GC_REG_TRAV(scheme_rt_input_fd, mark_input_fd); GC_REG_TRAV(scheme_rt_input_fd, mark_input_fd);
#endif #endif
#if defined(UNIX_PROCESSES) && !(defined(MZ_USE_PLACES) && defined (MZ_PRECISE_GC)) #if defined(UNIX_PROCESSES) && !defined(MZ_PLACES_WAITPID)
GC_REG_TRAV(scheme_rt_system_child, mark_system_child); GC_REG_TRAV(scheme_rt_system_child, mark_system_child);
#endif #endif

View File

@ -105,6 +105,12 @@ THREAD_LOCAL_DECL(static int free_list_bucket_count;)
void scheme_set_stack_base(void *base, int no_auto_statics) XFORM_SKIP_PROC void scheme_set_stack_base(void *base, int no_auto_statics) XFORM_SKIP_PROC
{ {
#if defined(MZ_PLACES_WAITPID)
/* Early, to maximize the chance that no threads have been
created that might later receive SIGCHLD */
scheme_places_block_child_signal();
#endif
#ifdef MZ_PRECISE_GC #ifdef MZ_PRECISE_GC
GC_init_type_tags(_scheme_last_type_, GC_init_type_tags(_scheme_last_type_,
scheme_pair_type, scheme_mutable_pair_type, scheme_weak_box_type, scheme_pair_type, scheme_mutable_pair_type, scheme_weak_box_type,
@ -324,6 +330,7 @@ void scheme_set_report_out_of_memory(Scheme_Report_Out_Of_Memory_Proc p)
#include <mach/mach.h> #include <mach/mach.h>
# ifdef MZ_PRECISE_GC # ifdef MZ_PRECISE_GC
extern void GC_attach_current_thread_exceptions_to_handler(); extern void GC_attach_current_thread_exceptions_to_handler();
extern void GC_detach_current_thread_exceptions_from_handler();
# endif # endif
#endif #endif
@ -372,6 +379,16 @@ void scheme_init_os_thread() XFORM_SKIP_PROC
scheme_init_os_thread_like(NULL); scheme_init_os_thread_like(NULL);
} }
void scheme_done_os_thread() XFORM_SKIP_PROC
{
free(scheme_get_thread_local_variables());
#ifdef OS_X
# ifdef MZ_PRECISE_GC
GC_detach_current_thread_exceptions_from_handler();
# endif
#endif
}
/************************************************************************/ /************************************************************************/
/* memory utils */ /* memory utils */
/************************************************************************/ /************************************************************************/

View File

@ -13,7 +13,7 @@
#define USE_COMPILED_STARTUP 1 #define USE_COMPILED_STARTUP 1
#define EXPECTED_PRIM_COUNT 999 #define EXPECTED_PRIM_COUNT 1000
#define EXPECTED_UNSAFE_COUNT 69 #define EXPECTED_UNSAFE_COUNT 69
#define EXPECTED_FLFXNUM_COUNT 58 #define EXPECTED_FLFXNUM_COUNT 58

View File

@ -313,6 +313,7 @@ void scheme_do_add_global_symbol(Scheme_Env *env, Scheme_Object *sym,
void *scheme_get_os_thread_like(); void *scheme_get_os_thread_like();
void scheme_init_os_thread_like(void *); void scheme_init_os_thread_like(void *);
void scheme_done_os_thread();
/*========================================================================*/ /*========================================================================*/
/* constants */ /* constants */
@ -3449,11 +3450,18 @@ typedef struct Scheme_Symbol_Parts {
} Scheme_Symbol_Parts; } Scheme_Symbol_Parts;
void scheme_spawn_master_place(); void scheme_spawn_master_place();
void scheme_places_block_child_signal();
int scheme_get_child_status(int pid, int *status);
int scheme_places_register_child(int pid, void *signal_fd, int *status);
# endif # endif
Scheme_Object *scheme_places_deep_copy(Scheme_Object *so); Scheme_Object *scheme_places_deep_copy(Scheme_Object *so);
# ifdef UNIX_PROCESSES
# define MZ_PLACES_WAITPID
void scheme_places_block_child_signal();
void scheme_places_start_child_signal_handler();
int scheme_get_child_status(int pid, int is_group, int *status);
int scheme_places_register_child(int pid, int is_group, void *signal_fd, int *status);
void scheme_wait_suspend();
void scheme_wait_resume();
void scheme_done_with_process_id(int pid, int is_group);
# endif
#endif #endif
typedef struct Scheme_Place_Bi_Channel { typedef struct Scheme_Place_Bi_Channel {

View File

@ -13,12 +13,12 @@
consistently.) consistently.)
*/ */
#define MZSCHEME_VERSION "5.0.0.6" #define MZSCHEME_VERSION "5.0.0.7"
#define MZSCHEME_VERSION_X 5 #define MZSCHEME_VERSION_X 5
#define MZSCHEME_VERSION_Y 0 #define MZSCHEME_VERSION_Y 0
#define MZSCHEME_VERSION_Z 0 #define MZSCHEME_VERSION_Z 0
#define MZSCHEME_VERSION_W 6 #define MZSCHEME_VERSION_W 7
#define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y) #define MZSCHEME_VERSION_MAJOR ((MZSCHEME_VERSION_X * 100) + MZSCHEME_VERSION_Y)
#define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W) #define MZSCHEME_VERSION_MINOR ((MZSCHEME_VERSION_Z * 1000) + MZSCHEME_VERSION_W)

View File

@ -4117,7 +4117,7 @@ void scheme_thread_block(float sleep_time)
/* Check scheduled_kills early and often. */ /* Check scheduled_kills early and often. */
check_scheduled_kills(); check_scheduled_kills();
#if defined(UNIX_PROCESSES) && !(defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC)) #if defined(UNIX_PROCESSES) && !defined(MZ_PLACES_WAITPID)
/* Reap zombie processes: */ /* Reap zombie processes: */
scheme_check_child_done(); scheme_check_child_done();
#endif #endif
@ -7430,7 +7430,7 @@ static void get_ready_for_GC()
#ifdef WINDOWS_PROCESSES #ifdef WINDOWS_PROCESSES
scheme_suspend_remembered_threads(); scheme_suspend_remembered_threads();
#endif #endif
#if defined(UNIX_PROCESSES) && !(defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC)) #if defined(UNIX_PROCESSES) && !defined(MZ_PLACES_WAITPID)
scheme_block_child_signals(1); scheme_block_child_signals(1);
#endif #endif
@ -7461,7 +7461,7 @@ static void done_with_GC()
#ifdef WINDOWS_PROCESSES #ifdef WINDOWS_PROCESSES
scheme_resume_remembered_threads(); scheme_resume_remembered_threads();
#endif #endif
#if defined(UNIX_PROCESSES) && !(defined(MZ_USE_PLACES) && defined(MZ_PRECISE_GC)) #if defined(UNIX_PROCESSES) && !defined(MZ_PLACES_WAITPID)
scheme_block_child_signals(0); scheme_block_child_signals(0);
#endif #endif