b.a.t.m.a.n.lists.open-mesh.org archive mirror
 help / color / mirror / Atom feed
From: Sven Eckelmann <sven.eckelmann@gmx.de>
To: greg@kroah.com
Cc: b.a.t.m.a.n@lists.open-mesh.org
Subject: [B.A.T.M.A.N.] [PATCH 20/29] Staging: batman-adv: Move hash callback related function to header
Date: Mon, 22 Nov 2010 00:55:58 +0100	[thread overview]
Message-ID: <1290383767-32602-21-git-send-email-sven.eckelmann@gmx.de> (raw)
In-Reply-To: <1290383767-32602-1-git-send-email-sven.eckelmann@gmx.de>

To enable inlining of the function pointers hashdata_choose_cb,
hashdata_choose_cb and hashdata_free_cb, also the hash functions which
uses them must be inlined by the called function.

This should increase the performance, but also increases the size of the
generated machine code slightly.

Reported-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de>
---
 drivers/staging/batman-adv/hash.c |  150 ------------------------------------
 drivers/staging/batman-adv/hash.h |  152 ++++++++++++++++++++++++++++++++++---
 2 files changed, 140 insertions(+), 162 deletions(-)

diff --git a/drivers/staging/batman-adv/hash.c b/drivers/staging/batman-adv/hash.c
index 6361a31..7d04987 100644
--- a/drivers/staging/batman-adv/hash.c
+++ b/drivers/staging/batman-adv/hash.c
@@ -33,30 +33,6 @@ static void hash_init(struct hashtable_t *hash)
 		hash->table[i] = NULL;
 }
 
-/* remove the hash structure. if hashdata_free_cb != NULL, this function will be
- * called to remove the elements inside of the hash.  if you don't remove the
- * elements, memory might be leaked. */
-void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb, void *arg)
-{
-	struct element_t *bucket, *last_bucket;
-	int i;
-
-	for (i = 0; i < hash->size; i++) {
-		bucket = hash->table[i];
-
-		while (bucket != NULL) {
-			if (free_cb != NULL)
-				free_cb(bucket->data, arg);
-
-			last_bucket = bucket;
-			bucket = bucket->next;
-			kfree(last_bucket);
-		}
-	}
-
-	hash_destroy(hash);
-}
-
 /* free only the hashtable and the hash itself. */
 void hash_destroy(struct hashtable_t *hash)
 {
@@ -159,70 +135,6 @@ struct hashtable_t *hash_new(int size)
 	return hash;
 }
 
-/* adds data to the hashtable. returns 0 on success, -1 on error */
-int hash_add(struct hashtable_t *hash, hashdata_compare_cb compare,
-	     hashdata_choose_cb choose, void *data)
-{
-	int index;
-	struct element_t *bucket, *prev_bucket = NULL;
-
-	if (!hash)
-		return -1;
-
-	index = choose(data, hash->size);
-	bucket = hash->table[index];
-
-	while (bucket != NULL) {
-		if (compare(bucket->data, data))
-			return -1;
-
-		prev_bucket = bucket;
-		bucket = bucket->next;
-	}
-
-	/* found the tail of the list, add new element */
-	bucket = kmalloc(sizeof(struct element_t), GFP_ATOMIC);
-
-	if (bucket == NULL)
-		return -1;
-
-	bucket->data = data;
-	bucket->next = NULL;
-
-	/* and link it */
-	if (prev_bucket == NULL)
-		hash->table[index] = bucket;
-	else
-		prev_bucket->next = bucket;
-
-	hash->elements++;
-	return 0;
-}
-
-/* finds data, based on the key in keydata. returns the found data on success,
- * or NULL on error */
-void *hash_find(struct hashtable_t *hash, hashdata_compare_cb compare,
-		hashdata_choose_cb choose, void *keydata)
-{
-	int index;
-	struct element_t *bucket;
-
-	if (!hash)
-		return NULL;
-
-	index = choose(keydata , hash->size);
-	bucket = hash->table[index];
-
-	while (bucket != NULL) {
-		if (compare(bucket->data, keydata))
-			return bucket->data;
-
-		bucket = bucket->next;
-	}
-
-	return NULL;
-}
-
 /* remove bucket (this might be used in hash_iterate() if you already found the
  * bucket you want to delete and don't need the overhead to find it again with
  * hash_remove(). But usually, you don't want to use this function, as it
@@ -243,65 +155,3 @@ void *hash_remove_bucket(struct hashtable_t *hash, struct hash_it_t *hash_it_t)
 
 	return data_save;
 }
-
-/* removes data from hash, if found. returns pointer do data on success, so you
- * can remove the used structure yourself, or NULL on error .  data could be the
- * structure you use with just the key filled, we just need the key for
- * comparing. */
-void *hash_remove(struct hashtable_t *hash, hashdata_compare_cb compare,
-		  hashdata_choose_cb choose, void *data)
-{
-	struct hash_it_t hash_it_t;
-
-	hash_it_t.index = choose(data, hash->size);
-	hash_it_t.bucket = hash->table[hash_it_t.index];
-	hash_it_t.prev_bucket = NULL;
-
-	while (hash_it_t.bucket != NULL) {
-		if (compare(hash_it_t.bucket->data, data)) {
-			hash_it_t.first_bucket =
-				(hash_it_t.bucket ==
-				 hash->table[hash_it_t.index] ?
-				 &hash->table[hash_it_t.index] : NULL);
-			return hash_remove_bucket(hash, &hash_it_t);
-		}
-
-		hash_it_t.prev_bucket = hash_it_t.bucket;
-		hash_it_t.bucket = hash_it_t.bucket->next;
-	}
-
-	return NULL;
-}
-
-/* resize the hash, returns the pointer to the new hash or NULL on
- * error. removes the old hash on success. */
-struct hashtable_t *hash_resize(struct hashtable_t *hash,
-				hashdata_compare_cb compare,
-				hashdata_choose_cb choose, int size)
-{
-	struct hashtable_t *new_hash;
-	struct element_t *bucket;
-	int i;
-
-	/* initialize a new hash with the new size */
-	new_hash = hash_new(size);
-
-	if (new_hash == NULL)
-		return NULL;
-
-	/* copy the elements */
-	for (i = 0; i < hash->size; i++) {
-		bucket = hash->table[i];
-
-		while (bucket != NULL) {
-			hash_add(new_hash, compare, choose, bucket->data);
-			bucket = bucket->next;
-		}
-	}
-
-	/* remove hash and eventual overflow buckets but not the content
-	 * itself. */
-	hash_delete(hash, NULL, NULL);
-
-	return new_hash;
-}
diff --git a/drivers/staging/batman-adv/hash.h b/drivers/staging/batman-adv/hash.h
index 85ee12b..efc4c28 100644
--- a/drivers/staging/batman-adv/hash.h
+++ b/drivers/staging/batman-adv/hash.h
@@ -66,35 +66,163 @@ struct hashtable_t *hash_new(int size);
  * fiddles with hash-internals. */
 void *hash_remove_bucket(struct hashtable_t *hash, struct hash_it_t *hash_it_t);
 
+/* free only the hashtable and the hash itself. */
+void hash_destroy(struct hashtable_t *hash);
+
 /* remove the hash structure. if hashdata_free_cb != NULL, this function will be
  * called to remove the elements inside of the hash.  if you don't remove the
  * elements, memory might be leaked. */
-void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb, void *arg);
+static inline void hash_delete(struct hashtable_t *hash,
+			       hashdata_free_cb free_cb, void *arg)
+{
+	struct element_t *bucket, *last_bucket;
+	int i;
 
-/* free only the hashtable and the hash itself. */
-void hash_destroy(struct hashtable_t *hash);
+	for (i = 0; i < hash->size; i++) {
+		bucket = hash->table[i];
+
+		while (bucket != NULL) {
+			if (free_cb != NULL)
+				free_cb(bucket->data, arg);
+
+			last_bucket = bucket;
+			bucket = bucket->next;
+			kfree(last_bucket);
+		}
+	}
+
+	hash_destroy(hash);
+}
 
 /* adds data to the hashtable. returns 0 on success, -1 on error */
-int hash_add(struct hashtable_t *hash, hashdata_compare_cb compare,
-	     hashdata_choose_cb choose, void *data);
+static inline int hash_add(struct hashtable_t *hash,
+			   hashdata_compare_cb compare,
+			   hashdata_choose_cb choose, void *data)
+{
+	int index;
+	struct element_t *bucket, *prev_bucket = NULL;
+
+	if (!hash)
+		return -1;
+
+	index = choose(data, hash->size);
+	bucket = hash->table[index];
+
+	while (bucket != NULL) {
+		if (compare(bucket->data, data))
+			return -1;
+
+		prev_bucket = bucket;
+		bucket = bucket->next;
+	}
+
+	/* found the tail of the list, add new element */
+	bucket = kmalloc(sizeof(struct element_t), GFP_ATOMIC);
+
+	if (bucket == NULL)
+		return -1;
+
+	bucket->data = data;
+	bucket->next = NULL;
+
+	/* and link it */
+	if (prev_bucket == NULL)
+		hash->table[index] = bucket;
+	else
+		prev_bucket->next = bucket;
+
+	hash->elements++;
+	return 0;
+}
 
 /* removes data from hash, if found. returns pointer do data on success, so you
  * can remove the used structure yourself, or NULL on error .  data could be the
  * structure you use with just the key filled, we just need the key for
  * comparing. */
-void *hash_remove(struct hashtable_t *hash, hashdata_compare_cb compare,
-		  hashdata_choose_cb choose, void *data);
+static inline void *hash_remove(struct hashtable_t *hash,
+				hashdata_compare_cb compare,
+				hashdata_choose_cb choose, void *data)
+{
+	struct hash_it_t hash_it_t;
+
+	hash_it_t.index = choose(data, hash->size);
+	hash_it_t.bucket = hash->table[hash_it_t.index];
+	hash_it_t.prev_bucket = NULL;
+
+	while (hash_it_t.bucket != NULL) {
+		if (compare(hash_it_t.bucket->data, data)) {
+			hash_it_t.first_bucket =
+				(hash_it_t.bucket ==
+				 hash->table[hash_it_t.index] ?
+				 &hash->table[hash_it_t.index] : NULL);
+			return hash_remove_bucket(hash, &hash_it_t);
+		}
+
+		hash_it_t.prev_bucket = hash_it_t.bucket;
+		hash_it_t.bucket = hash_it_t.bucket->next;
+	}
+
+	return NULL;
+}
 
 /* finds data, based on the key in keydata. returns the found data on success,
  * or NULL on error */
-void *hash_find(struct hashtable_t *hash, hashdata_compare_cb compare,
-		hashdata_choose_cb choose, void *keydata);
+static inline void *hash_find(struct hashtable_t *hash,
+			      hashdata_compare_cb compare,
+			      hashdata_choose_cb choose, void *keydata)
+{
+	int index;
+	struct element_t *bucket;
+
+	if (!hash)
+		return NULL;
+
+	index = choose(keydata , hash->size);
+	bucket = hash->table[index];
+
+	while (bucket != NULL) {
+		if (compare(bucket->data, keydata))
+			return bucket->data;
+
+		bucket = bucket->next;
+	}
+
+	return NULL;
+}
 
 /* resize the hash, returns the pointer to the new hash or NULL on
  * error. removes the old hash on success */
-struct hashtable_t *hash_resize(struct hashtable_t *hash,
-				hashdata_compare_cb compare,
-				hashdata_choose_cb choose, int size);
+static inline struct hashtable_t *hash_resize(struct hashtable_t *hash,
+					      hashdata_compare_cb compare,
+					      hashdata_choose_cb choose,
+					      int size)
+{
+	struct hashtable_t *new_hash;
+	struct element_t *bucket;
+	int i;
+
+	/* initialize a new hash with the new size */
+	new_hash = hash_new(size);
+
+	if (new_hash == NULL)
+		return NULL;
+
+	/* copy the elements */
+	for (i = 0; i < hash->size; i++) {
+		bucket = hash->table[i];
+
+		while (bucket != NULL) {
+			hash_add(new_hash, compare, choose, bucket->data);
+			bucket = bucket->next;
+		}
+	}
+
+	/* remove hash and eventual overflow buckets but not the content
+	 * itself. */
+	hash_delete(hash, NULL, NULL);
+
+	return new_hash;
+}
 
 /* iterate though the hash. first element is selected with iter_in NULL.  use
  * the returned iterator to access the elements until hash_it_t returns NULL. */
-- 
1.7.2.3


  parent reply	other threads:[~2010-11-21 23:55 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-21 23:55 [B.A.T.M.A.N.] batman-adv for 2.6.38 (1) Sven Eckelmann
2010-11-21 23:55 ` [B.A.T.M.A.N.] [PATCH 01/29] Staging: batman-adv: Replace Andrew Lunn as Staging maintainer Sven Eckelmann
2010-11-21 23:55 ` [B.A.T.M.A.N.] [PATCH 02/29] Staging: batman-adv: ensure that eth_type_trans gets linear memory Sven Eckelmann
2010-11-21 23:55 ` [B.A.T.M.A.N.] [PATCH 03/29] Staging: batman-adv: Add new sysfs files to README Sven Eckelmann
2010-11-21 23:55 ` [B.A.T.M.A.N.] [PATCH 04/29] Staging: batman-adv: Don't remove interface with spinlock held Sven Eckelmann
2010-11-21 23:55 ` [B.A.T.M.A.N.] [PATCH 05/29] Staging: batman-adv: convert batman_if custom refcounting to kref functions Sven Eckelmann
2010-11-21 23:55 ` [B.A.T.M.A.N.] [PATCH 06/29] Staging: batman-adv: use rcu callbacks when freeing batman_if Sven Eckelmann
2010-11-21 23:55 ` [B.A.T.M.A.N.] [PATCH 07/29] Staging: batman-adv: restructure fragmentation to handle batman unicast packets Sven Eckelmann
2010-11-21 23:55 ` [B.A.T.M.A.N.] [PATCH 08/29] Staging: batman-adv: add frag_ prefix to all fragmentation related functions Sven Eckelmann
2010-11-21 23:55 ` [B.A.T.M.A.N.] [PATCH 09/29] Staging: batman-adv: move skb reassembly of fragmented packets into dedicated function Sven Eckelmann
2010-11-21 23:55 ` [B.A.T.M.A.N.] [PATCH 10/29] Staging: batman-adv: remove redundant is_my_mac() check in route_unicast_packet Sven Eckelmann
2010-11-21 23:55 ` [B.A.T.M.A.N.] [PATCH 11/29] Staging: batman-adv: fragment forwarded packets Sven Eckelmann
2010-11-21 23:55 ` [B.A.T.M.A.N.] [PATCH 12/29] Staging: batman-adv: reassemble fragmented skb if mtu allows it Sven Eckelmann
2010-11-21 23:55 ` [B.A.T.M.A.N.] [PATCH 13/29] Staging: batman-adv: softif bridge loop avoidance Sven Eckelmann
2010-11-21 23:55 ` [B.A.T.M.A.N.] [PATCH 14/29] Staging: batman-adv: Unify sysfs file names with their bat_priv atomics Sven Eckelmann
2010-11-21 23:55 ` [B.A.T.M.A.N.] [PATCH 15/29] Staging: batman-adv: Wrapper functions for sysfs storing Sven Eckelmann
2010-11-21 23:55 ` [B.A.T.M.A.N.] [PATCH 16/29] Staging: batman-adv: Ommit storing struct device in sysfs functions Sven Eckelmann
2010-11-21 23:55 ` [B.A.T.M.A.N.] [PATCH 17/29] Staging: batman-adv: Make hop_penalty configurable via sysfs Sven Eckelmann
2010-11-21 23:55 ` [B.A.T.M.A.N.] [PATCH 18/29] Staging: batman-adv: Remove hashdata_compare_cb from hash Sven Eckelmann
2010-11-21 23:55 ` [B.A.T.M.A.N.] [PATCH 19/29] Staging: batman-adv: Remove hashdata_choose_cb " Sven Eckelmann
2010-11-21 23:55 ` Sven Eckelmann [this message]
2010-11-21 23:55 ` [B.A.T.M.A.N.] [PATCH 21/29] Staging: batman-adv: Make hash_iterate inlineable Sven Eckelmann
2010-11-21 23:56 ` [B.A.T.M.A.N.] [PATCH 22/29] Staging: batman-adv: Rewrite hash using hlist_* Sven Eckelmann
2010-11-21 23:56 ` [B.A.T.M.A.N.] [PATCH 23/29] Staging: batman-adv: Limit spin_locks to spin_lock_bh Sven Eckelmann
2010-11-21 23:56 ` [B.A.T.M.A.N.] [PATCH 24/29] Staging: batman-adv: adding gateway functionality Sven Eckelmann
2010-11-21 23:56 ` [B.A.T.M.A.N.] [PATCH 25/29] Staging: batman-adv: send DHCP requests directly to the chosen gw Sven Eckelmann
2010-11-21 23:56 ` [B.A.T.M.A.N.] [PATCH 26/29] Staging: batman-adv: best gw DHCP filter 802.1Q support Sven Eckelmann
2010-11-21 23:56 ` [B.A.T.M.A.N.] [PATCH 27/29] Staging: batman-adv: add gateway IPv6 support by filtering DHCPv6 messages Sven Eckelmann
2010-11-21 23:56 ` [B.A.T.M.A.N.] [PATCH 28/29] Staging: batman-adv: Use kernel version min macro Sven Eckelmann
2010-11-21 23:56 ` [B.A.T.M.A.N.] [PATCH 29/29] Staging: batman-adv: Use kernel functions to identify broadcasts Sven Eckelmann
2010-11-22  1:06 ` [B.A.T.M.A.N.] batman-adv for 2.6.38 (1) Marek Lindner
2010-11-22 10:28   ` Sven Eckelmann
2010-11-22 11:34     ` [B.A.T.M.A.N.] Staging: batman-adv for 2.6.37 (6) Sven Eckelmann
2010-11-29 18:55       ` Greg KH
2010-11-22 11:34     ` [B.A.T.M.A.N.] [PATCH-stable] Staging: batman-adv: ensure that eth_type_trans gets linear memory Sven Eckelmann
2010-11-22 11:34     ` [B.A.T.M.A.N.] [PATCH 1/2] " Sven Eckelmann
2010-11-22 11:34     ` [B.A.T.M.A.N.] [PATCH 2/2] Staging: batman-adv: Don't remove interface with spinlock held Sven Eckelmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1290383767-32602-21-git-send-email-sven.eckelmann@gmx.de \
    --to=sven.eckelmann@gmx.de \
    --cc=b.a.t.m.a.n@lists.open-mesh.org \
    --cc=greg@kroah.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).