threads / patch / 36954

patchalloc.c: remove alloc_raw_commit_node() function

Subject: [PATCH] alloc.c: remove alloc_raw_commit_node() function

## tl;dr

6 messages between Jun 18, 2014 and Jun 19, 2014. Diffs are folded; open one to read it.

replies: 5people: 3as markdown or json

Ramsay Jones· Jun 18, 2014, 19:52 UTC · lore

In order to encapsulate the setting of the unique commit index, commit 969eba63 ("commit: push commit_index update into alloc_commit_node", 10-06-2014) introduced a (logically private) intermediary allocator function. However, this function (alloc_raw_commit_node()) was declared as a public function, which undermines its entire purpose.

Remove the alloc_raw_commit_node() function and inline its code into the (public) alloc_commit_node() function.

Noticed by sparse ("symbol 'alloc_raw_commit_node' was not declared. Should it be static?").

Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
---
Hi Jeff,

I noticed this while it was still in 'pu', but got distracted and didn't send this in time ... sorry about that! :(

My first attempt at fixing this involved changing the DEFINE_ALLOCATOR macro to include a 'scope' parameter so that I could declare the raw_commit allocator 'static'. Unfortunately, I could not pass the extern keyword as the scope parameter to all the other allocators, because that made sparse even more upset - you can't use extern on a function _definition_. That meant passing an empty argument (or a comment token) to the scope parameter. This worked for gcc 4.8.2 and clang 3.4, but I was a little concerned about portability.

This seems a better solution to me. Having said that ... as I'm typing this I realized that I could have removed the 'commit_count' variable and used 'commit_allocs' to set c->index instead! :-P Oh well ...

ATB, Ramsay Jones

 alloc.c | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)
Show changes to alloc.c +18 −4
diff --git a/alloc.c b/alloc.c
index eb22a45..124d710 100644
--- a/alloc.c
+++ b/alloc.c
@@ -47,16 +47,30 @@ union any_object {
 
 DEFINE_ALLOCATOR(blob, struct blob)
 DEFINE_ALLOCATOR(tree, struct tree)
-DEFINE_ALLOCATOR(raw_commit, struct commit)
 DEFINE_ALLOCATOR(tag, struct tag)
 DEFINE_ALLOCATOR(object, union any_object)
 
+static unsigned int commit_allocs;
+
 void *alloc_commit_node(void)
 {
 	static int commit_count;
-	struct commit *c = alloc_raw_commit_node();
+	static int nr;
+	static struct commit *block;
+	struct commit *c;
+	void *ret;
+
+	if (!nr) {
+		nr = BLOCKING;
+		block = xmalloc(BLOCKING * sizeof(struct commit));
+	}
+	nr--;
+	commit_allocs++;
+	ret = block++;
+	memset(ret, 0, sizeof(struct commit));
+	c = (struct commit *) ret;
 	c->index = commit_count++;
-	return c;
+	return ret;
 }
 
 static void report(const char *name, unsigned int count, size_t size)
@@ -72,7 +86,7 @@ void alloc_report(void)
 {
 	REPORT(blob, struct blob);
 	REPORT(tree, struct tree);
-	REPORT(raw_commit, struct commit);
+	REPORT(commit, struct commit);
 	REPORT(tag, struct tag);
 	REPORT(object, union any_object);
 }
-- 
2.0.0
Jeff King· Jun 18, 2014, 20:08 UTC · re: Ramsay Jones · lore

Re: [PATCH] alloc.c: remove alloc_raw_commit_node() function

On Wed, Jun 18, 2014 at 08:52:46PM +0100, Ramsay Jones wrote:
Show 19 quoted lines
> In order to encapsulate the setting of the unique commit index, commit
> 969eba63 ("commit: push commit_index update into alloc_commit_node",
> 10-06-2014) introduced a (logically private) intermediary allocator
> function. However, this function (alloc_raw_commit_node()) was declared
> as a public function, which undermines its entire purpose.
> 
> Remove the alloc_raw_commit_node() function and inline its code into
> the (public) alloc_commit_node() function.
> 
> Noticed by sparse ("symbol 'alloc_raw_commit_node' was not declared.
> Should it be static?").
> 
> Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
> ---
> 
> Hi Jeff,
> 
> I noticed this while it was still in 'pu', but got distracted and
> didn't send this in time ... sorry about that! :(

Yeah, I noticed it while writing the patch but decided it wasn't worth the trouble to deal with (since after all, it's not advertised to any callers, the very thing that sparse is complaining about. :) ).

I don't mind fixing it, though I really don't like repeating the contents of DEFINE_ALLOCATOR. I know it hasn't changed in a while, but it just feels wrong.

Show 8 quoted lines
> My first attempt at fixing this involved changing the DEFINE_ALLOCATOR
> macro to include a 'scope' parameter so that I could declare the
> raw_commit allocator 'static'. Unfortunately, I could not pass the
> extern keyword as the scope parameter to all the other allocators,
> because that made sparse even more upset - you can't use extern on
> a function _definition_. That meant passing an empty argument (or a
> comment token) to the scope parameter. This worked for gcc 4.8.2 and
> clang 3.4, but I was a little concerned about portability.

Yeah, passing an empty argument was my first thought, but I don't know offhand if there are portability concerns.

You could also have DEFINE_ALLOCATOR just fill in the body, and do:
  struct blob *alloc_blob_node(void)
  {
	DEFINE_ALLOCATOR(struct blob);
  }
or similar.
-Peff
Ramsay Jones· Jun 18, 2014, 22:30 UTC · re: Jeff King · lore

Re: [PATCH] alloc.c: remove alloc_raw_commit_node() function

On 18/06/14 21:08, Jeff King wrote:
> On Wed, Jun 18, 2014 at 08:52:46PM +0100, Ramsay Jones wrote:
> 
[snip]
Show 7 quoted lines
> Yeah, I noticed it while writing the patch but decided it wasn't worth
> the trouble to deal with (since after all, it's not advertised to any
> callers, the very thing that sparse is complaining about. :) ).
> 
> I don't mind fixing it, though I really don't like repeating the
> contents of DEFINE_ALLOCATOR. I know it hasn't changed in a while, but
> it just feels wrong.

So, the patch below is a slight variation on the original patch. I'm still slightly concerned about portability, but given that it has been at least a decade since I last used a (pre-ANSI) compiler which had a problem with this ...

[I have several versions of the C standard that I can use to check up on the legalise, but I'm not sure I can be bothered! ;-) ]

ATB, Ramsay Jones

-- >8 --
Subject: [PATCH] alloc.c: make alloc_raw_commit_node() a static function

In order to encapsulate the setting of the unique commit index, commit 969eba63 ("commit: push commit_index update into alloc_commit_node", 10-06-2014) introduced a (logically private) intermediary allocator function. However, this function (alloc_raw_commit_node()) was declared as a public function, which undermines its entire purpose.

Add a scope parameter to the DEFINE_ALLOCATOR macro to allow the raw commit allocator definition to include the 'static' qualifier.

Noticed by sparse ("symbol 'alloc_raw_commit_node' was not declared. Should it be static?").

Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
---
 alloc.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)
Show changes to alloc.c +10 −7
diff --git a/alloc.c b/alloc.c
index eb22a45..5392d13 100644
--- a/alloc.c
+++ b/alloc.c
@@ -18,9 +18,12 @@
 
 #define BLOCKING 1024
 
-#define DEFINE_ALLOCATOR(name, type)				\
+#define PUBLIC
+#define PRIVATE static
+
+#define DEFINE_ALLOCATOR(scope, name, type)			\
 static unsigned int name##_allocs;				\
-void *alloc_##name##_node(void)					\
+scope void *alloc_##name##_node(void)				\
 {								\
 	static int nr;						\
 	static type *block;					\
@@ -45,11 +48,11 @@ union any_object {
 	struct tag tag;
 };
 
-DEFINE_ALLOCATOR(blob, struct blob)
-DEFINE_ALLOCATOR(tree, struct tree)
-DEFINE_ALLOCATOR(raw_commit, struct commit)
-DEFINE_ALLOCATOR(tag, struct tag)
-DEFINE_ALLOCATOR(object, union any_object)
+DEFINE_ALLOCATOR(PUBLIC, blob, struct blob)
+DEFINE_ALLOCATOR(PUBLIC, tree, struct tree)
+DEFINE_ALLOCATOR(PRIVATE, raw_commit, struct commit)
+DEFINE_ALLOCATOR(PUBLIC, tag, struct tag)
+DEFINE_ALLOCATOR(PUBLIC, object, union any_object)
 
 void *alloc_commit_node(void)
 {
-- 
2.0.0
Jeff King· Jun 19, 2014, 09:19 UTC · re: Ramsay Jones · lore

Re: [PATCH] alloc.c: remove alloc_raw_commit_node() function

On Wed, Jun 18, 2014 at 11:30:50PM +0100, Ramsay Jones wrote:
> So, the patch below is a slight variation on the original patch.
> I'm still slightly concerned about portability, but given that it
> has been at least a decade since I last used a (pre-ANSI) compiler
> which had a problem with this ...

For a while some people were compiling git with pretty antique compilers, but I do not know if that is the case any more (Junio noted recently that we have had trailing commas on arrays and enums in builtin/clean.c for the past year, and nobody has complained).

Maybe those systems have all died off, or maybe those people only upgrade every few years, and we are due for an onslaught of portability fixes soon. :)

> [I have several versions of the C standard that I can use to check
> up on the legalise, but I'm not sure I can be bothered! ;-) ]

It was actually pretty easy to find. I only have C99, but "empty macro arguments" are listed as one of the changes since C89 in the foreward.

Show 13 quoted lines
> diff --git a/alloc.c b/alloc.c
> index eb22a45..5392d13 100644
> --- a/alloc.c
> +++ b/alloc.c
> @@ -18,9 +18,12 @@
>  
>  #define BLOCKING 1024
>  
> -#define DEFINE_ALLOCATOR(name, type)				\
> +#define PUBLIC
> +#define PRIVATE static
> +
> +#define DEFINE_ALLOCATOR(scope, name, type)			\

I am not sure offhand whether this is more portable or not (it would depend on order of macro expansion, and I am not brave enough to read through the preprocessor section of the standard carefully). Quick reading online suggests that it's OK, but that an extra level of macro expansion would not be. And of course the Internet is never wrong. :)

I'm inclined to go with it, and deal with it later if we get a portability complaint (at which point we are no worse off than we are right now).

-Peff
Ramsay Jones· Jun 19, 2014, 09:55 UTC · re: Jeff King · lore

Re: [PATCH] alloc.c: remove alloc_raw_commit_node() function

On 19/06/14 10:19, Jeff King wrote:
Show 15 quoted lines
> On Wed, Jun 18, 2014 at 11:30:50PM +0100, Ramsay Jones wrote:
> 
>> So, the patch below is a slight variation on the original patch.
>> I'm still slightly concerned about portability, but given that it
>> has been at least a decade since I last used a (pre-ANSI) compiler
>> which had a problem with this ...
> 
> For a while some people were compiling git with pretty antique
> compilers, but I do not know if that is the case any more (Junio noted
> recently that we have had trailing commas on arrays and enums in
> builtin/clean.c for the past year, and nobody has complained).
> 
> Maybe those systems have all died off, or maybe those people only
> upgrade every few years, and we are due for an onslaught of portability
> fixes soon. :)
:-P You never know ...
Show 5 quoted lines
>> [I have several versions of the C standard that I can use to check
>> up on the legalise, but I'm not sure I can be bothered! ;-) ]
> 
> It was actually pretty easy to find. I only have C99, but "empty macro
> arguments" are listed as one of the changes since C89 in the foreward.

Ah yes, having prompted me to look, it took all of 2 minutes to find it in the C11 .pdf file I have right here ...

Show 17 quoted lines
>> diff --git a/alloc.c b/alloc.c
>> index eb22a45..5392d13 100644
>> --- a/alloc.c
>> +++ b/alloc.c
>> @@ -18,9 +18,12 @@
>>  
>>  #define BLOCKING 1024
>>  
>> -#define DEFINE_ALLOCATOR(name, type)				\
>> +#define PUBLIC
>> +#define PRIVATE static
>> +
>> +#define DEFINE_ALLOCATOR(scope, name, type)			\
> 
> I am not sure offhand whether this is more portable or not (it would
> depend on order of macro expansion, and I am not brave enough to read
> through the preprocessor section of the standard carefully).

I suspect it is _slightly_ more portable, but I wouldn't bet any money on it! I may take a look at the standard (it wouldn't be the first time I've looked this up), but it would not help in this situation anyway. The fact that a given compiler does/does-not conform to the standard is useless knowledge if we need to support them.

>                                                               Quick
> reading online suggests that it's OK, but that an extra level of macro
> expansion would not be. And of course the Internet is never wrong. :)
;-)
> I'm inclined to go with it, and deal with it later if we get a
> portability complaint (at which point we are no worse off than we are
> right now).

Hmm, well my initial reaction was to send the more conservative patch first. I wasn't so worried about inlining the code from the macro (I doubt it will change), but I understand (and would often agree with) your concern.

I would be happy with either solution, so I'll let yourself and Junio decide! (sloping shoulders, or what. :) ).

ATB, Ramsay Jones

Junio C Hamano· Jun 19, 2014, 20:32 UTC · re: Jeff King · lore

Re: [PATCH] alloc.c: remove alloc_raw_commit_node() function

Jeff King <peff@peff.net> writes:
> For a while some people were compiling git with pretty antique
> compilers, but I do not know if that is the case any more (Junio noted
> recently that we have had trailing commas on arrays and enums in
> builtin/clean.c for the past year, and nobody has complained).

IIRC, the problematic is a trailing comma in enum definitions, not array initialisations.

← back to recent threads