Browse Source

Implement cgminer specific cgsem semaphores to imitate unnamed semaphore behaviour on osx which does not support them.

nfactor-troky
ckolivas 11 years ago
parent
commit
b59c33800b
  1. 5
      cgminer.c
  2. 17
      driver-avalon.c
  3. 6
      driver-avalon.h
  4. 2
      miner.h
  5. 8
      usbutils.c
  6. 71
      util.c
  7. 18
      util.h

5
cgminer.c

@ -150,7 +150,7 @@ char *opt_avalon_options = NULL; @@ -150,7 +150,7 @@ char *opt_avalon_options = NULL;
char *opt_usb_select = NULL;
int opt_usbdump = -1;
bool opt_usb_list_all;
sem_t usb_resource_sem;
cgsem_t usb_resource_sem;
#endif
char *opt_kernel_path;
@ -7442,8 +7442,7 @@ int main(int argc, char *argv[]) @@ -7442,8 +7442,7 @@ int main(int argc, char *argv[])
// before device detection
if (!opt_scrypt) {
if (sem_init(&usb_resource_sem, 0, 0))
quit(1, "Failed to sem_init usb_resource_sem");
cgsem_init(&usb_resource_sem);
usbres_thr_id = 1;
thr = &control_thr[usbres_thr_id];
if (thr_info_create(thr, NULL, usb_resource_thread, thr))

17
driver-avalon.c

@ -769,8 +769,8 @@ static void *avalon_get_results(void *userdata) @@ -769,8 +769,8 @@ static void *avalon_get_results(void *userdata)
if (unlikely(info->reset)) {
/* Tell the write thread it can start the reset */
sem_post(&info->write_sem);
sem_wait(&info->read_sem);
cgsem_post(&info->write_sem);
cgsem_wait(&info->read_sem);
/* Discard anything in the buffer */
offset = 0;
@ -820,9 +820,9 @@ static void *avalon_send_tasks(void *userdata) @@ -820,9 +820,9 @@ static void *avalon_send_tasks(void *userdata)
if (unlikely(info->reset)) {
/* Wait till read thread tells us it's received the
* reset message */
sem_wait(&info->write_sem);
cgsem_wait(&info->write_sem);
avalon_running_reset(avalon, info);
sem_post(&info->read_sem);
cgsem_post(&info->read_sem);
}
mutex_lock(&info->qlock);
@ -890,10 +890,8 @@ static bool avalon_prepare(struct thr_info *thr) @@ -890,10 +890,8 @@ static bool avalon_prepare(struct thr_info *thr)
mutex_init(&info->qlock);
if (unlikely(pthread_cond_init(&info->qcond, NULL)))
quit(1, "Failed to pthread_cond_init avalon qcond");
if (unlikely(sem_init(&info->read_sem, 0, 0)))
quit(1, "Failed to sem_init avalon read_sem");
if (unlikely(sem_init(&info->write_sem, 0, 0)))
quit(1, "Failed to sem_init avalon write_sem");
cgsem_init(&info->read_sem);
cgsem_init(&info->write_sem);
if (pthread_create(&info->read_thr, NULL, avalon_get_results, (void *)avalon))
quit(1, "Failed to create avalon read_thr");
@ -918,6 +916,9 @@ static void do_avalon_close(struct thr_info *thr) @@ -918,6 +916,9 @@ static void do_avalon_close(struct thr_info *thr)
avalon_running_reset(avalon, info);
info->no_matching_work = 0;
cgsem_destroy(&info->read_sem);
cgsem_destroy(&info->write_sem);
}
static inline void record_temp_fan(struct avalon_info *info, struct avalon_result *ar, float *temp_avg)

6
driver-avalon.h

@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
#ifdef USE_AVALON
#include <semaphore.h>
#include "util.h"
#define AVALON_RESET_FAULT_DECISECONDS 1
#define AVALON_MINER_THREADS 1
@ -110,8 +110,8 @@ struct avalon_info { @@ -110,8 +110,8 @@ struct avalon_info {
pthread_mutex_t lock;
pthread_mutex_t qlock;
pthread_cond_t qcond;
sem_t read_sem;
sem_t write_sem;
cgsem_t read_sem;
cgsem_t write_sem;
int nonces;
bool idle;

2
miner.h

@ -855,7 +855,7 @@ extern char *opt_avalon_options; @@ -855,7 +855,7 @@ extern char *opt_avalon_options;
extern char *opt_usb_select;
extern int opt_usbdump;
extern bool opt_usb_list_all;
extern sem_t usb_resource_sem;
extern cgsem_t usb_resource_sem;
#endif
#ifdef USE_BITFORCE
extern bool opt_bfl_noncerange;

8
usbutils.c

@ -1225,7 +1225,7 @@ static bool cgminer_usb_lock_bd(struct device_drv *drv, uint8_t bus_number, uint @@ -1225,7 +1225,7 @@ static bool cgminer_usb_lock_bd(struct device_drv *drv, uint8_t bus_number, uint
res_work_head = res_work;
mutex_unlock(&cgusbres_lock);
sem_post(&usb_resource_sem);
cgsem_post(&usb_resource_sem);
// TODO: add a timeout fail - restart the resource thread?
while (true) {
@ -1284,7 +1284,7 @@ static void cgminer_usb_unlock_bd(struct device_drv *drv, uint8_t bus_number, ui @@ -1284,7 +1284,7 @@ static void cgminer_usb_unlock_bd(struct device_drv *drv, uint8_t bus_number, ui
res_work_head = res_work;
mutex_unlock(&cgusbres_lock);
sem_post(&usb_resource_sem);
cgsem_post(&usb_resource_sem);
return;
}
@ -2610,6 +2610,8 @@ void usb_cleanup() @@ -2610,6 +2610,8 @@ void usb_cleanup()
}
mutex_unlock(&cgusbres_lock);
}
cgsem_destroy(&usb_resource_sem);
}
void usb_initialise()
@ -3115,7 +3117,7 @@ void *usb_resource_thread(void __maybe_unused *userdata) @@ -3115,7 +3117,7 @@ void *usb_resource_thread(void __maybe_unused *userdata)
while (42) {
/* Wait to be told we have work to do */
sem_wait(&usb_resource_sem);
cgsem_wait(&usb_resource_sem);
mutex_lock(&cgusbres_lock);
while (res_work_head)

71
util.c

@ -1870,3 +1870,74 @@ void RenameThread(const char* name) @@ -1870,3 +1870,74 @@ void RenameThread(const char* name)
#endif
}
/* cgminer specific wrappers for true unnamed semaphore usage on platforms
* that support them and for apple which does not. We use a single byte across
* a pipe to emulate semaphore behaviour there. */
#ifdef __APPLE__
void cgsem_init(cgsem_t *cgsem)
{
int flags, fd, i;
if (pipe(cgsem->pipefd) == -1)
quit(1, "Failed pipe in cgsem_init");
/* Make the pipes FD_CLOEXEC to allow them to close should we call
* execv on restart. */
for (i = 0; i < 2; i++) {
fd = cgsem->pipefd[i];
flags = fcntl(fd, F_GETFD, 0);
flags |= FD_CLOEXEC;
if (fcntl(fd, F_SETFD, flags) == -1)
quit(1, "Failed to fcntl in cgsem_init");
}
}
void cgsem_post(cgsem_t *cgsem)
{
const char buf = 1;
int ret;
ret = write(cgsem->pipefd[1], &buf, 1);
if (ret == 0)
quit(1, "Failed to write in cgsem_post");
}
void cgsem_wait(cgsem_t *cgsem)
{
char buf;
int ret;
ret = read(cgsem->pipefd[0], &buf, 1);
if (ret == 0)
quit(1, "Failed to read in cgsem_wait");
}
void cgsem_destroy(cgsem_t *cgsem)
{
close(cgsem->pipefd[1]);
close(cgsem->pipefd[0]);
}
#else
void cgsem_init(cgsem_t *cgsem)
{
if (sem_init(cgsem, 0, 0))
quit(1, "Failed to sem_init in cgsem_init");
}
void cgsem_post(cgsem_t *cgsem)
{
if (unlikely(sem_post(cgsem)))
quit(1, "Failed to sem_post in cgsem_post");
}
void cgsem_wait(cgsem_t *cgsem)
{
if (unlikely(sem_wait(cgsem)))
quit(1, "Failed to sem_wait in cgsem_wait");
}
void cgsem_destroy(cgsem_t *cgsem)
{
sem_destroy(cgsem);
}
#endif

18
util.h

@ -1,6 +1,8 @@ @@ -1,6 +1,8 @@
#ifndef __UTIL_H__
#define __UTIL_H__
#include <semaphore.h>
#if defined(unix) || defined(__APPLE__)
#include <errno.h>
#include <sys/socket.h>
@ -50,6 +52,18 @@ @@ -50,6 +52,18 @@
#define JSON_LOADS(str, err_ptr) json_loads((str), (err_ptr))
#endif
/* cgminer specific unnamed semaphore implementations to cope with osx not
* implementing them. */
#ifdef __APPLE__
struct cgsem {
int pipefd[2];
};
typedef struct cgsem cgsem_t;
#else
typedef sem_t cgsem_t;
#endif
struct thr_info;
struct pool;
enum dev_reason;
@ -80,6 +94,10 @@ void dev_error(struct cgpu_info *dev, enum dev_reason reason); @@ -80,6 +94,10 @@ void dev_error(struct cgpu_info *dev, enum dev_reason reason);
void *realloc_strcat(char *ptr, char *s);
void *str_text(char *ptr);
void RenameThread(const char* name);
void cgsem_init(cgsem_t *cgsem);
void cgsem_post(cgsem_t *cgsem);
void cgsem_wait(cgsem_t *cgsem);
void cgsem_destroy(cgsem_t *cgsem);
/* Align a size_t to 4 byte boundaries for fussy arches */
static inline void align_len(size_t *len)

Loading…
Cancel
Save