-
Notifications
You must be signed in to change notification settings - Fork 0
/
msieve.c
196 lines (158 loc) · 4.99 KB
/
msieve.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/**
* Emscripten interface for msieve.
* Based on `demo.c` provided with the official source distribution.
*/
#include <msieve.h>
#include <signal.h>
// progress callback
extern void publishFactor(uint factor_type, char *factor_number);
msieve_obj *g_curr_factorization = NULL;
/*--------------------------------------------------------------------*/
void handle_signal(int sig) {
msieve_obj *obj = g_curr_factorization;
printf("\nreceived signal %d; shutting down\n", sig);
if (obj && (obj->flags & MSIEVE_FLAG_SIEVING_IN_PROGRESS))
obj->flags |= MSIEVE_FLAG_STOP_SIEVING;
else
_exit(0);
}
/*--------------------------------------------------------------------*/
void get_random_seeds(uint32 *seed1, uint32 *seed2) {
uint32 tmp_seed1, tmp_seed2;
/* In a multithreaded program, every msieve object
* should have two unique, non-correlated seeds
* chosen for it */
/* Sample the current time, the high-res timer
* (hopefully not correlated to the current time),
* and the process ID. Multithreaded applications
* should fold in the thread ID too */
uint64 high_res_time = read_clock();
tmp_seed1 = ((uint32)(high_res_time >> 32) ^ (uint32)time(NULL)) * (uint32)getpid();
tmp_seed2 = (uint32)high_res_time;
/* The final seeds are the result of a multiplicative
* hash of the initial seeds */
(*seed1) = tmp_seed1 * ((uint32)40499 * 65543);
(*seed2) = tmp_seed2 * ((uint32)40499 * 65543);
}
/*--------------------------------------------------------------------*/
void factor_integer(char *buf, uint32 flags,
char *savefile_name,
char *logfile_name,
char *nfs_fbfile_name,
uint32 *seed1, uint32 *seed2,
uint32 max_relations,
enum cpu_type cpu,
uint32 cache_size1,
uint32 cache_size2,
uint32 num_threads,
uint32 which_gpu,
const char *nfs_args) {
char *int_start, *last;
msieve_obj *obj;
msieve_factor *factor;
/* point to the start of the integer or expression;
* if the start point indicates no integer is present,
* don't try to factor it :) */
last = strchr(buf, '\n');
if (last)
*last = 0;
int_start = buf;
while (*int_start && !isdigit(*int_start) && *int_start != '(') {
int_start++;
}
if (*int_start == 0)
return;
g_curr_factorization = msieve_obj_new(int_start, flags,
savefile_name, logfile_name,
nfs_fbfile_name,
*seed1, *seed2, max_relations,
cpu, cache_size1, cache_size2,
num_threads, which_gpu,
nfs_args);
if (g_curr_factorization == NULL) {
fprintf(stderr, "factoring initialization failed\n");
return;
}
msieve_run(g_curr_factorization);
if (!(g_curr_factorization->flags & MSIEVE_FLAG_FACTORIZATION_DONE)) {
fprintf(stderr, "\ncurrent factorization was interrupted\n");
exit(0);
}
/* Print out the factors that were found */
factor = g_curr_factorization->factors;
printf("\n");
printf("%s\n", buf);
while (factor != NULL) {
char *factor_type;
if (factor->factor_type == MSIEVE_PRIME)
factor_type = "p";
else if (factor->factor_type == MSIEVE_COMPOSITE)
factor_type = "c";
else
factor_type = "prp";
publishFactor(factor->factor_type, factor->number);
printf("%s%d: %s\n", factor_type,
(int32)strlen(factor->number),
factor->number);
factor = factor->next;
}
printf("\n");
/* save the current value of the random seeds, so that
* the next factorization will pick up the pseudorandom
* sequence where this factorization left off */
*seed1 = g_curr_factorization->seed1;
*seed2 = g_curr_factorization->seed2;
/* free the current factorization struct. The following
* avoids a race condition in the signal handler */
obj = g_curr_factorization;
g_curr_factorization = NULL;
if (obj)
msieve_obj_free(obj);
}
/*--------------------------------------------------------------------*/
/** Main(): factorize by sieving */
int sieve(char *input) {
char *buf = input;
uint32 seed1, seed2;
char *savefile_name = NULL;
char *logfile_name = NULL;
char *nfs_fbfile_name = NULL;
uint32 flags = MSIEVE_FLAG_USE_LOGFILE;
uint32 max_relations = 0; // CONST
enum cpu_type cpu;
uint32 cache_size1;
uint32 cache_size2;
uint32 num_threads = 0; // CONST
uint32 which_gpu = 0; // CONST (CUDA only)
const char *nfs_args = NULL; // CONST
if (!(isdigit(buf[0]) || buf[0] == '(' )) {
fprintf(stderr, "cannot parse input '%s'\n", buf);
return -1;
}
get_cache_sizes(&cache_size1, &cache_size2);
cpu = get_cpu_type();
if (signal(SIGINT, handle_signal) == SIG_ERR) {
fprintf(stderr, "could not install handler on SIGINT\n");
return -1;
}
if (signal(SIGTERM, handle_signal) == SIG_ERR) {
fprintf(stderr, "could not install handler on SIGTERM\n");
return -1;
}
get_random_seeds(&seed1, &seed2);
factor_integer(buf, flags, savefile_name,
logfile_name, nfs_fbfile_name,
&seed1, &seed2,
max_relations,
cpu, cache_size1, cache_size2,
num_threads, which_gpu,
nfs_args);
return 0;
}
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "usage: %s EXPRESSION\n", argv[0]);
return -1;
}
return sieve(argv[1]);
}