]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IOHistogramReporter.cpp
xnu-4903.270.47.tar.gz
[apple/xnu.git] / iokit / Kernel / IOHistogramReporter.cpp
index 4c288ccdb89095888d2d0751026c8294846003bf..efbd6de16e9643e4fe4b9500c2427bada5163e13 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Copyright (c) 2012-2013 Apple Computer, Inc.  All Rights Reserved.
- * 
+ *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * unlawful or unlicensed copies of an Apple operating system, or to
  * circumvent, violate, or enable the circumvention or violation of, any
  * terms of an Apple operating system software license agreement.
- * 
+ *
  * Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -22,7 +22,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
@@ -40,340 +40,354 @@ OSDefineMetaClassAndStructors(IOHistogramReporter, IOReporter);
 /* static */
 IOHistogramReporter*
 IOHistogramReporter::with(IOService *reportingService,
-                          IOReportCategories categories,
-                          uint64_t channelID,
-                          const char *channelName,
-                          IOReportUnit unit,
-                          int nSegments,
-                          IOHistogramSegmentConfig *config)
+    IOReportCategories categories,
+    uint64_t channelID,
+    const char *channelName,
+    IOReportUnit unit,
+    int nSegments,
+    IOHistogramSegmentConfig *config)
 {
-    IOHistogramReporter *reporter = new IOHistogramReporter;
-    
-    const OSSymbol *tmpChannelName = NULL;
-    
-    if (reporter) {
-        
-        if (channelName)
-            tmpChannelName = OSSymbol::withCString(channelName);
-                
-        if(reporter->initWith(reportingService, categories,
-                              channelID, tmpChannelName,
-                              unit, nSegments, config)) {
-            return reporter;
-        }
-    }
-    OSSafeReleaseNULL(reporter);
-    OSSafeReleaseNULL(tmpChannelName);
-    
-    return 0;
+       IOHistogramReporter *reporter = new IOHistogramReporter;
+
+       const OSSymbol *tmpChannelName = NULL;
+
+       if (reporter) {
+               if (channelName) {
+                       tmpChannelName = OSSymbol::withCString(channelName);
+               }
+
+               if (reporter->initWith(reportingService, categories,
+                   channelID, tmpChannelName,
+                   unit, nSegments, config)) {
+                       return reporter;
+               }
+       }
+       OSSafeReleaseNULL(reporter);
+       OSSafeReleaseNULL(tmpChannelName);
+
+       return 0;
 }
 
 
 bool
 IOHistogramReporter::initWith(IOService *reportingService,
-                              IOReportCategories categories,
-                              uint64_t channelID,
-                              const OSSymbol *channelName,
-                              IOReportUnit unit,
-                              int nSegments,
-                              IOHistogramSegmentConfig *config)
+    IOReportCategories categories,
+    uint64_t channelID,
+    const OSSymbol *channelName,
+    IOReportUnit unit,
+    int nSegments,
+    IOHistogramSegmentConfig *config)
 {
-    bool            result = false;
-    IOReturn        res;        // for PREFL_MEMOP
-    size_t          configSize, elementsSize, eCountsSize, boundsSize;
-    int             cnt, cnt2, cnt3 = 0;
-    int64_t        bucketBound = 0, previousBucketBound = 0;
-    
-    // analyzer appeasement
-    configSize = elementsSize = eCountsSize = boundsSize = 0;
-    
-    IORLOG("IOHistogramReporter::initWith");
-
-    // For now, this reporter is currently limited to a single channel
-    _nChannels = 1;
-
-    IOReportChannelType channelType = {
-        .categories = categories,
-        .report_format = kIOReportFormatHistogram,
-        .nelements = 0,  // Initialized when Config is unpacked
-        .element_idx = 0
-    };
-    
-    if (super::init(reportingService, channelType, unit) != true) {
-        IORLOG("%s - ERROR: super::init failed", __func__);
-        result = false;
-        goto finish;
-    }
-    
-    // Make sure to call this after the commit init phase
-    if (channelName) _channelNames->setObject(channelName);
-    
-    _segmentCount = nSegments;
-    if (_segmentCount == 0) {
-        IORLOG("IOReportHistogram init ERROR. No configuration provided!");
-        result = false;
-        goto finish;
-    }
-    
-    IORLOG("%s - %u segment(s)", __func__, _segmentCount);
-    
-    PREFL_MEMOP_FAIL(_segmentCount, IOHistogramSegmentConfig);
-    configSize = (size_t)_segmentCount * sizeof(IOHistogramSegmentConfig);
-    _histogramSegmentsConfig = (IOHistogramSegmentConfig*)IOMalloc(configSize);
-    if (!_histogramSegmentsConfig)      goto finish;
-    memcpy(_histogramSegmentsConfig, config, configSize);
-    
-    // Find out how many elements are need to store the histogram
-    for (cnt = 0; cnt < _segmentCount; cnt++) {
-        
-        _nElements += _histogramSegmentsConfig[cnt].segment_bucket_count;
-        _channelDimension += _histogramSegmentsConfig[cnt].segment_bucket_count;
-        
-        IORLOG("\t\t bucket_base_width: %u | log_scale: %u | buckets: %u",
-                _histogramSegmentsConfig[cnt].base_bucket_width,
-                _histogramSegmentsConfig[cnt].scale_flag,
-                _histogramSegmentsConfig[cnt].segment_bucket_count);
-        
-        if (_histogramSegmentsConfig[cnt].scale_flag > 1
-            || _histogramSegmentsConfig[cnt].base_bucket_width == 0) {
-            result = false;
-            goto finish;
-        }
-
-    }
-    
-    // Update the channel type with discovered dimension
-    _channelType.nelements = _channelDimension;
-
-    IORLOG("%s - %u channel(s) of dimension %u",
-           __func__, _nChannels, _channelDimension);
-
-    IORLOG("%s %d segments for a total dimension of %d elements",
-           __func__, _nChannels, _nElements);
-    
-    // Allocate memory for the array of report elements
-    PREFL_MEMOP_FAIL(_nElements, IOReportElement);
-    elementsSize = (size_t)_nElements * sizeof(IOReportElement);
-    _elements = (IOReportElement *)IOMalloc(elementsSize);
-    if (!_elements)             goto finish;
-    memset(_elements, 0, elementsSize);
-    
-    // Allocate memory for the array of element watch count
-    PREFL_MEMOP_FAIL(_nElements, int);
-    eCountsSize = (size_t)_nChannels * sizeof(int);
-    _enableCounts = (int *)IOMalloc(eCountsSize);
-    if (!_enableCounts)         goto finish;
-    memset(_enableCounts, 0, eCountsSize);
-    
-    lockReporter();
-    for (cnt2 = 0; cnt2 < _channelDimension; cnt2++) {
-        IOHistogramReportValues hist_values;
-        if (copyElementValues(cnt2, (IOReportElementValues*)&hist_values)){
-            goto finish;
-        }
-        hist_values.bucket_min = kIOReportInvalidIntValue;
-        hist_values.bucket_max = kIOReportInvalidIntValue;
-        hist_values.bucket_sum = kIOReportInvalidIntValue;
-        if (setElementValues(cnt2, (IOReportElementValues*)&hist_values)){
-            goto finish;
-        }
-
-        // Setup IOReporter's channel IDs
-        _elements[cnt2].channel_id = channelID;
-        
-        // Setup IOReporter's reporting provider service
-        _elements[cnt2].provider_id = _driver_id;
-        
-        // Setup IOReporter's channel type
-        _elements[cnt2].channel_type = _channelType;
-        _elements[cnt2].channel_type.element_idx = cnt2;
-        
-        //IOREPORTER_DEBUG_ELEMENT(cnt2);
-    }
-    unlockReporter();
-    
-    // Allocate memory for the bucket upper bounds
-    PREFL_MEMOP_FAIL(_nElements, uint64_t);
-    boundsSize = (size_t)_nElements * sizeof(uint64_t);
-    _bucketBounds = (int64_t*)IOMalloc(boundsSize);
-    if (!_bucketBounds)         goto finish;
-    memset(_bucketBounds, 0, boundsSize);
-    _bucketCount = _nElements;
-
-    for (cnt = 0; cnt < _segmentCount; cnt++) {
-        
-        if (_histogramSegmentsConfig[cnt].segment_bucket_count > INT_MAX
-            || _histogramSegmentsConfig[cnt].base_bucket_width > INT_MAX) {
-            goto finish;
-        }
-        for (cnt2 = 0; cnt2 < (int)_histogramSegmentsConfig[cnt].segment_bucket_count; cnt2++) {
-            
-            if (cnt3 >= _nElements) {
-                IORLOG("ERROR: _bucketBounds init");
-                result = false;
-                goto finish;
-            }
-            
-            if (_histogramSegmentsConfig[cnt].scale_flag) {
-                // FIXME: Could use pow() but not sure how to include math.h
-                int64_t power = 1;
-                int exponent = cnt2 + 1;
-                while (exponent) {
-                    power *= _histogramSegmentsConfig[cnt].base_bucket_width;
-                    exponent--;
-                }
-                bucketBound = power;
-            }
-            
-            else {
-                bucketBound = _histogramSegmentsConfig[cnt].base_bucket_width *
-                                                    ((unsigned)cnt2 + 1);
-            }
-            
-            if (previousBucketBound >= bucketBound) {
-                IORLOG("Histogram ERROR: bucket bound does not increase linearly (segment %u / bucket # %u)",
-                       cnt, cnt2);
-                result = false;
-                goto finish;
-            }
-            
-            _bucketBounds[cnt3] = bucketBound;
-            // IORLOG("_bucketBounds[%u] = %llu", cnt3, bucketBound);
-            previousBucketBound = _bucketBounds[cnt3];
-            cnt3++;
-        }
-    }
-    
-    // success
-    result = true;
-    
+       bool            result = false;
+       IOReturn        res;    // for PREFL_MEMOP
+       size_t          configSize, elementsSize, eCountsSize, boundsSize;
+       int             cnt, cnt2, cnt3 = 0;
+       int64_t        bucketBound = 0, previousBucketBound = 0;
+
+       // analyzer appeasement
+       configSize = elementsSize = eCountsSize = boundsSize = 0;
+
+       IORLOG("IOHistogramReporter::initWith");
+
+       // For now, this reporter is currently limited to a single channel
+       _nChannels = 1;
+
+       IOReportChannelType channelType = {
+               .categories = categories,
+               .report_format = kIOReportFormatHistogram,
+               .nelements = 0, // Initialized when Config is unpacked
+               .element_idx = 0
+       };
+
+       if (super::init(reportingService, channelType, unit) != true) {
+               IORLOG("%s - ERROR: super::init failed", __func__);
+               result = false;
+               goto finish;
+       }
+
+       // Make sure to call this after the commit init phase
+       if (channelName) {
+               _channelNames->setObject(channelName);
+       }
+
+       _segmentCount = nSegments;
+       if (_segmentCount == 0) {
+               IORLOG("IOReportHistogram init ERROR. No configuration provided!");
+               result = false;
+               goto finish;
+       }
+
+       IORLOG("%s - %u segment(s)", __func__, _segmentCount);
+
+       PREFL_MEMOP_FAIL(_segmentCount, IOHistogramSegmentConfig);
+       configSize = (size_t)_segmentCount * sizeof(IOHistogramSegmentConfig);
+       _histogramSegmentsConfig = (IOHistogramSegmentConfig*)IOMalloc(configSize);
+       if (!_histogramSegmentsConfig) {
+               goto finish;
+       }
+       memcpy(_histogramSegmentsConfig, config, configSize);
+
+       // Find out how many elements are need to store the histogram
+       for (cnt = 0; cnt < _segmentCount; cnt++) {
+               _nElements += _histogramSegmentsConfig[cnt].segment_bucket_count;
+               _channelDimension += _histogramSegmentsConfig[cnt].segment_bucket_count;
+
+               IORLOG("\t\t bucket_base_width: %u | log_scale: %u | buckets: %u",
+                   _histogramSegmentsConfig[cnt].base_bucket_width,
+                   _histogramSegmentsConfig[cnt].scale_flag,
+                   _histogramSegmentsConfig[cnt].segment_bucket_count);
+
+               if (_histogramSegmentsConfig[cnt].scale_flag > 1
+                   || _histogramSegmentsConfig[cnt].base_bucket_width == 0) {
+                       result = false;
+                       goto finish;
+               }
+       }
+
+       // Update the channel type with discovered dimension
+       _channelType.nelements = _channelDimension;
+
+       IORLOG("%s - %u channel(s) of dimension %u",
+           __func__, _nChannels, _channelDimension);
+
+       IORLOG("%s %d segments for a total dimension of %d elements",
+           __func__, _nChannels, _nElements);
+
+       // Allocate memory for the array of report elements
+       PREFL_MEMOP_FAIL(_nElements, IOReportElement);
+       elementsSize = (size_t)_nElements * sizeof(IOReportElement);
+       _elements = (IOReportElement *)IOMalloc(elementsSize);
+       if (!_elements) {
+               goto finish;
+       }
+       memset(_elements, 0, elementsSize);
+
+       // Allocate memory for the array of element watch count
+       PREFL_MEMOP_FAIL(_nElements, int);
+       eCountsSize = (size_t)_nChannels * sizeof(int);
+       _enableCounts = (int *)IOMalloc(eCountsSize);
+       if (!_enableCounts) {
+               goto finish;
+       }
+       memset(_enableCounts, 0, eCountsSize);
+
+       lockReporter();
+       for (cnt2 = 0; cnt2 < _channelDimension; cnt2++) {
+               IOHistogramReportValues hist_values;
+               if (copyElementValues(cnt2, (IOReportElementValues*)&hist_values)) {
+                       goto finish;
+               }
+               hist_values.bucket_min = kIOReportInvalidIntValue;
+               hist_values.bucket_max = kIOReportInvalidIntValue;
+               hist_values.bucket_sum = kIOReportInvalidIntValue;
+               if (setElementValues(cnt2, (IOReportElementValues*)&hist_values)) {
+                       goto finish;
+               }
+
+               // Setup IOReporter's channel IDs
+               _elements[cnt2].channel_id = channelID;
+
+               // Setup IOReporter's reporting provider service
+               _elements[cnt2].provider_id = _driver_id;
+
+               // Setup IOReporter's channel type
+               _elements[cnt2].channel_type = _channelType;
+               _elements[cnt2].channel_type.element_idx = cnt2;
+
+               //IOREPORTER_DEBUG_ELEMENT(cnt2);
+       }
+       unlockReporter();
+
+       // Allocate memory for the bucket upper bounds
+       PREFL_MEMOP_FAIL(_nElements, uint64_t);
+       boundsSize = (size_t)_nElements * sizeof(uint64_t);
+       _bucketBounds = (int64_t*)IOMalloc(boundsSize);
+       if (!_bucketBounds) {
+               goto finish;
+       }
+       memset(_bucketBounds, 0, boundsSize);
+       _bucketCount = _nElements;
+
+       for (cnt = 0; cnt < _segmentCount; cnt++) {
+               if (_histogramSegmentsConfig[cnt].segment_bucket_count > INT_MAX
+                   || _histogramSegmentsConfig[cnt].base_bucket_width > INT_MAX) {
+                       goto finish;
+               }
+               for (cnt2 = 0; cnt2 < (int)_histogramSegmentsConfig[cnt].segment_bucket_count; cnt2++) {
+                       if (cnt3 >= _nElements) {
+                               IORLOG("ERROR: _bucketBounds init");
+                               result = false;
+                               goto finish;
+                       }
+
+                       if (_histogramSegmentsConfig[cnt].scale_flag) {
+                               // FIXME: Could use pow() but not sure how to include math.h
+                               int64_t power = 1;
+                               int exponent = cnt2 + 1;
+                               while (exponent) {
+                                       power *= _histogramSegmentsConfig[cnt].base_bucket_width;
+                                       exponent--;
+                               }
+                               bucketBound = power;
+                       } else {
+                               bucketBound = _histogramSegmentsConfig[cnt].base_bucket_width *
+                                   ((unsigned)cnt2 + 1);
+                       }
+
+                       if (previousBucketBound >= bucketBound) {
+                               IORLOG("Histogram ERROR: bucket bound does not increase linearly (segment %u / bucket # %u)",
+                                   cnt, cnt2);
+                               result = false;
+                               goto finish;
+                       }
+
+                       _bucketBounds[cnt3] = bucketBound;
+                       // IORLOG("_bucketBounds[%u] = %llu", cnt3, bucketBound);
+                       previousBucketBound = _bucketBounds[cnt3];
+                       cnt3++;
+               }
+       }
+
+       // success
+       result = true;
+
 finish:
-    return result;
+       return result;
 }
 
 
 void
 IOHistogramReporter::free(void)
 {
-    if (_bucketBounds) {
-        PREFL_MEMOP_PANIC(_nElements, int64_t);
-        IOFree(_bucketBounds, (size_t)_nElements * sizeof(int64_t));
-    }
-    if (_histogramSegmentsConfig) {
-        PREFL_MEMOP_PANIC(_segmentCount, IOHistogramSegmentConfig);
-        IOFree(_histogramSegmentsConfig,
-               (size_t)_segmentCount * sizeof(IOHistogramSegmentConfig));
-    }
-    
-    super::free();
+       if (_bucketBounds) {
+               PREFL_MEMOP_PANIC(_nElements, int64_t);
+               IOFree(_bucketBounds, (size_t)_nElements * sizeof(int64_t));
+       }
+       if (_histogramSegmentsConfig) {
+               PREFL_MEMOP_PANIC(_segmentCount, IOHistogramSegmentConfig);
+               IOFree(_histogramSegmentsConfig,
+                   (size_t)_segmentCount * sizeof(IOHistogramSegmentConfig));
+       }
+
+       super::free();
 }
 
 
 IOReportLegendEntry*
 IOHistogramReporter::handleCreateLegend(void)
 {
-    IOReportLegendEntry     *rval = NULL, *legendEntry = NULL;
-    OSData                  *tmpConfigData = NULL;
-    OSDictionary            *tmpDict;       // no refcount
-        
-    legendEntry = super::handleCreateLegend();
-    if (!legendEntry)       goto finish;
-    
-    PREFL_MEMOP_PANIC(_segmentCount, IOHistogramSegmentConfig);
-    tmpConfigData = OSData::withBytes(_histogramSegmentsConfig,
-                         (unsigned)_segmentCount *
-                             sizeof(IOHistogramSegmentConfig));
-    if (!tmpConfigData)         goto finish;
-
-    tmpDict = OSDynamicCast(OSDictionary,
-                    legendEntry->getObject(kIOReportLegendInfoKey));
-    if (!tmpDict)               goto finish;
-
-    tmpDict->setObject(kIOReportLegendConfigKey, tmpConfigData);
-
-    // success
-    rval = legendEntry;
+       IOReportLegendEntry     *rval = NULL, *legendEntry = NULL;
+       OSData                  *tmpConfigData = NULL;
+       OSDictionary            *tmpDict;   // no refcount
+
+       legendEntry = super::handleCreateLegend();
+       if (!legendEntry) {
+               goto finish;
+       }
+
+       PREFL_MEMOP_PANIC(_segmentCount, IOHistogramSegmentConfig);
+       tmpConfigData = OSData::withBytes(_histogramSegmentsConfig,
+           (unsigned)_segmentCount *
+           sizeof(IOHistogramSegmentConfig));
+       if (!tmpConfigData) {
+               goto finish;
+       }
+
+       tmpDict = OSDynamicCast(OSDictionary,
+           legendEntry->getObject(kIOReportLegendInfoKey));
+       if (!tmpDict) {
+               goto finish;
+       }
+
+       tmpDict->setObject(kIOReportLegendConfigKey, tmpConfigData);
+
+       // success
+       rval = legendEntry;
 
 finish:
-    if (tmpConfigData)  tmpConfigData->release();
-    if (!rval && legendEntry) {
-        legendEntry->release();
-    }
+       if (tmpConfigData) {
+               tmpConfigData->release();
+       }
+       if (!rval && legendEntry) {
+               legendEntry->release();
+       }
 
-    return rval;
+       return rval;
 }
 
 IOReturn
-IOHistogramReporter::overrideBucketValues(unsigned int index, 
-                                          uint64_t bucket_hits,
-                                          int64_t bucket_min,
-                                          int64_t bucket_max,
-                                          int64_t bucket_sum)
+IOHistogramReporter::overrideBucketValues(unsigned int index,
+    uint64_t bucket_hits,
+    int64_t bucket_min,
+    int64_t bucket_max,
+    int64_t bucket_sum)
 {
-    IOReturn result;
-    IOHistogramReportValues bucket;
-    lockReporter();
+       IOReturn result;
+       IOHistogramReportValues bucket;
+       lockReporter();
 
-    if (index >= (unsigned int)_bucketCount) {
-        result = kIOReturnBadArgument;
-        goto finish;
-    }
+       if (index >= (unsigned int)_bucketCount) {
+               result = kIOReturnBadArgument;
+               goto finish;
+       }
 
-    bucket.bucket_hits = bucket_hits;
-    bucket.bucket_min = bucket_min;
-    bucket.bucket_max = bucket_max;
-    bucket.bucket_sum = bucket_sum;
+       bucket.bucket_hits = bucket_hits;
+       bucket.bucket_min = bucket_min;
+       bucket.bucket_max = bucket_max;
+       bucket.bucket_sum = bucket_sum;
 
-    result = setElementValues(index, (IOReportElementValues *)&bucket);
+       result = setElementValues(index, (IOReportElementValues *)&bucket);
 finish:
-    unlockReporter();
-    return result;
+       unlockReporter();
+       return result;
 }
 
 int
 IOHistogramReporter::tallyValue(int64_t value)
 {
-    int result = -1;
-    int cnt = 0, element_index = 0;
-    IOHistogramReportValues hist_values;
-    
-    lockReporter();
-    
-    // Iterate over _bucketCount minus one to make last bucket of infinite width
-    for (cnt = 0; cnt < _bucketCount - 1; cnt++) {
-        if (value <= _bucketBounds[cnt]) break;
-    }
-    
-    element_index = cnt;
-    
-    if (copyElementValues(element_index, (IOReportElementValues *)&hist_values) != kIOReturnSuccess) {
-        goto finish;
-    }
-    
-    // init stats on first hit
-    if (hist_values.bucket_hits == 0) {
-        hist_values.bucket_min = hist_values.bucket_max = value;
-        hist_values.bucket_sum = 0;     // += is below
-    }
-
-    // update all values
-    if (value < hist_values.bucket_min) {
-        hist_values.bucket_min = value;
-    } else if (value > hist_values.bucket_max) {
-        hist_values.bucket_max = value;
-    }
-    hist_values.bucket_sum += value;
-    hist_values.bucket_hits++;
-    
-    if (setElementValues(element_index, (IOReportElementValues *)&hist_values)
-                != kIOReturnSuccess) {
-        goto finish;
-    }
-
-    // success!
-    result = element_index;
-    
+       int result = -1;
+       int cnt = 0, element_index = 0;
+       IOHistogramReportValues hist_values;
+
+       lockReporter();
+
+       // Iterate over _bucketCount minus one to make last bucket of infinite width
+       for (cnt = 0; cnt < _bucketCount - 1; cnt++) {
+               if (value <= _bucketBounds[cnt]) {
+                       break;
+               }
+       }
+
+       element_index = cnt;
+
+       if (copyElementValues(element_index, (IOReportElementValues *)&hist_values) != kIOReturnSuccess) {
+               goto finish;
+       }
+
+       // init stats on first hit
+       if (hist_values.bucket_hits == 0) {
+               hist_values.bucket_min = hist_values.bucket_max = value;
+               hist_values.bucket_sum = 0; // += is below
+       }
+
+       // update all values
+       if (value < hist_values.bucket_min) {
+               hist_values.bucket_min = value;
+       } else if (value > hist_values.bucket_max) {
+               hist_values.bucket_max = value;
+       }
+       hist_values.bucket_sum += value;
+       hist_values.bucket_hits++;
+
+       if (setElementValues(element_index, (IOReportElementValues *)&hist_values)
+           != kIOReturnSuccess) {
+               goto finish;
+       }
+
+       // success!
+       result = element_index;
+
 finish:
-    unlockReporter();
-    return result;
+       unlockReporter();
+       return result;
 }