From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Ethan Kong Newsgroups: gmane.emacs.bugs Subject: bug#73883: [PATCH] Fix 'equal' freezing on large cyclic objects Date: Sun, 20 Oct 2024 19:47:41 +0800 Message-ID: References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------YTR8mj80epC2vzTcYP0170Ey" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="26256"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Mozilla Thunderbird To: 73883@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sun Oct 20 14:04:56 2024 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1t2Ug4-0006g0-Av for geb-bug-gnu-emacs@m.gmane-mx.org; Sun, 20 Oct 2024 14:04:56 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t2Ufr-0000MF-Rw; Sun, 20 Oct 2024 08:04:43 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t2Ufm-0000L8-G9 for bug-gnu-emacs@gnu.org; Sun, 20 Oct 2024 08:04:38 -0400 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1t2Ufm-00074F-5c for bug-gnu-emacs@gnu.org; Sun, 20 Oct 2024 08:04:38 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=In-Reply-To:References:From:MIME-Version:Date:To:Subject; bh=UMl4nGk/vZLSwgmCgEYC8hk6J6WpA773hmcbw/SpBJI=; b=WYgCrzxFyp4x9De3JvGbkNt4X4YneAD/oMh4TJOnRfWZU6Q7yEH7VLcKn/Lthh9re5RY13jRgffhxrXBonDQ8SmblZI7eyCGacuNal3Qto2Yw35Xzf61VGBzYkFLKHsY2uOm2P6OZ0dtRDlpdUkwKwUatE4zgefch+lyB/ckmkDiIWUckw0Kdmlz7QQBEAKE+35JGCBJvGqfK7/NBo3sTWcnn+OuQnsath3UzCGsMMVG9R6DpPJM0/EytvMGCkGejlvNRUevxNsxqgNynFk0ZVCrqDsCNQoZOVcB9zUlb1Hn12L94vXhUibqLBuXJ8FXtQFo0yfrsItrV6J2qXfe3g==; Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1t2UgA-0003op-V7 for bug-gnu-emacs@gnu.org; Sun, 20 Oct 2024 08:05:03 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Ethan Kong Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 20 Oct 2024 12:05:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 73883 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 73883-submit@debbugs.gnu.org id=B73883.172942588614634 (code B ref 73883); Sun, 20 Oct 2024 12:05:02 +0000 Original-Received: (at 73883) by debbugs.gnu.org; 20 Oct 2024 12:04:46 +0000 Original-Received: from localhost ([127.0.0.1]:46198 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1t2Ufu-0003nx-0k for submit@debbugs.gnu.org; Sun, 20 Oct 2024 08:04:46 -0400 Original-Received: from mail-pl1-f177.google.com ([209.85.214.177]:49555) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1t2UQr-00033W-SQ for 73883@debbugs.gnu.org; Sun, 20 Oct 2024 07:49:14 -0400 Original-Received: by mail-pl1-f177.google.com with SMTP id d9443c01a7336-20cdda5cfb6so36962265ad.3 for <73883@debbugs.gnu.org>; Sun, 20 Oct 2024 04:48:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1729424868; x=1730029668; darn=debbugs.gnu.org; h=in-reply-to:content-language:references:to:from:subject:user-agent :mime-version:date:message-id:from:to:cc:subject:date:message-id :reply-to; bh=S8oIBG/1JK+HoeNF9TrNxpw4pSGaK8GclVEdrxfOZqE=; b=YsDKyymrI0e3pdc2RvAATcfF937J4dpHmqWft4uUnlTO4nTleKwX20noq7XC1gvPf/ FSkJfScI67n9KvmSmluiINlPtdICalJJRghBT30XZt/+e/zlQEEfSn0F92MdVPlPNUCd iVqiLgBAkmgtbxBGvoW0XMcMOZ6GGDNXCmRPg5LSGHdrJjw1RjOkyZd0FTqUrKuIv9LV knXZOUObSalLzItsU9uXfhL225lhWlUyhjjAGh1smNAfNRAXHWzl8uwHR/onqpESgRwI oe3gNZFE83RIrd01S2dDnSLKJKenEYoCHL9Cf0IOW3yqE+RXY8WMyJUE5VXT6t+A+Xm3 L9Og== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1729424868; x=1730029668; h=in-reply-to:content-language:references:to:from:subject:user-agent :mime-version:date:message-id:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=S8oIBG/1JK+HoeNF9TrNxpw4pSGaK8GclVEdrxfOZqE=; b=RRqEjJe0FuiWhWpgi0bJw6U4uucGyq935I1a4wQtVXdWkQqMZpwG09E/gGkpJF9xBl OcM0Et5vTC5zv0FKgonwfR5leDZ+aExZFxYm7cllXWsKW0gJScnr5SE+yyVUqhJDhXEH D5sR5WPpOYet41KD+/5nSAZoc1D0wTZ2wo0mkZQFR7nANZnUtU3AylMR2vOFzhhaubHM BO1+OyrKCq0DSUrBUFerk00jI5RawoGWEhr1L9O1Yj7W3nKRoSr5wT/TJr9JQuBhz+/H orEwQDqyDURyuMxagJ0kqiVIP6K95ROrFgwaW29pCMgMvF5oZxT/uvA20PTwcB0MrIRm CekA== X-Gm-Message-State: AOJu0Yxu5jnG5eRh0aL8rgyc3p00jpHuUBHRO48Sz0LZSAWxkLoh4xJX f1wHuOnqm36iJxCBjFb5oUcvNsmbEf4FK3BZUg6BqH5yqFCYndjKjJAEvzROsKI= X-Google-Smtp-Source: AGHT+IG/415oquC+YXS63MRGh8nQTYw1ZtiKN7U732YIEiiPgT2x/KtxafkFzhRnGLdSa0gnvJ/Kqw== X-Received: by 2002:a17:902:e5c6:b0:20b:49f5:9999 with SMTP id d9443c01a7336-20e5a921da0mr120832515ad.30.1729424867322; Sun, 20 Oct 2024 04:47:47 -0700 (PDT) Original-Received: from [127.0.0.1] ([64.176.36.230]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-20e7f106c01sm9003895ad.300.2024.10.20.04.47.45 for <73883@debbugs.gnu.org> (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sun, 20 Oct 2024 04:47:46 -0700 (PDT) Content-Language: en-US In-Reply-To: X-Mailman-Approved-At: Sun, 20 Oct 2024 08:04:44 -0400 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:293954 Archived-At: This is a multi-part message in MIME format. --------------YTR8mj80epC2vzTcYP0170Ey Content-Type: multipart/alternative; boundary="------------q6R8kxGBLQOK3Q8WP00xNOJv" --------------q6R8kxGBLQOK3Q8WP00xNOJv Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit I realize the previous title might have been misleading, so I'm replying with a more suitable one. The summary line of the patch is also updated. On 2024/10/19 18:53, Ethan Kong wrote: > Tags: patch > > Hi, > > When I use 'equal' on large, cyclic objects, emacs freezes. > > Reproduce: > >     ;; emacs -Q >     (require 'org-element) > >     ;; get two identical `org-element' trees of this file >     ;; > https://github.com/emacs-mirror/emacs/blob/master/doc/misc/modus-themes.org >     (let ((file (expand-file-name "doc/misc/modus-themes.org > " >                                   source-directory))) >       (with-current-buffer (find-file-noselect file) >         (setq org-o1 (org-element-parse-buffer)) >         (org-element-cache-reset) >         (setq org-o2 (org-element-parse-buffer)))) > >     ;; the test >     (equal org-o1 org-o2) > > This equal call freezes emacs. And the memory usage of emacs grows > quickly, until I quit. Reproduced with emacs 29.4 and the master branch. > > > The cause: > > Current code on the master branch: > >     static bool >     internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind > equal_kind, >                     int depth, Lisp_Object ht) >     { >      tail_recurse: >       if (depth > 10) >         { >           // ... >           if (NILP (ht)) >             ht = CALLN (Fmake_hash_table, QCtest, Qeq); >           // ... >         } >       // ... >             if (! internal_equal (XCAR (o1), XCAR (o2), >                                   equal_kind, depth + 1, ht)) >               return false; >             // ... >     } > > When internal_equal calls itself, it passes the hash table argument 'ht' > by value. As a result, each internal_equal(depth=11) call initializes > its own hash table, separately recording the objects it encounters in > further recursive calls. This leads to excessive 'hash_put' and > significant memory allocation. > > > Fix: > > Make internal_equal pass the hash table by pointer (see the patch). > > With this patch, the test above returns quickly: > >     (benchmark-run 100 (equal org-o1 org-o2)) > > (2.562444 20 0.30933900000000014) > > This will also improve the performance for smaller cyclic objects: > >     ;; emacs -Q >     (defun make-cyclic (n m) >       (let* ((l1 (make-list n 1)) >              (l2 (make-list m 2))) >         (setf (nth (1- m) l2) l1) >         (setf (nth (1- n) l1) l2) >         l1)) > >     (let ((a (make-cyclic 100 7)) >           (b (make-cyclic 100 7))) >       (cl-assert (equal a b)) >       (benchmark-run 10000 (equal a b))) > > Current: > (0.530081 32 0.49294199999999977) > > With the patch: > (0.036401 1 0.0173350000000001) > > And it passes all the tests in 'make fns-tests'. > > > P.S. Could I get the copyright assignment paperwork please? > > Best, > Ethan Kong > > > In GNU Emacs 29.4 (build 2, x86_64-w64-mingw32) of 2024-07-05 built on >  AVALON > Windowing system distributor 'Microsoft Corp.', version 10.0.22631 > System Description: Microsoft Windows 10 Pro (v10.0.2009.22631.4317) > > Configured using: >  'configure --with-modules --without-dbus --with-native-compilation=aot >  --without-compress-install --with-sqlite3 --with-tree-sitter >  CFLAGS=-O2' --------------q6R8kxGBLQOK3Q8WP00xNOJv Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit

I realize the previous title might have been misleading, so I'm replying with a
more suitable one. The summary line of the patch is also updated.

On 2024/10/19 18:53, Ethan Kong wrote:
Tags: patch

Hi,

When I use 'equal' on large, cyclic objects, emacs freezes.

Reproduce:

    ;; emacs -Q
    (require 'org-element)

    ;; get two identical `org-element' trees of this file
    ;; https://github.com/emacs-mirror/emacs/blob/master/doc/misc/modus-themes.org
    (let ((file (expand-file-name "doc/misc/modus-themes.org"
                                  source-directory)))
      (with-current-buffer (find-file-noselect file)
        (setq org-o1 (org-element-parse-buffer))
        (org-element-cache-reset)
        (setq org-o2 (org-element-parse-buffer))))

    ;; the test
    (equal org-o1 org-o2)

This equal call freezes emacs. And the memory usage of emacs grows
quickly, until I quit. Reproduced with emacs 29.4 and the master branch.


The cause:

Current code on the master branch:

    static bool
    internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind,
                    int depth, Lisp_Object ht)
    {
     tail_recurse:
      if (depth > 10)
        {
          // ...
          if (NILP (ht))
            ht = CALLN (Fmake_hash_table, QCtest, Qeq);
          // ...
        }
      // ...
            if (! internal_equal (XCAR (o1), XCAR (o2),
                                  equal_kind, depth + 1, ht))
              return false;
            // ...
    }

When internal_equal calls itself, it passes the hash table argument 'ht'
by value. As a result, each internal_equal(depth=11) call initializes
its own hash table, separately recording the objects it encounters in
further recursive calls. This leads to excessive 'hash_put' and
significant memory allocation.


Fix:

Make internal_equal pass the hash table by pointer (see the patch).

With this patch, the test above returns quickly:

    (benchmark-run 100 (equal org-o1 org-o2))

(2.562444 20 0.30933900000000014)

This will also improve the performance for smaller cyclic objects:

    ;; emacs -Q
    (defun make-cyclic (n m)
      (let* ((l1 (make-list n 1))
             (l2 (make-list m 2)))
        (setf (nth (1- m) l2) l1)
        (setf (nth (1- n) l1) l2)
        l1))

    (let ((a (make-cyclic 100 7))
          (b (make-cyclic 100 7)))
      (cl-assert (equal a b))
      (benchmark-run 10000 (equal a b)))

Current:
(0.530081 32 0.49294199999999977)

With the patch:
(0.036401 1 0.0173350000000001)

And it passes all the tests in 'make fns-tests'.


P.S. Could I get the copyright assignment paperwork please?

Best,
Ethan Kong


In GNU Emacs 29.4 (build 2, x86_64-w64-mingw32) of 2024-07-05 built on
 AVALON
Windowing system distributor 'Microsoft Corp.', version 10.0.22631
System Description: Microsoft Windows 10 Pro (v10.0.2009.22631.4317)

Configured using:
 'configure --with-modules --without-dbus --with-native-compilation=aot
 --without-compress-install --with-sqlite3 --with-tree-sitter
 CFLAGS=-O2'
--------------q6R8kxGBLQOK3Q8WP00xNOJv-- --------------YTR8mj80epC2vzTcYP0170Ey Content-Type: text/plain; charset=UTF-8; name="0001-Fix-equal-freezing-on-large-cyclic-objects.patch" Content-Disposition: attachment; filename="0001-Fix-equal-freezing-on-large-cyclic-objects.patch" Content-Transfer-Encoding: base64 RnJvbSA5ZmJiNzZlYWYwYjUzZGMzYzcyOWQ4NzU5NzA2M2U2MTIzNzE3NWQ3IE1vbiBTZXAg MTcgMDA6MDA6MDAgMjAwMQpGcm9tOiBFdGhhbiBLb25nIDxlay5ldGhhbi5rb25nQGdtYWls LmNvbT4KRGF0ZTogU2F0LCAxOSBPY3QgMjAyNCAxMjo0MzoyNyArMDgwMApTdWJqZWN0OiBb UEFUQ0hdIEZpeCAnZXF1YWwnIGZyZWV6aW5nIG9uIGxhcmdlIGN5Y2xpYyBvYmplY3RzCgoq IHNyYy9mbnMuYyAoaW50ZXJuYWxfZXF1YWwpOiBEZWxlZ2F0ZSB0byBpbnRlcm5hbF9lcXVh bF8xLgooaW50ZXJuYWxfZXF1YWxfMSk6IE5ldyBmdW5jdGlvbi4gUGFzcyB0aGUgaGFzaCB0 YWJsZSBhcmd1bWVudCBieQpwb2ludGVyIGluc3RlYWQgb2YgYnkgdmFsdWUuCi0tLQogc3Jj L2Zucy5jIHwgMjMgKysrKysrKysrKysrKysrLS0tLS0tLS0KIDEgZmlsZSBjaGFuZ2VkLCAx NSBpbnNlcnRpb25zKCspLCA4IGRlbGV0aW9ucygtKQoKZGlmZiAtLWdpdCBhL3NyYy9mbnMu YyBiL3NyYy9mbnMuYwppbmRleCAyZGUwNGQwNjUxOS4uZWY2OTIyYzEzN2IgMTAwNjQ0Ci0t LSBhL3NyYy9mbnMuYworKysgYi9zcmMvZm5zLmMKQEAgLTI4MjMsOCArMjgyMyw4IEBAIGVx dWFsX25vX3F1aXQgKExpc3BfT2JqZWN0IG8xLCBMaXNwX09iamVjdCBvMikKICAgIGlmIEVR VUFMX0tJTkQgPT0gRVFVQUxfTk9fUVVJVC4gICovCiAKIHN0YXRpYyBib29sCi1pbnRlcm5h bF9lcXVhbCAoTGlzcF9PYmplY3QgbzEsIExpc3BfT2JqZWN0IG8yLCBlbnVtIGVxdWFsX2tp bmQgZXF1YWxfa2luZCwKLQkJaW50IGRlcHRoLCBMaXNwX09iamVjdCBodCkKK2ludGVybmFs X2VxdWFsXzEgKExpc3BfT2JqZWN0IG8xLCBMaXNwX09iamVjdCBvMiwgZW51bSBlcXVhbF9r aW5kIGVxdWFsX2tpbmQsCisJCSAgaW50IGRlcHRoLCBMaXNwX09iamVjdCAqaHQpCiB7CiAg dGFpbF9yZWN1cnNlOgogICBpZiAoZGVwdGggPiAxMCkKQEAgLTI4MzIsMTMgKzI4MzIsMTMg QEAgaW50ZXJuYWxfZXF1YWwgKExpc3BfT2JqZWN0IG8xLCBMaXNwX09iamVjdCBvMiwgZW51 bSBlcXVhbF9raW5kIGVxdWFsX2tpbmQsCiAgICAgICBlYXNzZXJ0IChlcXVhbF9raW5kICE9 IEVRVUFMX05PX1FVSVQpOwogICAgICAgaWYgKGRlcHRoID4gMjAwKQogCWVycm9yICgiU3Rh Y2sgb3ZlcmZsb3cgaW4gZXF1YWwiKTsKLSAgICAgIGlmIChOSUxQIChodCkpCi0JaHQgPSBD QUxMTiAoRm1ha2VfaGFzaF90YWJsZSwgUUN0ZXN0LCBRZXEpOworICAgICAgaWYgKE5JTFAg KCpodCkpCisJKmh0ID0gQ0FMTE4gKEZtYWtlX2hhc2hfdGFibGUsIFFDdGVzdCwgUWVxKTsK ICAgICAgIHN3aXRjaCAoWFRZUEUgKG8xKSkKIAl7CiAJY2FzZSBMaXNwX0NvbnM6IGNhc2Ug TGlzcF9WZWN0b3JsaWtlOgogCSAgewotCSAgICBzdHJ1Y3QgTGlzcF9IYXNoX1RhYmxlICpo ID0gWEhBU0hfVEFCTEUgKGh0KTsKKwkgICAgc3RydWN0IExpc3BfSGFzaF9UYWJsZSAqaCA9 IFhIQVNIX1RBQkxFICgqaHQpOwogCSAgICBoYXNoX2hhc2hfdCBoYXNoID0gaGFzaF9mcm9t X2tleSAoaCwgbzEpOwogCSAgICBwdHJkaWZmX3QgaSA9IGhhc2hfbG9va3VwX3dpdGhfaGFz aCAoaCwgbzEsIGhhc2gpOwogCSAgICBpZiAoaSA+PSAwKQpAQCAtMjg4OCw4ICsyODg4LDgg QEAgaW50ZXJuYWxfZXF1YWwgKExpc3BfT2JqZWN0IG8xLCBMaXNwX09iamVjdCBvMiwgZW51 bSBlcXVhbF9raW5kIGVxdWFsX2tpbmQsCiAJICB7CiAJICAgIGlmICghIENPTlNQIChvMikp CiAJICAgICAgcmV0dXJuIGZhbHNlOwotCSAgICBpZiAoISBpbnRlcm5hbF9lcXVhbCAoWENB UiAobzEpLCBYQ0FSIChvMiksCi0JCQkJICBlcXVhbF9raW5kLCBkZXB0aCArIDEsIGh0KSkK KwkgICAgaWYgKCEgaW50ZXJuYWxfZXF1YWxfMSAoWENBUiAobzEpLCBYQ0FSIChvMiksCisJ CQkJICAgIGVxdWFsX2tpbmQsIGRlcHRoICsgMSwgaHQpKQogCSAgICAgIHJldHVybiBmYWxz ZTsKIAkgICAgbzIgPSBYQ0RSIChvMik7CiAJICAgIGlmIChFUSAoWENEUiAobzEpLCBvMikp CkBAIC0yOTY0LDcgKzI5NjQsNyBAQCBpbnRlcm5hbF9lcXVhbCAoTGlzcF9PYmplY3QgbzEs IExpc3BfT2JqZWN0IG8yLCBlbnVtIGVxdWFsX2tpbmQgZXF1YWxfa2luZCwKIAkgICAgTGlz cF9PYmplY3QgdjEsIHYyOwogCSAgICB2MSA9IEFSRUYgKG8xLCBpKTsKIAkgICAgdjIgPSBB UkVGIChvMiwgaSk7Ci0JICAgIGlmICghaW50ZXJuYWxfZXF1YWwgKHYxLCB2MiwgZXF1YWxf a2luZCwgZGVwdGggKyAxLCBodCkpCisJICAgIGlmICghaW50ZXJuYWxfZXF1YWxfMSAodjEs IHYyLCBlcXVhbF9raW5kLCBkZXB0aCArIDEsIGh0KSkKIAkgICAgICByZXR1cm4gZmFsc2U7 CiAJICB9CiAJcmV0dXJuIHRydWU7CkBAIC0yOTg1LDYgKzI5ODUsMTMgQEAgaW50ZXJuYWxf ZXF1YWwgKExpc3BfT2JqZWN0IG8xLCBMaXNwX09iamVjdCBvMiwgZW51bSBlcXVhbF9raW5k IGVxdWFsX2tpbmQsCiAgIHJldHVybiBmYWxzZTsKIH0KIAorc3RhdGljIGJvb2wKK2ludGVy bmFsX2VxdWFsIChMaXNwX09iamVjdCBvMSwgTGlzcF9PYmplY3QgbzIsIGVudW0gZXF1YWxf a2luZCBlcXVhbF9raW5kLAorCQlpbnQgZGVwdGgsIExpc3BfT2JqZWN0IGh0KQoreworICBy ZXR1cm4gaW50ZXJuYWxfZXF1YWxfMSAobzEsIG8yLCBlcXVhbF9raW5kLCBkZXB0aCwgJmh0 KTsKK30KKwogLyogUmV0dXJuIC0xLzAvMSBmb3IgdGhlIDwvPS8+IGxleGljb2dyYXBoaWMg cmVsYXRpb24gYmV0d2VlbiBib29sLXZlY3RvcnMuICAqLwogc3RhdGljIGludAogYm9vbF92 ZWN0b3JfY21wIChMaXNwX09iamVjdCBhLCBMaXNwX09iamVjdCBiKQotLSAKMi40My4wLndp bmRvd3MuMQoK --------------YTR8mj80epC2vzTcYP0170Ey--