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
794a6678
Commit
794a6678
authored
Aug 05, 2008
by
Rusty Russell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Simplify external allocation (realloc only from Tridge)
parent
16b7eb13
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
80 additions
and
95 deletions
+80
-95
ccan/talloc/TODO
ccan/talloc/TODO
+0
-2
ccan/talloc/talloc.c
ccan/talloc/talloc.c
+56
-50
ccan/talloc/talloc.h
ccan/talloc/talloc.h
+10
-19
ccan/talloc/test/run-external-alloc.c
ccan/talloc/test/run-external-alloc.c
+14
-24
No files found.
ccan/talloc/TODO
deleted
100644 → 0
View file @
16b7eb13
- Remove talloc.h cruft
- Restore errno around (successful) talloc_free.
ccan/talloc/talloc.c
View file @
794a6678
...
...
@@ -82,9 +82,7 @@
static
void
*
null_context
;
static
pid_t
*
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
);
static
void
*
(
*
tc_external_realloc
)(
const
void
*
parent
,
void
*
ptr
,
size_t
size
);
struct
talloc_reference_handle
{
struct
talloc_reference_handle
*
next
,
*
prev
;
...
...
@@ -182,45 +180,23 @@ const char *talloc_parent_name(const void *ptr)
return
tc
?
tc
->
name
:
NULL
;
}
/*
Allocate a bit of memory as a child of an existing pointer
*/
static
inline
void
*
__talloc
(
const
void
*
context
,
size_t
size
)
static
void
*
init_talloc
(
struct
talloc_chunk
*
parent
,
struct
talloc_chunk
*
tc
,
size_t
size
,
int
external
)
{
struct
talloc_chunk
*
tc
;
struct
talloc_chunk
*
parent
=
NULL
;
/* Prevent spurious gcc warning */
unsigned
flags
=
TALLOC_MAGIC
;
if
(
unlikely
(
context
==
NULL
))
{
context
=
null_context
;
}
if
(
unlikely
(
size
>=
MAX_TALLOC_SIZE
))
{
if
(
unlikely
(
tc
==
NULL
))
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
=
flags
;
tc
->
flags
=
TALLOC_MAGIC
;
if
(
external
)
tc
->
flags
|=
TALLOC_FLAG_EXT_ALLOC
;
tc
->
destructor
=
NULL
;
tc
->
child
=
NULL
;
tc
->
name
=
NULL
;
tc
->
refs
=
NULL
;
if
(
likely
(
contex
t
))
{
if
(
likely
(
paren
t
))
{
if
(
parent
->
child
)
{
parent
->
child
->
parent
=
NULL
;
tc
->
next
=
parent
->
child
;
...
...
@@ -238,6 +214,38 @@ alloc_done:
return
TC_PTR_FROM_CHUNK
(
tc
);
}
/*
Allocate a bit of memory as a child of an existing pointer
*/
static
inline
void
*
__talloc
(
const
void
*
context
,
size_t
size
)
{
struct
talloc_chunk
*
tc
;
struct
talloc_chunk
*
parent
=
NULL
;
int
external
=
0
;
if
(
unlikely
(
context
==
NULL
))
{
context
=
null_context
;
}
if
(
unlikely
(
size
>=
MAX_TALLOC_SIZE
))
{
return
NULL
;
}
if
(
likely
(
context
))
{
parent
=
talloc_chunk_from_ptr
(
context
);
if
(
unlikely
(
parent
->
flags
&
TALLOC_FLAG_EXT_ALLOC
))
{
tc
=
tc_external_realloc
(
context
,
NULL
,
TC_HDR_SIZE
+
size
);
external
=
1
;
goto
alloc_done
;
}
}
tc
=
(
struct
talloc_chunk
*
)
malloc
(
TC_HDR_SIZE
+
size
);
alloc_done:
return
init_talloc
(
parent
,
tc
,
size
,
external
);
}
/*
setup a destructor to be called on free of a pointer
the destructor should return 0 on success, or -1 on failure.
...
...
@@ -419,7 +427,7 @@ static inline int _talloc_free(void *ptr)
tc
->
flags
|=
TALLOC_FLAG_FREE
;
if
(
unlikely
(
tc
->
flags
&
TALLOC_FLAG_EXT_ALLOC
))
tc_external_
free
(
tc
,
oldparent
);
tc_external_
realloc
(
oldparent
,
tc
,
0
);
else
free
(
tc
);
...
...
@@ -802,7 +810,7 @@ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *n
/* 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
);
new_ptr
=
tc_external_realloc
(
parent
,
tc
,
size
+
TC_HDR_SIZE
);
}
else
{
/* by resetting magic we catch users of the old memory */
tc
->
flags
|=
TALLOC_FLAG_FREE
;
...
...
@@ -1441,23 +1449,21 @@ 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
))
void
*
talloc_add_external
(
const
void
*
ctx
,
void
*
(
*
realloc
)(
const
void
*
,
void
*
,
size_t
))
{
tc_external_alloc
=
alloc
;
tc_external_free
=
free
;
tc_external_realloc
=
realloc
;
}
struct
talloc_chunk
*
tc
,
*
parent
;
void
talloc_mark_external
(
void
*
context
)
{
struct
talloc_chunk
*
t
c
;
if
(
tc_external_realloc
&&
tc_external_realloc
!=
realloc
)
TALLOC_ABORT
(
"talloc_add_external realloc replaced"
);
tc_external_realloc
=
reallo
c
;
if
(
unlikely
(
context
==
NULL
))
{
context
=
null_context
;
}
if
(
unlikely
(
ctx
==
NULL
))
{
ctx
=
null_context
;
parent
=
NULL
;
}
else
parent
=
talloc_chunk_from_ptr
(
ctx
);
tc
=
t
alloc_chunk_from_ptr
(
context
);
tc
->
flags
|=
TALLOC_FLAG_EXT_ALLOC
;
tc
=
t
c_external_realloc
(
ctx
,
NULL
,
TC_HDR_SIZE
);
return
init_talloc
(
parent
,
tc
,
0
,
1
)
;
}
ccan/talloc/talloc.h
View file @
794a6678
...
...
@@ -929,30 +929,21 @@ 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
* talloc_add_external - create an externally allocated node
* @ctx: the parent
* @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.
* talloc_add_external() creates a node which uses a separate allocator. All
* children allocated from that node will also use that allocator.
*
* 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
* Note: Currently there is only one external allocator, not per-node,
* and it is set with this function.
*
* 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.
* The parent pointers in realloc is the talloc pointer of the parent, if any.
*/
void
talloc_mark_external
(
void
*
ptr
);
void
*
talloc_add_external
(
const
void
*
ctx
,
void
*
(
*
realloc
)(
const
void
*
parent
,
void
*
ptr
,
size_t
));
/* The following definitions come from talloc.c */
void
*
_talloc
(
const
void
*
context
,
size_t
size
);
...
...
ccan/talloc/test/run-external-alloc.c
View file @
794a6678
...
...
@@ -5,47 +5,37 @@
static
int
ext_alloc_count
,
ext_free_count
,
ext_realloc_count
;
static
void
*
expected_parent
;
static
void
*
ext_
alloc
(
void
*
parent
,
size_t
size
)
static
void
*
ext_
realloc
(
const
void
*
parent
,
void
*
ptr
,
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
++
;
if
(
ptr
==
NULL
)
ext_alloc_count
++
;
if
(
size
==
0
)
ext_free_count
++
;
if
(
ptr
&&
size
)
ext_realloc_count
++
;
return
realloc
(
ptr
,
size
);
}
int
main
(
void
)
{
char
*
p
,
*
p2
,
*
head
;
plan_tests
(
1
0
);
plan_tests
(
1
2
);
talloc_external_enable
(
ext_alloc
,
ext_free
,
ext_realloc
)
;
head
=
talloc
(
NULL
,
char
);
expected_parent
=
NULL
;
head
=
talloc
_add_external
(
NULL
,
ext_realloc
);
assert
(
head
);
expected_parent
=
head
;
talloc_mark_external
(
head
);
ok1
(
ext_alloc_count
==
1
);
expected_parent
=
head
;
p
=
talloc_array
(
head
,
char
,
1
);
ok1
(
ext_alloc_count
==
1
);
ok1
(
ext_alloc_count
==
2
);
assert
(
p
);
/* Child is also externally allocated */
expected_parent
=
p
;
p2
=
talloc
(
p
,
char
);
ok1
(
ext_alloc_count
==
2
);
ok1
(
ext_alloc_count
==
3
);
expected_parent
=
head
;
p
=
talloc_realloc
(
NULL
,
p
,
char
,
1000
);
...
...
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