Commit 2358056606a51bacff895ec5db14e7afda0696a6

Kano 2011-11-23T14:35:49

API v0.1

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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
diff --git a/AUTHORS b/AUTHORS
index 51b7424..4ad7542 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,2 +1,3 @@
 Original CPU mining software: Jeff Garzik <jgarzik@pobox.com>
 GPU mining and rewrite: Con Kolivas <kernel@kolivas.org> 15qSxP1SQcUX3o4nhkfdbgyoWEFMomJ4rZ
+API+: Kano <kanoi@kano-kun.net> 1Jjk2LmktEQKnv8r2cZ9MvLiZwZ9gxabKm
diff --git a/Makefile.am b/Makefile.am
index 6f96290..3e691f0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -27,7 +27,7 @@ cgminer_SOURCES	= elist.h miner.h compat.h bench_block.h	\
 		  sha256_altivec_4way.c				\
 		  adl.c	adl.h adl_functions.h			\
 		  phatk110817.cl poclbm110817.cl \
-		  sha2.c sha2.h
+		  sha2.c sha2.h api.c
 
 cgminer_LDFLAGS	= $(PTHREAD_FLAGS)
 cgminer_LDADD	= $(DLOPEN_FLAGS) @LIBCURL_LIBS@ @JANSSON_LIBS@ @PTHREAD_LIBS@ @OPENCL_LIBS@ @NCURSES_LIBS@ @PDCURSES_LIBS@ @WS2_LIBS@ lib/libgnu.a ccan/libccan.a
diff --git a/api.c b/api.c
index 1f7dd81..e16f2e5 100644
--- a/api.c
+++ b/api.c
@@ -34,29 +34,38 @@
 //	#include <sys/wait.h>
 #endif
 
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
 // Big enough for largest API request
 //  though a PC with 100s of CPUs may exceed the size ...
 // Current code assumes it can socket send this size also
 #define MYBUFSIZ	16384
 
+// Socket is on 127.0.0.1
+#define QUEUE	10
+
 static char *buffer = NULL;
 
 static const char *UNAVAILABLE = " - API will not be available";
 
 static const char *BLANK = "";
 
-static const char *VERSION = "0.1";
+static const char *APIVERSION = "0.1";
 static const char *DEAD = "DEAD";
 static const char *SICK = "SICK";
 static const char *DISABLED = "DISABLED";
-static const char * = "";
-zzz -> other pool status
+static const char *ALIVE = "ALIVE";
+
+static const char *YES = "Y";
+static const char *NO = "N";
 
 static int bye = 0;
 
 char *apiversion(char *params)
 {
-	return VERSION;
+	return (char *)APIVERSION;
 }
 
 void gpustatus(int thr_id)
@@ -68,7 +77,7 @@ void gpustatus(int thr_id)
 	int gf, gp;
 
 	if (thr_id >= 0 && thr_id < gpu_threads) {
-		int gpu = dev_from_id(thr_id);
+		int gpu = thr_info[thr_id].cgpu->cpu_gpu;
 		struct cgpu_info *cgpu = &gpus[gpu];
 
 		cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60;
@@ -84,21 +93,21 @@ void gpustatus(int thr_id)
 		gt = gf = gp = 0;
 
 		if (cgpu->status == LIFE_DEAD)
-			status = DEAD;
+			status = (char *)DEAD;
 		else if (cgpu->status == LIFE_SICK)
-			status = SICK;
+			status = (char *)SICK;
 		else if (!gpu_devices[gpu])
-			status = DISABLED;
+			status = (char *)DISABLED;
 		else {
 			sprintf(status_buf, "%.1f", cgpu->rolling);
 			status = status_buf;
 		}
 
-		sprintf(buf, "G%d=%.2f,%d,%d,%s,%.2f,%d,%d,%d,%.2f,%d|",
+		sprintf(buf, "GPU=%d,GT=%.2f,FR=%d,FP=%d,STA=%s,MHS=%.2f,A=%d,R=%d,HW=%d,U=%.2f,I=%d|",
 			gpu, gt, gf, gp, status,
 			cgpu->total_mhashes / total_secs,
 			cgpu->accepted, cgpu->rejected, cgpu->hw_errors,
-			cgpu->utility, gpus[gpu].intensity);
+			cgpu->utility, gpus->intensity);
 
 		strcat(buffer, buf);
 	}
@@ -109,16 +118,16 @@ void cpustatus(int thr_id)
 	char buf[BUFSIZ];
 
 	if (thr_id >= gpu_threads) {
-		int cpu = dev_from_id(thr_id);
+		int cpu = thr_info[thr_id].cgpu->cpu_gpu;
 		struct cgpu_info *cgpu = &cpus[cpu];
 
 		cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60;
 
-		sprintf(buf, "C%d=%.2f,%.2f,%d,%d,%d,%.2f,%d|",
+		sprintf(buf, "CPU=%d,STA=%.2f,MHS=%.2f,A=%d,R=%d,U=%.2f|",
 			cpu, cgpu->rolling,
 			cgpu->total_mhashes / total_secs,
-			cgpu->accepted, cgpu->rejected, cgpu->hw_errors,
-			cgpu->utility, gpus[gpu].intensity);
+			cgpu->accepted, cgpu->rejected,
+			cgpu->utility);
 
 		strcat(buffer, buf);
 	}
@@ -142,7 +151,7 @@ char *devstatus(char *params)
 char *poolstatus(char *params)
 {
 	char buf[BUFSIZ];
-	char *status;
+	char *status, *lp;
 	int i;
 
 	*buffer = '\0';
@@ -151,12 +160,22 @@ char *poolstatus(char *params)
 		struct pool *pool = pools[i];
 
 		if (!pool->enabled)
-			status = DISABLED;
+			status = (char *)DISABLED;
 		else
-			status = OK;
+		{
+			if (pool->idle)
+				status = (char *)DEAD;
+			else
+				status = (char *)ALIVE;
+		}
 
-		sprintf(buf, "P%d=%s,%s,%d,%d,%d,%d,%d,%d,%d|",
-			i, pool->rpc_url, status,
+		if (pool->hdr_path)
+			lp = (char *)YES;
+		else
+			lp = (char *)NO;
+
+		sprintf(buf, "POOL=%d,URL=%s,STA=%s,PRI=%d,LP=%s,Q=%d,A=%d,R=%d,DW=%d,ST=%d,GF=%d,RF=%d|",
+			i, pool->rpc_url, status, pool->prio, lp,
 			pool->getwork_requested,
 			pool->accepted, pool->rejected,
 			pool->discarded_work,
@@ -171,31 +190,33 @@ char *poolstatus(char *params)
 }
 
 struct CMDS {
-	const char *cmd;
-	char (*func)();
+	char *name;
+	char *(*func)(char *);
 } cmds[] = {
 	{ "apiversion",	apiversion },
 	{ "dev",	devstatus },
-	{ "pool",	poolstatus }
+	{ "pool",	poolstatus },
 };
 
-#define MAXCMD sizeof(cmds)/sizeof(struct CMDS)
+#define CMDMAX 3
 
 void send_result(int c, char *result)
 {
 	int n;
 
 	if (result == NULL)
-		result = BLANK;
+		result = (char *)BLANK;
 
 	// ignore failure - it's closed immediately anyway
 	n = write(c, result, strlen(result)+1);
 }
 
-static void api()
+void api()
 {
+	char buf[BUFSIZ];
 	const char *addr;
 	int c, sock, n, bound;
+	char tmpaddr[32];
 	char *binderror;
 	time_t bindstart;
 	short int port = 4028;
@@ -205,13 +226,14 @@ static void api()
 	long long counter;
 	char *result;
 	char *params;
+	int i;
 
 	addr = "127.0.0.1";
 
 	sock = socket(AF_INET, SOCK_STREAM, 0);
 	if (sock < 0) {
 		applog(LOG_ERR, "API1 initialisation failed (%s)%s", strerror(errno), UNAVAILABLE);
-		return NULL;
+		return;
 	}
 
 	memset(&serv, 0, sizeof(serv));
@@ -219,7 +241,7 @@ static void api()
 	serv.sin_family = AF_INET;
 	if (inet_pton(AF_INET, addr, &(serv.sin_addr)) == 0) {
 		applog(LOG_ERR, "API2 initialisation failed (%s)%s", strerror(errno), UNAVAILABLE);
-		return NULL;
+		return;
 	}
 	serv.sin_port = htons(port);
 
@@ -232,8 +254,8 @@ static void api()
 			if ((time(NULL) - bindstart) > 61)
 				break;
 			else {
-				applog(LOG_ERR, "API bind to port %d failed - trying again in 10sec", port);
-				sleep(10);
+				applog(LOG_ERR, "API bind to port %d failed - trying again in 15sec", port);
+				sleep(15);
 			}
 		}
 		else
@@ -242,13 +264,13 @@ static void api()
 
 	if (bound == 0) {
 		applog(LOG_ERR, "API bind to port %d failed (%s)%s", port, binderror, UNAVAILABLE);
-		return NULL;
+		return;
 	}
 
 	if (listen(sock, QUEUE) < 0) {
 		applog(LOG_ERR, "API3 initialisation failed (%s)%s", strerror(errno), UNAVAILABLE);
 		close(sock);
-		return NULL;
+		return;
 	}
 
 	buffer = malloc(MYBUFSIZ+1);
@@ -262,24 +284,25 @@ static void api()
 			applog(LOG_ERR, "API failed (%s)%s", strerror(errno), UNAVAILABLE);
 			close(sock);
 			free(buffer);
-			return NULL;
+			return;
 		}
 
 		inet_ntop(AF_INET, &(cli.sin_addr), &(tmpaddr[0]), sizeof(tmpaddr)-1);
 		if (strcmp(tmpaddr, addr) != 0)
 			close(c);
 		else {
-			n = read(c, &buf[0], BUFS);
+			n = read(c, &buf[0], BUFSIZ-1);
 			if (n < 0)
 				close(c);
 			else {
+				buf[n] = '\0';
 				params = strchr(buf, '|');
 				if (params != NULL)
 					*(params++) = '\0';
 
 				for (i = 0; i < CMDMAX; i++) {
 					if (strcmp(buf, cmds[i].name) == 0) {
-						result = cmds[i].func(params);
+						result = (cmds[i].func)(params);
 						send_result(c, result);
 						close(c);
 						break;
@@ -291,6 +314,4 @@ static void api()
 
 	close(sock);
 	free(buffer);
-
-	return NULL;
 }
diff --git a/linux-usb-cgminer b/linux-usb-cgminer
index 3e3091d..a529263 100644
--- a/linux-usb-cgminer
+++ b/linux-usb-cgminer
@@ -1,22 +1,35 @@
-How to setup a cgminer using xubuntu 11.04 live on a USB courtesy of Kano
+How to setup a cgminer using xubuntu 11.04 live on a USB
+
+The master version of this document is here:
+ https://github.com/kanoi/linux-usb-cgminer
+
+The actual file is:
+ https://github.com/kanoi/linux-usb-cgminer/blob/master/linux-usb-cgminer
+
+The copy in cgminer (check to make sure it isn't older) is:
+ https://github.com/ckolivas/cgminer/blob/master/linux-usb-cgminer
+
+The original old verion on bitcointalk is:
+ https://bitcointalk.org/index.php?topic=28402.msg426741#msg426741
 
 Software
 ========
 Short hardware comment:
 Your mining computer doesn't need any HDD or CD/DVD/BD as long as it has at
-least 2GB of RAM, can boot USB, has some network connection to the internet and
-of course a reasonable mining ATI graphics card
+least 2GB of RAM, can boot USB, has some network connection to the internet
+and of course a reasonable mining ATI graphics card
 ... Or you can boot a windows PC with the USB to only do mining ... and ignore
-the system HDD ... wasting energy Smiley
+the system HDD ... wasting energy running the HDD :)
 
-To create the USB, you need of course a 4GB USB and temporarily need a PC with a
-CD (or DVD/BD) writer, a USB port and of course an internet connection to the PC
+To create the USB, you need of course a 4GB USB and temporarily need a PC
+with a CD (or DVD/BD) writer, a USB port and of course an internet
+connection to the PC
 
 1) Download the xubuntu 11.04 desktop live CD iso for amd64
    ( look here for mirrors: http://www.xubuntu.org/getubuntu )
 
-2) Burn it to CD then boot that temporarily on any PC with a CD/DVD/BD and a USB
-   port (this and the next 2 step won't effect that PC)
+2) Burn it to CD then boot that temporarily on any PC with a CD/DVD/BD and
+   a USB port (this and the next 2 step won't effect that PC)
 
 3) Plug in your 4GB USB device and it should appear on the desktop - you can
    leave it's contents as long as there is at least 2.8GB free
@@ -24,8 +37,8 @@ CD (or DVD/BD) writer, a USB port and of course an internet connection to the PC
 4) Now run "Startup Disk Creator" in "Applications->System"
    (the system menu is the little rat in the top left corner)
 
-(if you have no mouse you can get the menu with <ctr><esc> and navigate the menu
-with the arrow keys and <return> key)
+(if you have no mouse you can get the menu with <ctr><esc> and navigate
+the menu with the arrow keys and <return> key)
 
 From here select the boot CD as the "Source" and the USB as the "Disk to use"
 lastly move the slider to 2GB for reserved extra space
@@ -46,21 +59,21 @@ After about 10-15 minutes you have a base xubuntu 11.04 boot USB
 7) sudo apt-get install openssh-server screen
 
    if you have a problem here then it's probably coz the internet isn't
-available ... sort that   out by reading elsewhere about routers etc
+   available ... sort that out by reading elsewhere about routers etc
 
 8) sudo apt-get install fglrx fglrx-amdcccle fglrx-dev
    sudo sync
    sudo shutdown -r now
 
 N.B. always do a "sudo sync" and wait for it to finish every time before
-   shutting down the PC to ensure all data is written to the USB
+shutting down the PC to ensure all data is written to the USB
 
 9) sudo aticonfig --lsa
    this lists your ATI cards so you can see them
  sudo aticonfig --adapter=all --odgt
    this checks it can access all the cards ...
 
-10) aticonfig --adapter=all --initial
+10) sudo aticonfig --adapter=all --initial
    this gets an error - no idea why but the xorg.conf is OK
  sudo sync
  sudo shutdown -r now
@@ -91,13 +104,17 @@ N.B. always do a "sudo sync" and wait for it to finish every time before
 13) cgminer:
  sudo apt-get install curl
 
- get the binary linux cgminer (see the bitcoin forum cgminer thread
- for where to get it)
+ get the binary linux cgminer
+ (see the bitcoin forum cgminer thread for where to get it)
+ https://bitcointalk.org/index.php?topic=28402.0
 
  ./cgminer -n
    this shows you the GPU's it found on your PC
+   See further below if you get an error regarding libtinfo.so.5
 
 14) An OC option:
+ This is no longer needed since cgminer 2.* includes OC, however:
+
  sudo apt-get install libwxbase2.8-0 libwxgtk2.8-0
 
  http://sourceforge.net/projects/amdovdrvctrl/
@@ -106,21 +123,22 @@ N.B. always do a "sudo sync" and wait for it to finish every time before
 
 15) set the screen saver to ONLY blank ...
 
- Move the mouse to the bottom of the screen and you see a set of icons
- like on an Apple PC
+ Move the mouse to the bottom of the screen and you see a set of icons like
+ on an Apple PC
  Click on Settings, then in the Settings window "Screensaver"
  Set "Mode:" to "Blank Screen Only"
 
-Edit: originally left this somewhat useful addition out:
 16) apt-get install ntpd
- An accurate clock is always a good idea Smiley
+ An accurate clock is always a good idea :)
 
-Edit2: another item that seems I missed
 17) if you wish to ssh into the box you must set a password
     to do this you simply have to be logged into it at the screen and type
+
   sudo passwd ubuntu
+
     it will prompt you (twice) to enter a password for the ubuntu account
 
+
 Initial setup complete.
 
 ========
@@ -129,17 +147,23 @@ If you want to SSH into the machine and run cgminer:
  From a terminal on the miner display each time after you boot:
   xhost +
 
-Then after ssh into the machine:
+ 'xhost +' isn't needed if you ssh into the machine with the same
+ username that the GUI boots into (which is 'ubuntu' in this case)
+
+Then after you ssh into the machine:
  export DISPLAY=:0
 before running cgminer
 
-Also note, that you should force the screen to blank when mining if the ATI card
-is displaying the screen (using the screen saver application menu)
+Also note, that you should force the screen to blank when mining if
+the ATI card is displaying the screen (using the screen saver
+application menu)
 In my case it takes away 50Mh/s when the screen isn't blanked
+It will auto blank - but make sure the blank is of course just blank
+as mentioned above at 15)
 
 
-This is of course just the basics ... but it should get you a computer up and
-running and able to run cgminer
+This is of course just the basics ... but it should get you a computer
+up and running and able to run cgminer
 
 ========
 
@@ -147,10 +171,15 @@ You should keep an eye on USB disk space
 The system logger writes log files in the /var/log/ directory
 The two main ones that grow large are 'kern.log' and 'syslog'
 If you want to keep them, save them away to some other computer
-When space is low, just delete them.
+When space is low, just delete them e.g.
+
+   sudo rm -i /var/log/syslog
+   sudo rm -i /var/log/kern.log
 
 The 'df' command will show you the current space e.g.:
 
+   sudo df
+
 Filesystem           1K-blocks      Used Available Use% Mounted on
 aufs                   2099420    892024   1100748  45% /
 none                   1015720       628   1015092   1% /dev
@@ -164,3 +193,15 @@ none                   1023772         0   1023772   0% /var/lock
 
 This shows the 2GB space allocated when you setup the USB as '/' (aufs)
 In this example, it's currently 45% full with almost 1.1GB of free space
+
+========
+
+The latest version (2.0.8) of cgminer is built with 11.10 (not 11.04)
+If you get the following error when running the prebuilt version in 11.04:
+
+   ./cgminer: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory
+
+The fix is to simply link the old curses library to the new name e.g.:
+
+   cd /lib64/
+   sudo ln -s libncurses.so.5 libtinfo.so.5
diff --git a/main.c b/main.c
index a3fd11a..d2f794b 100644
--- a/main.c
+++ b/main.c
@@ -219,11 +219,11 @@ static int nDevs;
 static int opt_g_threads = 2;
 static int opt_device;
 static int total_devices;
-static bool gpu_devices[MAX_GPUDEVICES];
-static int gpu_threads;
+bool gpu_devices[MAX_GPUDEVICES];
+int gpu_threads;
 static bool forced_n_threads;
 static int opt_n_threads;
-static int mining_threads;
+int mining_threads;
 static int num_processors;
 bool use_curses = true;
 static bool opt_submit_stale;
@@ -248,6 +248,7 @@ static int watchdog_thr_id;
 static int input_thr_id;
 static int gpur_thr_id;
 static int cpur_thr_id;
+static int api_thr_id;
 static int total_threads;
 
 struct work_restart *work_restart = NULL;
@@ -273,15 +274,13 @@ static unsigned int found_blocks;
 static unsigned int local_work;
 static unsigned int total_go, total_ro;
 
-#define MAX_POOLS (32)
-
-static struct pool *pools[MAX_POOLS];
+struct pool *pools[MAX_POOLS];
 static struct pool *currentpool = NULL;
 
 static float opt_donation = 0.0;
 static struct pool donationpool;
 
-static int total_pools;
+int total_pools;
 static enum pool_strategy pool_strategy = POOL_FAILOVER;
 static int opt_rotate_period;
 static int total_urls, total_users, total_passes, total_userpasses;
@@ -1938,11 +1937,11 @@ static int requests_staged(void)
 }
 
 static WINDOW *mainwin, *statuswin, *logwin;
-static double total_secs = 0.1;
+double total_secs = 0.1;
 static char statusline[256];
 static int cpucursor, gpucursor, logstart, logcursor;
 struct cgpu_info gpus[MAX_GPUDEVICES]; /* Maximum number apparently possible */
-static struct cgpu_info *cpus;
+struct cgpu_info *cpus;
 
 static inline void unlock_curses(void)
 {
@@ -3747,6 +3746,15 @@ static void *workio_thread(void *userdata)
 	return NULL;
 }
 
+static void *api_thread(void *userdata)
+{
+	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+
+	api();
+
+	return NULL;
+}
+
 static void thread_reportin(struct thr_info *thr)
 {
 	gettimeofday(&thr->last, NULL);
@@ -6088,6 +6096,13 @@ retry_pools:
 	if (thr_info_create(thr, NULL, reinit_gpu, thr))
 		quit(1, "reinit_gpu thread create failed");
 
+	/* Create API socket thread */
+	api_thr_id = mining_threads + 7;
+	thr = &thr_info[api_thr_id];
+	if (thr_info_create(thr, NULL, api_thread, thr))
+		quit(1, "API thread create failed");
+	pthread_detach(thr->pth);
+
 	sleep(opt_log_interval);
 	if (opt_donation > 0.0)
 		applog(LOG_WARNING, "Donation is enabled at %.1f%% thank you :-)", opt_donation);
diff --git a/miner.h b/miner.h
index 30b2f9a..62d7312 100644
--- a/miner.h
+++ b/miner.h
@@ -394,8 +394,11 @@ struct work_restart {
 	char			padding[128 - sizeof(unsigned long)];
 };
 
+extern void api();
+
 
 #define MAX_GPUDEVICES 16
+#define MAX_POOLS (32)
 
 extern int hw_errors;
 extern bool use_syslog;
@@ -403,6 +406,13 @@ extern struct thr_info *thr_info;
 extern int longpoll_thr_id;
 extern struct work_restart *work_restart;
 extern struct cgpu_info gpus[MAX_GPUDEVICES];
+extern int gpu_threads;
+extern double total_secs;
+extern bool gpu_devices[MAX_GPUDEVICES];
+extern int mining_threads;
+extern struct cgpu_info *cpus;
+extern int total_pools;
+extern struct pool *pools[MAX_POOLS];
 
 #ifdef HAVE_OPENCL
 typedef struct {