|
|
1.1 ! root 1: /* $Id: runlength.c,v 1.1 2010/02/07 14:07:25 fredette Exp $ */ ! 2: ! 3: /* libtme/runlength.c - run length: */ ! 4: ! 5: /* ! 6: * Copyright (c) 2010 Matt Fredette ! 7: * All rights reserved. ! 8: * ! 9: * Redistribution and use in source and binary forms, with or without ! 10: * modification, are permitted provided that the following conditions ! 11: * are met: ! 12: * 1. Redistributions of source code must retain the above copyright ! 13: * notice, this list of conditions and the following disclaimer. ! 14: * 2. Redistributions in binary form must reproduce the above copyright ! 15: * notice, this list of conditions and the following disclaimer in the ! 16: * documentation and/or other materials provided with the distribution. ! 17: * 3. All advertising materials mentioning features or use of this software ! 18: * must display the following acknowledgement: ! 19: * This product includes software developed by Matt Fredette. ! 20: * 4. The name of the author may not be used to endorse or promote products ! 21: * derived from this software without specific prior written permission. ! 22: * ! 23: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ! 24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ! 25: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ! 26: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, ! 27: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ! 28: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ! 29: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ! 31: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ! 32: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ! 33: * POSSIBILITY OF SUCH DAMAGE. ! 34: */ ! 35: ! 36: #include <tme/common.h> ! 37: _TME_RCSID("$Id: runlength.c,v 1.1 2010/02/07 14:07:25 fredette Exp $"); ! 38: ! 39: /* includes: */ ! 40: #include <tme/runlength.h> ! 41: #include <tme/misc.h> ! 42: ! 43: /* this initializes runlength state: */ ! 44: void ! 45: tme_runlength_init(struct tme_runlength *runlength) ! 46: { ! 47: unsigned long runlength_history_count; ! 48: tme_runlength_t runlength_value; ! 49: ! 50: /* allocate the runlength history: */ ! 51: runlength_history_count = runlength->tme_runlength_history_count; ! 52: assert (runlength_history_count > 0); ! 53: runlength->_tme_runlength_history = tme_new(tme_runlength_t, runlength_history_count); ! 54: ! 55: /* set the initial runlength history sum: */ ! 56: runlength_value = runlength->tme_runlength_value; ! 57: runlength->_tme_runlength_history_sum ! 58: = (((double) runlength_value) ! 59: * runlength->tme_runlength_history_count); ! 60: ! 61: /* initialize the runlength history: */ ! 62: do { ! 63: runlength->_tme_runlength_history[runlength_history_count - 1] = runlength_value; ! 64: } while (--runlength_history_count); ! 65: runlength->_tme_runlength_history_next = 0; ! 66: } ! 67: ! 68: /* this sets the runlength cycles target: */ ! 69: void ! 70: tme_runlength_target_cycles(struct tme_runlength *runlength, ! 71: union tme_value64 cycles_elapsed_target_value64) ! 72: { ! 73: double two_to_the_thirtysecond; ! 74: ! 75: /* make 2^32: */ ! 76: two_to_the_thirtysecond = 65536 * (double) 65536; ! 77: ! 78: /* set the target number of cycles to elapse during a run: */ ! 79: runlength->_tme_runlength_cycles_elapsed_target ! 80: = ((cycles_elapsed_target_value64.tme_value64_uint32_hi ! 81: * two_to_the_thirtysecond) ! 82: + cycles_elapsed_target_value64.tme_value64_uint32_lo); ! 83: } ! 84: ! 85: /* this updates the runlength: */ ! 86: void ! 87: tme_runlength_update(struct tme_runlength *runlength) ! 88: { ! 89: double two_to_the_thirtysecond; ! 90: union tme_value64 cycles_elapsed; ! 91: tme_runlength_t runlength_value; ! 92: unsigned long runlength_history_next; ! 93: double runlength_history_sum; ! 94: ! 95: /* make 2^32: */ ! 96: two_to_the_thirtysecond = 65536 * (double) 65536; ! 97: ! 98: /* get the number of cycles that elapsed during this run: */ ! 99: cycles_elapsed = tme_misc_cycles(); ! 100: (void) tme_value64_sub(&cycles_elapsed, &runlength->tme_runlength_cycles_start); ! 101: ! 102: /* get a better length for this run: */ ! 103: runlength_value ! 104: = (runlength->tme_runlength_value ! 105: * (runlength->_tme_runlength_cycles_elapsed_target ! 106: / ((cycles_elapsed.tme_value64_uint32_hi ! 107: * two_to_the_thirtysecond) ! 108: + cycles_elapsed.tme_value64_uint32_lo))); ! 109: if (__tme_predict_false(runlength_value == 0)) { ! 110: runlength_value += 1; ! 111: } ! 112: ! 113: /* update the runlength history and sum: */ ! 114: runlength_history_next = runlength->_tme_runlength_history_next; ! 115: runlength_history_sum ! 116: = ((runlength->_tme_runlength_history_sum ! 117: - runlength->_tme_runlength_history[runlength_history_next]) ! 118: + runlength_value); ! 119: runlength->_tme_runlength_history[runlength_history_next] = runlength_value; ! 120: runlength->_tme_runlength_history_sum = runlength_history_sum; ! 121: if (runlength_history_next == 0) { ! 122: runlength_history_next = runlength->tme_runlength_history_count; ! 123: } ! 124: runlength->_tme_runlength_history_next = runlength_history_next - 1; ! 125: ! 126: /* update the runlength value: */ ! 127: runlength->tme_runlength_value ! 128: = (runlength_history_sum ! 129: / runlength->tme_runlength_history_count); ! 130: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.