Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
ccan
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
mirror
ccan
Commits
6502a872
Commit
6502a872
authored
Jun 29, 2008
by
Rusty Russell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
External allocator support.
parent
1d7e593d
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
154 additions
and
12 deletions
+154
-12
ccan/talloc/talloc.c
ccan/talloc/talloc.c
+64
-12
ccan/talloc/talloc.h
ccan/talloc/talloc.h
+26
-0
ccan/talloc/test/run-external-alloc.c
ccan/talloc/test/run-external-alloc.c
+64
-0
No files found.
ccan/talloc/talloc.c
View file @
6502a872
...
...
@@ -45,6 +45,7 @@
#define TALLOC_MAGIC 0xe814ec70
#define TALLOC_FLAG_FREE 0x01
#define TALLOC_FLAG_LOOP 0x02
#define TALLOC_FLAG_EXT_ALLOC 0x04
#define TALLOC_MAGIC_REFERENCE ((const char *)1)
/* by default we abort when given a bad pointer (such as when talloc_free() is called
...
...
@@ -79,6 +80,10 @@
static
void
*
null_context
;
static
void
*
autofree_context
;
static
void
*
(
*
tc_external_alloc
)(
void
*
parent
,
size_t
size
);
static
void
(
*
tc_external_free
)(
void
*
ptr
,
void
*
parent
);
static
void
*
(
*
tc_external_realloc
)(
void
*
ptr
,
void
*
parent
,
size_t
size
);
struct
talloc_reference_handle
{
struct
talloc_reference_handle
*
next
,
*
prev
;
void
*
ptr
;
...
...
@@ -181,6 +186,8 @@ const char *talloc_parent_name(const void *ptr)
static
inline
void
*
__talloc
(
const
void
*
context
,
size_t
size
)
{
struct
talloc_chunk
*
tc
;
struct
talloc_chunk
*
parent
=
NULL
;
/* Prevent spurious gcc warning */
unsigned
flags
=
TALLOC_MAGIC
;
if
(
unlikely
(
context
==
NULL
))
{
context
=
null_context
;
...
...
@@ -190,19 +197,28 @@ static inline void *__talloc(const void *context, size_t size)
return
NULL
;
}
if
(
likely
(
context
))
{
parent
=
talloc_chunk_from_ptr
(
context
);
if
(
unlikely
(
parent
->
flags
&
TALLOC_FLAG_EXT_ALLOC
))
{
tc
=
tc_external_alloc
(
TC_PTR_FROM_CHUNK
(
parent
),
TC_HDR_SIZE
+
size
);
flags
|=
TALLOC_FLAG_EXT_ALLOC
;
goto
alloc_done
;
}
}
tc
=
(
struct
talloc_chunk
*
)
malloc
(
TC_HDR_SIZE
+
size
);
alloc_done:
if
(
unlikely
(
tc
==
NULL
))
return
NULL
;
tc
->
size
=
size
;
tc
->
flags
=
TALLOC_MAGIC
;
tc
->
flags
=
flags
;
tc
->
destructor
=
NULL
;
tc
->
child
=
NULL
;
tc
->
name
=
NULL
;
tc
->
refs
=
NULL
;
if
(
likely
(
context
))
{
struct
talloc_chunk
*
parent
=
talloc_chunk_from_ptr
(
context
);
if
(
parent
->
child
)
{
parent
->
child
->
parent
=
NULL
;
tc
->
next
=
parent
->
child
;
...
...
@@ -319,6 +335,7 @@ void *_talloc_reference(const void *context, const void *ptr)
static
inline
int
_talloc_free
(
void
*
ptr
)
{
struct
talloc_chunk
*
tc
;
void
*
oldparent
=
NULL
;
if
(
unlikely
(
ptr
==
NULL
))
{
return
-
1
;
...
...
@@ -362,6 +379,7 @@ static inline int _talloc_free(void *ptr)
}
if
(
tc
->
parent
)
{
oldparent
=
TC_PTR_FROM_CHUNK
(
tc
->
parent
);
_TLIST_REMOVE
(
tc
->
parent
->
child
,
tc
);
if
(
tc
->
parent
->
child
)
{
tc
->
parent
->
child
->
parent
=
tc
->
parent
;
...
...
@@ -395,7 +413,12 @@ static inline int _talloc_free(void *ptr)
}
tc
->
flags
|=
TALLOC_FLAG_FREE
;
free
(
tc
);
if
(
unlikely
(
tc
->
flags
&
TALLOC_FLAG_EXT_ALLOC
))
tc_external_free
(
tc
,
oldparent
);
else
free
(
tc
);
return
0
;
}
...
...
@@ -771,18 +794,26 @@ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *n
return
NULL
;
}
/* by resetting magic we catch users of the old memory */
tc
->
flags
|=
TALLOC_FLAG_FREE
;
if
(
unlikely
(
tc
->
flags
&
TALLOC_FLAG_EXT_ALLOC
))
{
/* need to get parent before setting free flag. */
void
*
parent
=
talloc_parent
(
ptr
);
tc
->
flags
|=
TALLOC_FLAG_FREE
;
new_ptr
=
tc_external_realloc
(
tc
,
parent
,
size
+
TC_HDR_SIZE
);
}
else
{
/* by resetting magic we catch users of the old memory */
tc
->
flags
|=
TALLOC_FLAG_FREE
;
#if ALWAYS_REALLOC
new_ptr
=
malloc
(
size
+
TC_HDR_SIZE
);
if
(
new_ptr
)
{
memcpy
(
new_ptr
,
tc
,
tc
->
size
+
TC_HDR_SIZE
);
free
(
tc
);
}
new_ptr
=
malloc
(
size
+
TC_HDR_SIZE
);
if
(
new_ptr
)
{
memcpy
(
new_ptr
,
tc
,
tc
->
size
+
TC_HDR_SIZE
);
free
(
tc
);
}
#else
new_ptr
=
realloc
(
tc
,
size
+
TC_HDR_SIZE
);
new_ptr
=
realloc
(
tc
,
size
+
TC_HDR_SIZE
);
#endif
}
if
(
unlikely
(
!
new_ptr
))
{
tc
->
flags
&=
~
TALLOC_FLAG_FREE
;
return
NULL
;
...
...
@@ -1401,3 +1432,24 @@ int talloc_is_parent(const void *context, const void *ptr)
}
return
0
;
}
void
talloc_external_enable
(
void
*
(
*
alloc
)(
void
*
parent
,
size_t
size
),
void
(
*
free
)(
void
*
ptr
,
void
*
parent
),
void
*
(
*
realloc
)(
void
*
ptr
,
void
*
parent
,
size_t
))
{
tc_external_alloc
=
alloc
;
tc_external_free
=
free
;
tc_external_realloc
=
realloc
;
}
void
talloc_mark_external
(
void
*
context
)
{
struct
talloc_chunk
*
tc
;
if
(
unlikely
(
context
==
NULL
))
{
context
=
null_context
;
}
tc
=
talloc_chunk_from_ptr
(
context
);
tc
->
flags
|=
TALLOC_FLAG_EXT_ALLOC
;
}
ccan/talloc/talloc.h
View file @
6502a872
...
...
@@ -928,6 +928,32 @@ size_t talloc_get_size(const void *ctx);
*/
void
*
talloc_find_parent_byname
(
const
void
*
ctx
,
const
char
*
name
);
/**
* talloc_external_enable - set external allocators for some nodes
* @alloc: the malloc() equivalent
* @free: the free() equivalent
* @realloc: the realloc() equivalent
*
* talloc_mark_external() can be used to mark nodes whose children should
* use separate allocators. Currently the set of allocators is global, not
* per-node, and is set with this function.
*
* The parent pointers is the talloc pointer of the parent.
*/
void
talloc_external_enable
(
void
*
(
*
alloc
)(
void
*
parent
,
size_t
size
),
void
(
*
free
)(
void
*
ptr
,
void
*
parent
),
void
*
(
*
realloc
)(
void
*
ptr
,
void
*
parent
,
size_t
));
/**
* talloc_mark_external - children of this note must use external allocators
* @p: the talloc pointer
*
* This function indicates that all children (and children's children etc)
* should use the allocators set up wth talloc_external_enable() rather than
* normal malloc/free.
*/
void
talloc_mark_external
(
void
*
ptr
);
/* The following definitions come from talloc.c */
void
*
_talloc
(
const
void
*
context
,
size_t
size
);
void
_talloc_set_destructor
(
const
void
*
ptr
,
int
(
*
destructor
)(
void
*
));
...
...
ccan/talloc/test/run-external-alloc.c
0 → 100644
View file @
6502a872
#include "talloc/talloc.c"
#include "tap/tap.h"
#include <assert.h>
static
int
ext_alloc_count
,
ext_free_count
,
ext_realloc_count
;
static
void
*
expected_parent
;
static
void
*
ext_alloc
(
void
*
parent
,
size_t
size
)
{
ok1
(
parent
==
expected_parent
);
ext_alloc_count
++
;
return
malloc
(
size
);
}
static
void
ext_free
(
void
*
ptr
,
void
*
parent
)
{
ok1
(
parent
==
expected_parent
);
ext_free_count
++
;
free
(
ptr
);
}
static
void
*
ext_realloc
(
void
*
ptr
,
void
*
parent
,
size_t
size
)
{
ok1
(
parent
==
expected_parent
);
ext_realloc_count
++
;
return
realloc
(
ptr
,
size
);
}
int
main
(
void
)
{
char
*
p
,
*
p2
,
*
head
;
plan_tests
(
10
);
talloc_external_enable
(
ext_alloc
,
ext_free
,
ext_realloc
);
head
=
talloc
(
NULL
,
char
);
assert
(
head
);
expected_parent
=
head
;
talloc_mark_external
(
head
);
p
=
talloc_array
(
head
,
char
,
1
);
ok1
(
ext_alloc_count
==
1
);
assert
(
p
);
/* Child is also externally allocated */
expected_parent
=
p
;
p2
=
talloc
(
p
,
char
);
ok1
(
ext_alloc_count
==
2
);
expected_parent
=
head
;
p
=
talloc_realloc
(
NULL
,
p
,
char
,
1000
);
ok1
(
ext_realloc_count
==
1
);
assert
(
p
);
expected_parent
=
p
;
talloc_free
(
p2
);
ok1
(
ext_free_count
==
1
);
expected_parent
=
head
;
talloc_free
(
p
);
ok1
(
ext_free_count
==
2
);
return
exit_status
();
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment