Skip to content

Commit

Permalink
Staging: batman-adv: Calculate hamming weight using optimized kernel …
Browse files Browse the repository at this point in the history
…functions

The Kernighan algorithm is not able to calculate the number of set bits
in parallel and the compiler cannot replace it with optimized
instructions.

The kernel provides specialised functions for each cpu which can either
use a software implementation or hardware instruction depending on the
target cpu.

Reported-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Sven Eckelmann authored and Greg Kroah-Hartman committed Sep 5, 2010
1 parent 556c83e commit 8bb22a3
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 12 deletions.
1 change: 0 additions & 1 deletion drivers/staging/batman-adv/TODO
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
* Use hweight* for hamming weight calculation
* Save/cache packets direktly as skb instead of using a normal memory region
and copying it in a skb using send_raw_packet and similar functions
* Request a new review
Expand Down
15 changes: 5 additions & 10 deletions drivers/staging/batman-adv/bitarray.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include "main.h"
#include "bitarray.h"

#include <linux/bitops.h>

/* returns true if the corresponding bit in the given seq_bits indicates true
* and curr_seqno is within range of last_seqno */
uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint32_t last_seqno,
Expand Down Expand Up @@ -187,21 +189,14 @@ char bit_get_packet(TYPE_OF_WORD *seq_bits, int32_t seq_num_diff,
}

/* count the hamming weight, how many good packets did we receive? just count
* the 1's. The inner loop uses the Kernighan algorithm, see
* http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan
* the 1's.
*/
int bit_packet_count(TYPE_OF_WORD *seq_bits)
{
int i, hamming = 0;
TYPE_OF_WORD word;

for (i = 0; i < NUM_WORDS; i++) {
word = seq_bits[i];
for (i = 0; i < NUM_WORDS; i++)
hamming += hweight_long(seq_bits[i]);

while (word) {
word &= word-1;
hamming++;
}
}
return hamming;
}
3 changes: 2 additions & 1 deletion drivers/staging/batman-adv/bitarray.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
#ifndef _NET_BATMAN_ADV_BITARRAY_H_
#define _NET_BATMAN_ADV_BITARRAY_H_

/* you should choose something big, if you don't want to waste cpu */
/* you should choose something big, if you don't want to waste cpu
* and keep the type in sync with bit_packet_count */
#define TYPE_OF_WORD unsigned long
#define WORD_BIT_SIZE (sizeof(TYPE_OF_WORD) * 8)

Expand Down

0 comments on commit 8bb22a3

Please sign in to comment.