When partitioning the work amongst threads, dividing the number of
objects by the number of threads may return 0 when there are less
objects than threads; this will cause the subsequent code to segfault
when accessing list[sub_size-1]. Fix this by ensuring that sub_size
is not zero if there is at least one object to process.
Signed-off-by: Sergey Vlasov <redacted>
---
builtin-pack-objects.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
From: Johannes Sixt <hidden> Date: 2016-06-15 22:44:07
Sergey Vlasov schrieb:
quoted hunk
When partitioning the work amongst threads, dividing the number of
objects by the number of threads may return 0 when there are less
objects than threads; this will cause the subsequent code to segfault
when accessing list[sub_size-1]. Fix this by ensuring that sub_size
is not zero if there is at least one object to process.
Signed-off-by: Sergey Vlasov <redacted>
---
builtin-pack-objects.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
I think it fits the logic better to include sub_size > 0 in the while loop
that follows, like so:
/* try to split chunks on "path" boundaries */
while (0 < sub_size && sub_size < list_size &&
list[sub_size]->hash &&
list[sub_size]->hash == list[sub_size-1]->hash)
sub_size++;
because we explicitly want to allow threads to "work" on zero objects
(i.e. do nothing at all), but if a thread does get assigned some work,
then its chunk is extended past the next path boundary. This way you
collapse two special cases - "zero-sized chunk" and "path boundary" - into
one.
-- Hannes
From: Nicolas Pitre <hidden> Date: 2016-06-15 22:44:07
On Mon, 21 Jan 2008, Sergey Vlasov wrote:
When partitioning the work amongst threads, dividing the number of
objects by the number of threads may return 0 when there are less
objects than threads; this will cause the subsequent code to segfault
when accessing list[sub_size-1]. Fix this by ensuring that sub_size
is not zero if there is at least one object to process.
No. Forcing one object in a thread is counter productive since it won't
have anything to delta against. Instead, the thread should be allowed
to have zero objects and let the other threads have more.
This patch would be a proper fix:
From: Nicolas Pitre <hidden> Date: 2016-06-15 22:44:07
On Mon, 21 Jan 2008, Johannes Sixt wrote:
Sergey Vlasov schrieb:
quoted
When partitioning the work amongst threads, dividing the number of
objects by the number of threads may return 0 when there are less
objects than threads; this will cause the subsequent code to segfault
when accessing list[sub_size-1]. Fix this by ensuring that sub_size
is not zero if there is at least one object to process.
Signed-off-by: Sergey Vlasov <redacted>
---
builtin-pack-objects.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
I think it fits the logic better to include sub_size > 0 in the while loop
that follows, like so:
/* try to split chunks on "path" boundaries */
while (0 < sub_size && sub_size < list_size &&
list[sub_size]->hash &&
list[sub_size]->hash == list[sub_size-1]->hash)
sub_size++;
because we explicitly want to allow threads to "work" on zero objects
(i.e. do nothing at all), but if a thread does get assigned some work,
then its chunk is extended past the next path boundary. This way you
collapse two special cases - "zero-sized chunk" and "path boundary" - into
one.
On Mon, Jan 21, 2008 at 11:07:15AM -0500, Nicolas Pitre wrote:
quoted hunk
On Mon, 21 Jan 2008, Sergey Vlasov wrote:
quoted
When partitioning the work amongst threads, dividing the number of
objects by the number of threads may return 0 when there are less
objects than threads; this will cause the subsequent code to segfault
when accessing list[sub_size-1]. Fix this by ensuring that sub_size
is not zero if there is at least one object to process.
No. Forcing one object in a thread is counter productive since it won't
have anything to delta against. Instead, the thread should be allowed
to have zero objects and let the other threads have more.
This patch would be a proper fix:
@@ -1672,7 +1672,8 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size,p[i].data_ready=0;/* try to split chunks on "path" boundaries */-while(sub_size<list_size&&list[sub_size]->hash&&+while(sub_size&&sub_size<list_size&&+list[sub_size]->hash&&list[sub_size]->hash==list[sub_size-1]->hash)sub_size++;
Actually there will not be any significant differences - with my patch
the object distribution between threads will be 1, 1, ..., 0, 0...,
and with your patch it would be 0, 0, ..., 1, 1, ... (unless the
objects had the same hash, in which case they would be passed to a
single thread in both cases).
We could even introduce some limit on the number of objects below
which multithreaded packing is not attempted, so that packing a small
number of objects would be more efficient.
From: Nicolas Pitre <hidden> Date: 2016-06-15 22:44:07
On Mon, 21 Jan 2008, Sergey Vlasov wrote:
On Mon, Jan 21, 2008 at 11:07:15AM -0500, Nicolas Pitre wrote:
quoted
On Mon, 21 Jan 2008, Sergey Vlasov wrote:
quoted
When partitioning the work amongst threads, dividing the number of
objects by the number of threads may return 0 when there are less
objects than threads; this will cause the subsequent code to segfault
when accessing list[sub_size-1]. Fix this by ensuring that sub_size
is not zero if there is at least one object to process.
No. Forcing one object in a thread is counter productive since it won't
have anything to delta against. Instead, the thread should be allowed
to have zero objects and let the other threads have more.
This patch would be a proper fix:
@@ -1672,7 +1672,8 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size,p[i].data_ready=0;/* try to split chunks on "path" boundaries */-while(sub_size<list_size&&list[sub_size]->hash&&+while(sub_size&&sub_size<list_size&&+list[sub_size]->hash&&list[sub_size]->hash==list[sub_size-1]->hash)sub_size++;
Actually there will not be any significant differences - with my patch
the object distribution between threads will be 1, 1, ..., 0, 0...,
and with your patch it would be 0, 0, ..., 1, 1, ...
Or more likely 0, 0, ..., 2.
And the code is simpler.
We could even introduce some limit on the number of objects below
which multithreaded packing is not attempted, so that packing a small
number of objects would be more efficient.
Possibly. But that's not a requirement at this moment.
Nicolas