Browse Source

Merge pull request #18 from ycros/cgminer

Win32 threading, longpoll and clean exit fixes.
nfactor-troky
Con Kolivas 14 years ago
parent
commit
4a34d10477
  1. 58
      main.c
  2. 8
      miner.h
  3. 44
      util.c

58
main.c

@ -998,6 +998,11 @@ static void workio_cmd_free(struct workio_cmd *wc)
static void disable_curses(void) static void disable_curses(void)
{ {
if (test_and_clear(&curses_active)) { if (test_and_clear(&curses_active)) {
#ifdef WIN32
leaveok(logwin, false);
leaveok(statuswin, false);
leaveok(mainwin, false);
#endif
nocbreak(); nocbreak();
echo(); echo();
delwin(logwin); delwin(logwin);
@ -1005,6 +1010,19 @@ static void disable_curses(void)
delwin(mainwin); delwin(mainwin);
endwin(); endwin();
refresh(); refresh();
#ifdef WIN32
// Move the cursor to after curses output.
HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
COORD coord;
if (GetConsoleScreenBufferInfo(hout, &csbi)) {
coord.X = 0;
coord.Y = csbi.dwSize.Y - 1;
SetConsoleCursorPosition(hout, coord);
}
#endif
} }
} }
@ -1019,7 +1037,7 @@ void kill_work(void)
/* Kill the watchdog thread */ /* Kill the watchdog thread */
thr = &thr_info[watchdog_thr_id]; thr = &thr_info[watchdog_thr_id];
pthread_cancel(thr->pth); pthread_cancel(*thr->pth);
/* Stop the mining threads*/ /* Stop the mining threads*/
for (i = 0; i < mining_threads; i++) { for (i = 0; i < mining_threads; i++) {
@ -1028,14 +1046,14 @@ void kill_work(void)
continue; continue;
tq_freeze(thr->q); tq_freeze(thr->q);
/* No need to check if this succeeds or not */ /* No need to check if this succeeds or not */
pthread_cancel(thr->pth); pthread_cancel(*thr->pth);
} }
/* Stop the others */ /* Stop the others */
thr = &thr_info[stage_thr_id]; thr = &thr_info[stage_thr_id];
pthread_cancel(thr->pth); pthread_cancel(*thr->pth);
thr = &thr_info[longpoll_thr_id]; thr = &thr_info[longpoll_thr_id];
pthread_cancel(thr->pth); pthread_cancel(*thr->pth);
wc = calloc(1, sizeof(*wc)); wc = calloc(1, sizeof(*wc));
if (unlikely(!wc)) { if (unlikely(!wc)) {
@ -2805,7 +2823,7 @@ static void stop_longpoll(void)
struct thr_info *thr = &thr_info[longpoll_thr_id]; struct thr_info *thr = &thr_info[longpoll_thr_id];
tq_freeze(thr->q); tq_freeze(thr->q);
pthread_cancel(thr->pth); pthread_cancel(*thr->pth);
have_longpoll = false; have_longpoll = false;
} }
@ -2816,9 +2834,9 @@ static void start_longpoll(void)
struct thr_info *thr = &thr_info[longpoll_thr_id]; struct thr_info *thr = &thr_info[longpoll_thr_id];
tq_thaw(thr->q); tq_thaw(thr->q);
if (unlikely(pthread_create(&thr->pth, NULL, longpoll_thread, thr))) if (unlikely(thr_info_create(thr, NULL, longpoll_thread, thr)))
quit(1, "longpoll thread create failed"); quit(1, "longpoll thread create failed");
pthread_detach(thr->pth); pthread_detach(*thr->pth);
} }
static void restart_longpoll(void) static void restart_longpoll(void)
@ -2833,7 +2851,7 @@ static void reinit_cputhread(int thr_id)
struct thr_info *thr = &thr_info[thr_id]; struct thr_info *thr = &thr_info[thr_id];
tq_freeze(thr->q); tq_freeze(thr->q);
if (!(pthread_cancel(thr->pth)) && pthread_join(thr->pth, NULL)) { if (!(pthread_cancel(*thr->pth)) && pthread_join(*thr->pth, NULL)) {
applog(LOG_ERR, "Failed to pthread_join in reinit_cputhread"); applog(LOG_ERR, "Failed to pthread_join in reinit_cputhread");
goto failed_out; goto failed_out;
} }
@ -2843,7 +2861,7 @@ static void reinit_cputhread(int thr_id)
thread_reportin(thr); thread_reportin(thr);
if (unlikely(pthread_create(&thr->pth, NULL, miner_thread, thr))) { if (unlikely(thr_info_create(thr, NULL, miner_thread, thr))) {
applog(LOG_ERR, "thread %d create failed", thr_id); applog(LOG_ERR, "thread %d create failed", thr_id);
goto failed_out; goto failed_out;
} }
@ -2861,7 +2879,7 @@ static void reinit_gputhread(int thr_id)
char name[256]; char name[256];
tq_freeze(thr->q); tq_freeze(thr->q);
if (!(pthread_cancel(thr->pth)) && pthread_join(thr->pth, NULL)) { if (!(pthread_cancel(*thr->pth)) && pthread_join(*thr->pth, NULL)) {
applog(LOG_ERR, "Failed to pthread_join in reinit_gputhread"); applog(LOG_ERR, "Failed to pthread_join in reinit_gputhread");
goto failed_out; goto failed_out;
} }
@ -2878,7 +2896,7 @@ static void reinit_gputhread(int thr_id)
thread_reportin(thr); thread_reportin(thr);
if (unlikely(pthread_create(&thr->pth, NULL, gpuminer_thread, thr))) { if (unlikely(thr_info_create(thr, NULL, gpuminer_thread, thr))) {
applog(LOG_ERR, "thread %d create failed", thr_id); applog(LOG_ERR, "thread %d create failed", thr_id);
goto failed_out; goto failed_out;
} }
@ -3351,7 +3369,7 @@ int main (int argc, char *argv[])
quit(1, "Failed to tq_new"); quit(1, "Failed to tq_new");
/* start work I/O thread */ /* start work I/O thread */
if (pthread_create(&thr->pth, NULL, workio_thread, thr)) if (thr_info_create(thr, NULL, workio_thread, thr))
quit(1, "workio thread create failed"); quit(1, "workio thread create failed");
/* init longpoll thread info */ /* init longpoll thread info */
@ -3382,9 +3400,9 @@ int main (int argc, char *argv[])
if (!thr->q) if (!thr->q)
quit(1, "Failed to tq_new"); quit(1, "Failed to tq_new");
/* start stage thread */ /* start stage thread */
if (pthread_create(&thr->pth, NULL, stage_thread, thr)) if (thr_info_create(thr, NULL, stage_thread, thr))
quit(1, "stage thread create failed"); quit(1, "stage thread create failed");
pthread_detach(thr->pth); pthread_detach(*thr->pth);
/* Create a unique get work queue */ /* Create a unique get work queue */
getq = tq_new(); getq = tq_new();
@ -3449,7 +3467,7 @@ int main (int argc, char *argv[])
thread_reportin(thr); thread_reportin(thr);
if (unlikely(pthread_create(&thr->pth, NULL, gpuminer_thread, thr))) if (unlikely(thr_info_create(thr, NULL, gpuminer_thread, thr)))
quit(1, "thread %d create failed", i); quit(1, "thread %d create failed", i);
i++; i++;
} }
@ -3477,7 +3495,7 @@ int main (int argc, char *argv[])
thread_reportin(thr); thread_reportin(thr);
if (unlikely(pthread_create(&thr->pth, NULL, miner_thread, thr))) if (unlikely(thr_info_create(thr, NULL, miner_thread, thr)))
quit(1, "thread %d create failed", i); quit(1, "thread %d create failed", i);
} }
@ -3489,7 +3507,7 @@ int main (int argc, char *argv[])
watchdog_thr_id = mining_threads + 2; watchdog_thr_id = mining_threads + 2;
thr = &thr_info[watchdog_thr_id]; thr = &thr_info[watchdog_thr_id];
/* start wakeup thread */ /* start wakeup thread */
if (pthread_create(&thr->pth, NULL, watchdog_thread, NULL)) if (thr_info_create(thr, NULL, watchdog_thread, NULL))
quit(1, "wakeup thread create failed"); quit(1, "wakeup thread create failed");
/* Now that everything's ready put enough work in the queue */ /* Now that everything's ready put enough work in the queue */
@ -3503,12 +3521,12 @@ int main (int argc, char *argv[])
/* Create curses input thread for keyboard input */ /* Create curses input thread for keyboard input */
input_thr_id = mining_threads + 4; input_thr_id = mining_threads + 4;
thr = &thr_info[input_thr_id]; thr = &thr_info[input_thr_id];
if (pthread_create(&thr->pth, NULL, input_thread, thr)) if (thr_info_create(thr, NULL, input_thread, thr))
quit(1, "input thread create failed"); quit(1, "input thread create failed");
pthread_detach(thr->pth); pthread_detach(*thr->pth);
/* main loop - simply wait for workio thread to exit */ /* main loop - simply wait for workio thread to exit */
pthread_join(thr_info[work_thr_id].pth, NULL); pthread_join(*thr_info[work_thr_id].pth, NULL);
applog(LOG_INFO, "workio thread dead, exiting."); applog(LOG_INFO, "workio thread dead, exiting.");
gettimeofday(&total_tv_end, NULL); gettimeofday(&total_tv_end, NULL);

8
miner.h

@ -29,7 +29,11 @@
#ifdef HAVE_ALLOCA_H #ifdef HAVE_ALLOCA_H
# include <alloca.h> # include <alloca.h>
#elif defined __GNUC__ #elif defined __GNUC__
# ifndef WIN32
# define alloca __builtin_alloca # define alloca __builtin_alloca
# else
# include <malloc.h>
# endif
#elif defined _AIX #elif defined _AIX
# define alloca __alloca # define alloca __alloca
#elif defined _MSC_VER #elif defined _MSC_VER
@ -145,13 +149,15 @@ struct cgpu_info {
struct thr_info { struct thr_info {
int id; int id;
pthread_t pth; pthread_t *pth;
struct thread_q *q; struct thread_q *q;
struct cgpu_info *cgpu; struct cgpu_info *cgpu;
struct timeval last; struct timeval last;
bool getwork; bool getwork;
}; };
extern inline int thr_info_create(struct thr_info *thr, pthread_attr_t *attr, void *(*start) (void *), void *arg);
static inline uint32_t swab32(uint32_t v) static inline uint32_t swab32(uint32_t v)
{ {
#ifdef WANT_BUILTIN_BSWAP #ifdef WANT_BUILTIN_BSWAP

44
util.c

@ -24,8 +24,13 @@
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#ifndef WIN32
# include <sys/socket.h> # include <sys/socket.h>
# include <netinet/tcp.h> # include <netinet/tcp.h>
#else
# include <winsock2.h>
# include <mstcpip.h>
#endif
#include "miner.h" #include "miner.h"
#include "elist.h" #include "elist.h"
@ -252,18 +257,34 @@ int json_rpc_call_sockopt_cb(void *userdata, curl_socket_t fd, curlsocktype purp
int tcp_keepidle = 120; int tcp_keepidle = 120;
int tcp_keepintvl = 120; int tcp_keepintvl = 120;
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive))) #ifndef WIN32
if (unlikely(setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive))))
return 1;
if (unlikely(setsockopt(fd, SOL_TCP, TCP_KEEPCNT, &tcp_keepcnt, sizeof(tcp_keepcnt))))
return 1; return 1;
if (setsockopt(fd, SOL_TCP, TCP_KEEPCNT, &tcp_keepcnt, sizeof(tcp_keepcnt))) if (unlikely(setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &tcp_keepidle, sizeof(tcp_keepidle))))
return 1; return 1;
if (setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &tcp_keepidle, sizeof(tcp_keepidle))) if (unlikely(setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &tcp_keepintvl, sizeof(tcp_keepintvl))))
return 1; return 1;
if (setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &tcp_keepintvl, sizeof(tcp_keepintvl))) #else
struct tcp_keepalive vals;
vals.onoff = 1;
vals.keepalivetime = tcp_keepidle * 1000;
vals.keepaliveinterval = tcp_keepintvl * 1000;
DWORD outputBytes;
if (unlikely(WSAIoctl(fd, SIO_KEEPALIVE_VALS, &vals, sizeof(vals), NULL, 0, &outputBytes, NULL, NULL)))
return 1; return 1;
#endif
return 0; return 0;
} }
@ -647,3 +668,18 @@ out:
return rval; return rval;
} }
inline int thr_info_create(struct thr_info *thr, pthread_attr_t *attr, void *(*start) (void *), void *arg)
{
int ret = 0;
thr->pth = malloc(sizeof(pthread_t));
ret = pthread_create(thr->pth, attr, start, arg);
if (unlikely(ret)) {
free(thr->pth);
thr->pth = 0;
}
return ret;
}

Loading…
Cancel
Save