Skip to content
Browse files

oprofile fix for hashing backtraces.

Oprofile's hash function uses a 64-bit value for the
key where the high 32-bit are the 'from' address in a backtrace,
and the low 32-bits are the current PC. However, the hash
function was:

  uint32_t temp = (value >> 32) ^ value;
  return ((temp << 0) ^ (temp >> 8)) & data->hash_mask;

If 'from' and 'to' are the same (recursive function), this hashes
to 0, and you end up with lots of collisions, turning the
theoretically O(1) operation into O(n).

To fix it, I just drop the high 32-bits from the hash:

  uint32_t temp = value & 0xffffffff;
  return ((temp << 0) ^ (temp >> 8)) & data->hash_mask;

In testing, this drastically reduces the oprofile overhead
for some tracing.

Change-Id: I8ae65a8a73771c89b576c895f135efd7b730eaf5
  • Loading branch information...
1 parent 20192a8 commit 8a572b129c9755959b4421970947aeda4119c3b7 @midodd midodd committed Nov 11, 2010
Showing with 3 additions and 1 deletion.
  1. +2 −0 .gitignore
  2. +1 −1 libdb/odb.h
View
2 .gitignore
@@ -0,0 +1,2 @@
+.cproject
+.project
View
2 libdb/odb.h
@@ -228,7 +228,7 @@ odb_do_hash(odb_data_t const * data, odb_key_t value)
* files avoiding to rebuilding them at profiling re-start so
* on changing do_hash() change the file format!
*/
- uint32_t temp = (value >> 32) ^ value;
+ uint32_t temp = value & 0xffffffff;
return ((temp << 0) ^ (temp >> 8)) & data->hash_mask;
}

0 comments on commit 8a572b1

Please sign in to comment.
Something went wrong with that request. Please try again.