<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>