]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
improve Util_BufferIsEmpty performance
authorVMware, Inc <>
Mon, 20 Dec 2010 22:18:13 +0000 (14:18 -0800)
committerMarcelo Vanzin <mvanzin@vmware.com>
Mon, 20 Dec 2010 22:18:13 +0000 (14:18 -0800)
Use some better inlining...

Signed-off-by: Marcelo Vanzin <mvanzin@vmware.com>
open-vm-tools/lib/include/util.h

index d2b1cf61dedfe77effedf627738f842e69850a98..eb45d250269b690a33a30fe19ad32de68c803cba 100644 (file)
@@ -154,59 +154,93 @@ Bool Util_QueryCStResidency(uint32 *numCpus, uint32 *numCStates,
 EXTERN Bool Util_Throttle(uint32 count);
 EXTERN uint32 Util_FastRand(uint32 seed);
 
+
 /*
- *----------------------------------------------------------------------
+ *-----------------------------------------------------------------------------
  *
- * Util_BufferIsEmpty --
+ * Util_ValidateBytes --
  *
- *    Determine wether or not the buffer of 'len' bytes starting at 'base' is
- *    empty (i.e. full of zeroes)
+ *      Check that memory is filled with the specified value.
  *
  * Results:
- *    TRUE if yes
- *    FALSE if no
+ *      NULL   No error
+ *      !NULL  First address that doesn't have the proper value
  *
  * Side effects:
- *    None
+ *      None.
  *
- *----------------------------------------------------------------------
+ *-----------------------------------------------------------------------------
  */
 
-static INLINE Bool Util_BufferIsEmpty(void const *base, // IN
-                                      size_t len)       // IN
+static INLINE void *
+Util_ValidateBytes(int byteValue,    // IN: memory must be this
+                   const void *ptr,  // IN: ptr to check
+                   size_t size)      // IN: size of ptr
 {
-   uint32 const *p32;
-   uint32 const *e32;
-   uint16 const *p16;
+   uint64 bigValue;
 
-   ASSERT_ON_COMPILE(sizeof(uint32) == 4);
+   char *p = (char *) ptr;
 
-   p32 = (uint32 const *)base;
-   e32 = p32 + len / 4;
-   for (; p32 < e32; p32++) {
-      if (*p32) {
-         return FALSE;
+   /* Compare bytes until a "nice" boundary is achieved */
+   while ((((uintptr_t) p) & (sizeof(uint64) - 1)) != 0) {
+      if (*p != byteValue) {
+         return (void *) p;
       }
+
+      size--;
+      p++;
    }
 
-   len &= 0x3;
-   p16 = (uint16 const *)p32;
+   /* Compare using a "nice sized" chunk for a long as possible */
+   memset((void *) &bigValue, byteValue, sizeof bigValue);
 
-   if (len & 0x2) {
-      if (*p16) {
-         return FALSE;
+   while (size >= sizeof(uint64)) {
+      if (*((uint64 *) p) != bigValue) {
+         /* That's not right... let the loop below report the exact address */
+         break;
       }
 
-      p16++;
+      size -= sizeof(uint64);
+      p += sizeof(uint64);
    }
 
-   if (   len & 0x1
-       && *(uint8 const *)p16) {
-      return FALSE;
+   /* Handle any trailing bytes */
+   while (size) {
+      if (*p != byteValue) {
+         return (void *) p;
+      }
+
+      size--;
+      p++;
    }
 
-   return TRUE;
-};
+   return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Util_BufferIsEmpty --
+ *
+ *    Determine if the specified buffer of 'len' bytes starting at 'base'
+ *    is empty (i.e. full of zeroes).
+ *
+ * Results:
+ *    TRUE  Yes
+ *    FALSE No
+ *
+ * Side effects:
+ *    None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static INLINE Bool
+Util_BufferIsEmpty(void const *base,  // IN:
+                   size_t len)        // IN:
+{
+   return Util_ValidateBytes(0, base, len) == NULL;
+}
 
 
 EXTERN Bool Util_MakeSureDirExistsAndAccessible(char const *path,