<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">op 20-09-13 20:26, Wiley, Glen schreef:<br>
    </div>
    <blockquote cite="mid:CE6209DB.169D3%25gwiley@verisign.com"
      type="cite">
      <meta http-equiv="Content-Type" content="text/html;
        charset=windows-1252">
      <div>
        <div>Willem, Well written. Would there really be a need for
          "custom" helpers for non-trivial data types? </div>
      </div>
    </blockquote>
    Some applications might want to do this for performance
    enhancements.  For example to manage thread-specific memory-regions
    that do not need the global lock that malloc has.  Or to keep track
    of a bunch of related allocations needed for a specific operation
    that, when the operation is done, may be freed together in one go.<br>
    <br>
    But again, I think we should keep an initial implementation simple
    and I advocate global custom memory functions.<br>
    <br>
    <blockquote cite="mid:CE6209DB.169D3%25gwiley@verisign.com"
      type="cite">
      <div>
        <div>I think we could use the system allocator in the library
          routines as a default, if the user registers a new allocator
          then allocations would be made using that allocator.</div>
      </div>
    </blockquote>
    <blockquote cite="mid:CE6209DB.169D3%25gwiley@verisign.com"
      type="cite">
      <div>
        <div>In order to avoid silliness that might ensue if a custom
          allocator is set after allocations are made custom allocators
          must be registered as part of an initialization routine or
          prior to calling any other library entry points.  We could set
          a flag to detect that public entry points have been called and
          return FAIL if the user attempts to set a custom allocator.
        </div>
      </div>
    </blockquote>
    <br>
    Sounds good.  Or an allocation counter that is decreased on frees. 
    Custom memory functions may only be registered when the global
    allocation counter is zero.<br>
    <blockquote cite="mid:CE6209DB.169D3%25gwiley@verisign.com"
      type="cite">
      <div>
        <div>I think we almost have to follow this approach to avoid
          cases in which we are creating non-trivial data types within
          the library routines – unless we want to explicitly detect
          whether an allocator has been registered every time we create
          one of the data types.</div>
      </div>
    </blockquote>
    Yes, if we have that sort of protection, we have to use it
    internally as well...<br>
    <br>
    But maybe we should postpone this and keep the implementation as
    straight forward as possible for the moment.  We could use macro's
    for malloc, free and realloc to be able to easily modify behaviour
    in the future.<br>
    <br>
    -- <br>
    Willem<br>
    <blockquote cite="mid:CE6209DB.169D3%25gwiley@verisign.com"
      type="cite">
      <div>
        <div><br>
        </div>
        <div>-- </div>
        <div>
          <div>
            <div>Glen Wiley</div>
            <div>KK4SFV</div>
          </div>
          <div>Sr. Engineer</div>
          <div>The Hive, Verisign, Inc.</div>
        </div>
      </div>
      <div><br>
      </div>
      <span id="OLK_SRC_BODY_SECTION">
        <div style="font-family:Calibri; font-size:11pt;
          text-align:left; color:black; BORDER-BOTTOM: medium none;
          BORDER-LEFT: medium none; PADDING-BOTTOM: 0in; PADDING-LEFT:
          0in; PADDING-RIGHT: 0in; BORDER-TOP: #b5c4df 1pt solid;
          BORDER-RIGHT: medium none; PADDING-TOP: 3pt">
          <span style="font-weight:bold">From: </span>Willem Toorop
          <<a moz-do-not-send="true"
            href="mailto:willem@nlnetlabs.nl">willem@nlnetlabs.nl</a>><br>
          <span style="font-weight:bold">Date: </span>Friday, September
          20, 2013 8:25 AM<br>
          <span style="font-weight:bold">To: </span>"<a
            moz-do-not-send="true" href="mailto:getdns-api@vpnc.org">getdns-api@vpnc.org</a>"
          <<a moz-do-not-send="true"
            href="mailto:getdns-api@vpnc.org">getdns-api@vpnc.org</a>><br>
          <span style="font-weight:bold">Subject: </span>Re:
          [getdns-api] user defined allocators<br>
        </div>
        <div><br>
        </div>
        <div>
          <div bgcolor="#FFFFFF" text="#000000">
            <div class="moz-cite-prefix">Op 21-08-13 13:04, Wiley, Glen
              schreef:<br>
            </div>
            <blockquote cite="mid:CE3A16E4.1283E%25gwiley@verisign.com"
              type="cite">
              <div>As we are working on our implementation of the getdns
                API I realized that there doesn't seem to be a way for
                the helper functions that handle the dict and list types
                to get to the user defined allocator.  The allocator is
                specified in a context, however the signatures of the
                helper functions do not accept a context as an argument.
                 There are a few ways to address this:</div>
              <div><br>
              </div>
              <ol>
                <li>Add a context as an argument to the helper
                  functions.  This is probably the least disruptive to
                  the rest of the API.
                </li>
                <li>Change the way a user defined allocator is defined.
                   It is likely that the application developer would
                  expect to use the same allocator throughout the
                  application so it may be enough to make an assignment
                  outside a context as an initialization step.
                </li>
              </ol>
              <div>I am sure that there are other options, but I think
                approach #2 would be a comfortable way to handle this.</div>
            </blockquote>
            I agree.<br>
            <br>
            Also the custom memory management functions that may be
            specified have the same prototype as the standard C
            functions.  This restricts the type of custom memory
            functions to ones that either do no custom memory
            bookkeeping, or have the needed bookkeeping-journal in
            globals.  Having global custom memory functions in a
            individual getdns context feels as a discrepancy.  A global
            registration function would suit better. For example, just
            like the one in libevent:<br>
            <br>
            <pre><tt><strong>void</strong> getdns_set_mem_functions(<strong>void</strong> *(*malloc_fn)(size_t sz),
                              <strong>void</strong> *(*realloc_fn)(<strong>void</strong> *ptr, size_t sz),
                              <strong>void</strong> (*free_fn)(<strong>void</strong> *ptr));</tt></pre>
            <br>
            I prefer custom memory management functions to be
            implementation specific in the API, just like setting the
            event base is.  I feel there are too many variables to
            consider to have a conclusive solution that fits all.  It
            would also allow for implementations to match this
            capability with the capabilities of the event base.<br>
            <br>
            <br>
            -- Willem<br>
            <br>
            <br>
            PS. An implementations that would allow bookkeeping memory
            functions, could have a registration function that would
            look something like this:<br>
            <pre><tt><strong>void</strong> getdns_context_set_mem_functions(getdns_context_t<strong> </strong>context<strong>,
                                      void</strong> *(*malloc_fn)(<b>void</b> *journal, size_t sz),
                              <strong>        void</strong> *(*realloc_fn)(<b>void</b> *journal, <strong>void</strong> *ptr, size_t sz),
                              <strong>        void</strong> (*free_fn)(<strong>void</strong> *journal, <strong>void</strong> *ptr));</tt></pre>
            <br>
            Of course it would then also need custom list and dict
            create functions:<br>
            <br>
            <pre><tt>struct getdns_list * getdns_list_create_custom(getdns_context_t<strong> </strong>context<strong>);</strong></tt></pre>
            <pre><tt>struct getdns_dict * getdns_dict_create_custom(getdns_context_t<strong> </strong>context<strong>);

</strong></tt></pre>
          </div>
        </div>
      </span>
    </blockquote>
    <br>
  </body>
</html>