]> git.ipfire.org Git - people/ms/pakfire.git/blob - src/_pakfire/util.c
Performance check: Count iterations as unsigned long
[people/ms/pakfire.git] / src / _pakfire / util.c
1 /*#############################################################################
2 # #
3 # Pakfire - The IPFire package management system #
4 # Copyright (C) 2011 Pakfire development team #
5 # #
6 # This program is free software: you can redistribute it and/or modify #
7 # it under the terms of the GNU General Public License as published by #
8 # the Free Software Foundation, either version 3 of the License, or #
9 # (at your option) any later version. #
10 # #
11 # This program is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
15 # #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
18 # #
19 #############################################################################*/
20
21 #include <Python.h>
22
23 #include <errno.h>
24 #include <sched.h>
25 #include <sys/personality.h>
26 #include <time.h>
27 #include <unistd.h>
28
29 #include "constants.h"
30 #include "util.h"
31
32 PyObject *_personality(PyObject *self, PyObject *args) {
33 unsigned long persona;
34 int ret = 0;
35
36 if (!PyArg_ParseTuple(args, "l", &persona)) {
37 /* XXX raise exception */
38 return NULL;
39 }
40
41 /* Change personality here. */
42 ret = personality(persona);
43
44 if (ret < 0) {
45 PyErr_SetString(PyExc_RuntimeError, "Could not set personality.");
46 return NULL;
47 }
48
49 return Py_BuildValue("i", ret);
50 }
51
52 PyObject *_sync(PyObject *self, PyObject *args) {
53 /* Just sync everything to disks. */
54 sync();
55
56 Py_RETURN_NONE;
57 }
58
59 PyObject *_unshare(PyObject *self, PyObject *args) {
60 int flags = 0;
61
62 if (!PyArg_ParseTuple(args, "i", &flags)) {
63 return NULL;
64 }
65
66 int ret = unshare(flags);
67 if (ret < 0) {
68 return PyErr_SetFromErrno(PyExc_RuntimeError);
69 }
70
71 return Py_BuildValue("i", ret);
72 }
73
74 PyObject *version_compare(PyObject *self, PyObject *args) {
75 Pool *pool;
76 const char *evr1, *evr2;
77
78 if (!PyArg_ParseTuple(args, "Oss", &pool, &evr1, &evr2)) {
79 /* XXX raise exception */
80 return NULL;
81 }
82
83 int ret = pool_evrcmp_str(pool, evr1, evr2, EVRCMP_COMPARE);
84
85 return Py_BuildValue("i", ret);
86 }
87
88 static unsigned long fibonnacci(const clock_t* deadline) {
89 clock_t now = clock();
90
91 unsigned long f1 = 1;
92 unsigned long f2 = 1;
93
94 // Count iterations
95 unsigned long counter = 0;
96
97 while (now < *deadline) {
98 unsigned long next = f1 + f2;
99 f1 = f2;
100 f2 = next;
101
102 now = clock();
103 counter++;
104 }
105
106 return counter;
107 }
108
109 PyObject* performance_index(PyObject* self, PyObject* args) {
110 int seconds = 1;
111
112 if (!PyArg_ParseTuple(args, "|i", &seconds)) {
113 return NULL;
114 }
115
116 if (seconds == 0) {
117 PyErr_SetString(PyExc_ValueError, "Runtime must be one second or longer");
118 return NULL;
119 }
120
121 // Determine the number of online processors
122 int processors = sysconf(_SC_NPROCESSORS_ONLN);
123
124 // Determine deadline
125 clock_t deadline = clock();
126 deadline += CLOCKS_PER_SEC * seconds;
127
128 // Run Fibonnacci until deadline
129 unsigned long iterations = fibonnacci(&deadline);
130
131 // Times the result by the number of processors
132 iterations *= processors;
133
134 // Normalise to a second
135 iterations /= seconds;
136
137 return PyLong_FromUnsignedLong(iterations);
138 }