summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJarno Rajahalme <jarno@ovn.org>2016-07-29 11:04:48 -0700
committerJarno Rajahalme <jarno@ovn.org>2016-07-29 11:11:14 -0700
commit93f25605e49e106c1b05babd21923d5ad6bb551b (patch)
treef60c3785e68ae6c4ef83486915a19b9c8416f2cb
parent3d0dc308a46e1e05aaec454f94e0129b811cb3c2 (diff)
downloadopenvswitch-93f25605e49e106c1b05babd21923d5ad6bb551b.tar.gz
pvector: Get rid of special purpose of INT_MIN.
Allow clients to use the whole priority range. Note that this changes the semantics of PVECTOR_FOR_EACH_PRIORITY so that the iteration still continues for entries at the given priority. Suggested-by: Ben Pfaff <blp@ovn.org> Signed-off-by: Jarno Rajahalme <jarno@ovn.org> Acked-by: Ben Pfaff <blp@ovn.org>
-rw-r--r--lib/classifier.c4
-rw-r--r--lib/pvector.c12
-rw-r--r--lib/pvector.h14
3 files changed, 13 insertions, 17 deletions
diff --git a/lib/classifier.c b/lib/classifier.c
index 2b24724c6..54941ed04 100644
--- a/lib/classifier.c
+++ b/lib/classifier.c
@@ -960,7 +960,7 @@ classifier_lookup__(const struct classifier *cls, cls_version_t version,
/* Main loop. */
struct cls_subtable *subtable;
- PVECTOR_FOR_EACH_PRIORITY (subtable, hard_pri, 2, sizeof *subtable,
+ PVECTOR_FOR_EACH_PRIORITY (subtable, hard_pri + 1, 2, sizeof *subtable,
&cls->subtables) {
struct cls_conjunction_set *conj_set;
@@ -1232,7 +1232,7 @@ classifier_rule_overlaps(const struct classifier *cls,
struct cls_subtable *subtable;
/* Iterate subtables in the descending max priority order. */
- PVECTOR_FOR_EACH_PRIORITY (subtable, target->priority - 1, 2,
+ PVECTOR_FOR_EACH_PRIORITY (subtable, target->priority, 2,
sizeof(struct cls_subtable), &cls->subtables) {
struct {
struct minimask mask;
diff --git a/lib/pvector.c b/lib/pvector.c
index 04c2e65e9..aaeee9214 100644
--- a/lib/pvector.c
+++ b/lib/pvector.c
@@ -95,10 +95,6 @@ static void
pvector_impl_sort(struct pvector_impl *impl)
{
qsort(impl->vector, impl->size, sizeof *impl->vector, pvector_entry_cmp);
- /* Trim gaps. */
- while (impl->size && impl->vector[impl->size - 1].priority == INT_MIN) {
- impl->size = impl->size - 1;
- }
}
/* Returns the index of the 'ptr' in the vector, or -1 if none is found. */
@@ -163,9 +159,11 @@ pvector_remove(struct pvector *pvec, void *ptr)
index = pvector_impl_find(temp, ptr);
ovs_assert(index >= 0);
/* Now at the index of the entry to be deleted.
- * Clear in place, publish will sort and clean these off. */
- temp->vector[index].ptr = NULL;
- temp->vector[index].priority = INT_MIN;
+ * Swap another entry in if needed, publish will sort anyway. */
+ temp->size--;
+ if (index != temp->size) {
+ temp->vector[index] = temp->vector[temp->size];
+ }
}
/* Change entry's 'priority' and keep the vector ordered. */
diff --git a/lib/pvector.h b/lib/pvector.h
index 263e783a2..b175b213d 100644
--- a/lib/pvector.h
+++ b/lib/pvector.h
@@ -54,8 +54,6 @@
* 'temp' may contain NULL pointers and it may be in unsorted order. It is
* sorted before it is published at 'impl', which also removes the NULLs from
* the published vector.
- *
- * Clients should not use priority INT_MIN.
*/
struct pvector_entry {
@@ -129,7 +127,7 @@ static inline bool pvector_is_empty(const struct pvector *);
* has to be started.
*
* The PVECTOR_FOR_EACH_PRIORITY limits the iteration to entries with higher
- * than given priority and allows for object lookahead.
+ * than or equal to the given priority and allows for object lookahead.
*
* The iteration loop must be completed without entering the OVS RCU quiescent
* period. That is, an old iteration loop must not be continued after any
@@ -145,7 +143,7 @@ static inline struct pvector_cursor pvector_cursor_init(const struct pvector *,
size_t n_ahead,
size_t obj_size);
static inline void *pvector_cursor_next(struct pvector_cursor *,
- int stop_at_priority,
+ int lowest_priority,
size_t n_ahead, size_t obj_size);
static inline void pvector_cursor_lookahead(const struct pvector_cursor *,
int n, size_t size);
@@ -154,8 +152,8 @@ static inline void pvector_cursor_lookahead(const struct pvector_cursor *,
for (struct pvector_cursor cursor__ = pvector_cursor_init(PVECTOR, 0, 0); \
((PTR) = pvector_cursor_next(&cursor__, INT_MIN, 0, 0)) != NULL; )
-/* Loop while priority is higher than 'PRIORITY' and prefetch objects
- * of size 'SZ' 'N' objects ahead from the current object. */
+/* Loop while priority is higher than or equal to 'PRIORITY' and prefetch
+ * objects of size 'SZ' 'N' objects ahead from the current object. */
#define PVECTOR_FOR_EACH_PRIORITY(PTR, PRIORITY, N, SZ, PVECTOR) \
for (struct pvector_cursor cursor__ = pvector_cursor_init(PVECTOR, N, SZ); \
((PTR) = pvector_cursor_next(&cursor__, PRIORITY, N, SZ)) != NULL; )
@@ -193,11 +191,11 @@ pvector_cursor_init(const struct pvector *pvec,
}
static inline void *pvector_cursor_next(struct pvector_cursor *cursor,
- int stop_at_priority,
+ int lowest_priority,
size_t n_ahead, size_t obj_size)
{
if (++cursor->entry_idx < cursor->size &&
- cursor->vector[cursor->entry_idx].priority > stop_at_priority) {
+ cursor->vector[cursor->entry_idx].priority >= lowest_priority) {
if (n_ahead) {
pvector_cursor_lookahead(cursor, n_ahead, obj_size);
}