Update copyright notice to LGPL
[dyninst.git] / common / src / linuxKludges.C
1 /*
2  * Copyright (c) 1996-2007 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
30  */
31
32 #include "common/h/headers.h"
33
34 typedef int (*intKludge)();
35
36 int P_getopt(int argc, char *argv[], const char *optstring)
37 {
38   /* On linux we prepend a + character */
39   char newopt[strlen(optstring)+5];
40   strcpy(newopt, "+");
41   strcat(newopt, optstring);
42   return getopt(argc, argv, newopt);
43 }
44
45 int P_copy(const char *from, const char *to) {
46     int from_fd = P_open(from, O_RDONLY, 0);
47     if (from_fd == -1)  {
48         perror("Opening from file in copy"); 
49         return -1;
50     }
51     int to_fd = P_open(to, O_WRONLY | O_APPEND | O_CREAT | O_TRUNC, 0);
52     if (to_fd == -1) {
53         perror("Opening to file in copy");
54         close(from_fd);
55         return -1;
56     }
57
58     char buffer[1048576];
59     while(true) {
60         int amount = read(from_fd, buffer, 1048576);
61         if (amount == -1) {
62             perror("Reading in file copy");
63             return -1;
64         }
65         write(to_fd, buffer, amount);
66         if (amount < 1048576) break;
67     }
68     close(to_fd);
69     close(from_fd);
70     return 0;
71 }
72
73
74 unsigned long long PDYN_div1000(unsigned long long in) {
75    /* Divides by 1000 without an integer division instruction or library call, both of
76     * which are slow.
77     * We do only shifts, adds, and subtracts.
78     *
79     * We divide by 1000 in this way:
80     * multiply by 1/1000, or multiply by (1/1000)*2^30 and then right-shift by 30.
81     * So what is 1/1000 * 2^30?
82     * It is 1,073,742.   (actually this is rounded)
83     * So we can multiply by 1,073,742 and then right-shift by 30 (neat, eh?)
84     *
85     * Now for multiplying by 1,073,742...
86     * 1,073,742 = (1,048,576 + 16384 + 8192 + 512 + 64 + 8 + 4 + 2)
87     * or, slightly optimized:
88     * = (1,048,576 + 16384 + 8192 + 512 + 64 + 16 - 2)
89     * for a total of 8 shifts and 6 add/subs, or 14 operations.
90     *
91     */
92
93    unsigned long long temp = in << 20; // multiply by 1,048,576
94       // beware of overflow; left shift by 20 is quite a lot.
95       // If you know that the input fits in 32 bits (4 billion) then
96       // no problem.  But if it's much bigger then start worrying...
97
98    temp += in << 14; // 16384
99    temp += in << 13; // 8192
100    temp += in << 9;  // 512
101    temp += in << 6;  // 64
102    temp += in << 4;  // 16
103    temp -= in >> 2;  // 2
104
105    return (temp >> 30); // divide by 2^30
106 }
107
108 unsigned long long PDYN_divMillion(unsigned long long in) {
109    /* Divides by 1,000,000 without an integer division instruction or library call,
110     * both of which are slow.
111     * We do only shifts, adds, and subtracts.
112     *
113     * We divide by 1,000,000 in this way:
114     * multiply by 1/1,000,000, or multiply by (1/1,000,000)*2^30 and then right-shift
115     * by 30.  So what is 1/1,000,000 * 2^30?
116     * It is 1,074.   (actually this is rounded)
117     * So we can multiply by 1,074 and then right-shift by 30 (neat, eh?)
118     *
119     * Now for multiplying by 1,074
120     * 1,074 = (1024 + 32 + 16 + 2)
121     * for a total of 4 shifts and 4 add/subs, or 8 operations.
122     *
123     * Note: compare with div1000 -- it's cheaper to divide by a million than
124     *       by a thousand (!)
125     *
126     */
127
128    unsigned long long temp = in << 10; // multiply by 1024
129       // beware of overflow...if the input arg uses more than 52 bits
130       // than start worrying about whether (in << 10) plus the smaller additions
131       // we're gonna do next will fit in 64...
132
133    temp += in << 5; // 32
134    temp += in << 4; // 16
135    temp += in << 1; // 2
136
137    return (temp >> 30); // divide by 2^30
138 }
139
140 unsigned long long PDYN_mulMillion(unsigned long long in) {
141    unsigned long long result = in;
142
143    /* multiply by 125 by multiplying by 128 and subtracting 3x */
144    result = (result << 7) - result - result - result;
145
146    /* multiply by 125 again, for a total of 15625x */
147    result = (result << 7) - result - result - result;
148
149    /* multiply by 64, for a total of 1,000,000x */
150    result <<= 6;
151
152    /* cost was: 3 shifts and 6 subtracts
153     * cost of calling mul1000(mul1000()) would be: 6 shifts and 4 subtracts
154     *
155     * Another algorithm is to multiply by 2^6 and then 5^6.
156     * The former is super-cheap (one shift); the latter is more expensive.
157     * 5^6 = 15625 = 16384 - 512 - 256 + 8 + 1
158     * so multiplying by 5^6 means 4 shift operations and 4 add/sub ops
159     * so multiplying by 1000000 means 5 shift operations and 4 add/sub ops.
160     * That may or may not be cheaper than what we're doing (3 shifts; 6 subtracts);
161     * I'm not sure.  --ari
162     */
163
164    return result;
165 }