|
|
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.