static void wq_enqueue(struct thr_info *thr, struct T1_chain *t1) { struct work *work = get_work(thr, thr->id); struct work_queue *wq; struct work_ent *we; int rolls = 0; wq = &t1->active_wq; while (42) { we = cgmalloc(sizeof(*we)); we->work = work; INIT_LIST_HEAD(&we->head); mutex_lock(&t1->lock); list_add_tail(&we->head, &wq->head); wq->num_elems++; mutex_unlock(&t1->lock); if (wq->num_elems >= t1->num_active_chips * 2) { break; } if (rolls > work->drv_rolllimit) { work = get_work(thr, thr->id); continue; } work = make_clone(work); roll_work(work); } }
/*===========================================================================* * main * *===========================================================================*/ PUBLIC void main() { /* Main routine of the memory manager. */ int error; mm_init(); /* initialize memory manager tables */ /* This is MM's main loop- get work and do it, forever and forever. */ while (TRUE) { /* Wait for message. */ get_work(); /* wait for an MM system call */ mp = &mproc[who]; /* Set some flags. */ error = OK; dont_reply = FALSE; err_code = -999; /* If the call number is valid, perform the call. */ if (mm_call < 0 || mm_call >= NCALLS) error = EBADCALL; else error = (*call_vec[mm_call])(); /* Send the results back to the user to indicate completion. */ if (dont_reply) continue; /* no reply for EXIT and WAIT */ if (mm_call == EXEC && error == OK) continue; reply(who, error, result2, res_ptr); } }
void boss() { struct q_work_struct *ptr; int ret,i; i = 0; /* obtain work, return when complete */ for ( ; ; ) { /* allocate a work structure */ ptr = (struct q_work_struct *) malloc (sizeof(struct q_work_struct)); if ( ptr == NULL ) break; /* create/obtain work and fill in the work structure */ ret = get_work(ptr,i); if ( ret == 0 ) { free((void *)ptr); break; } /* queue up the work */ if ( enqueue(&thr_queue, ptr) != 0 ) { fprintf(stderr, "enqueue() error\n"); exit(-1); } i++; } }
/*===========================================================================* * worker_main * *===========================================================================*/ static void *worker_main(void *arg) { /* Worker thread main loop */ struct worker_thread *me; me = (struct worker_thread *) arg; ASSERTW(me); while(TRUE) { get_work(me); /* Register ourselves in fproc table if possible */ if (me->w_job.j_fp != NULL) { me->w_job.j_fp->fp_wtid = me->w_tid; } /* Carry out work */ me->w_job.j_func(&me->w_job); /* Deregister if possible */ if (me->w_job.j_fp != NULL) { me->w_job.j_fp->fp_wtid = invalid_thread_id; } /* Mark ourselves as done */ me->w_job.j_func = NULL; me->w_job.j_fp = NULL; } return(NULL); /* Unreachable */ }
/* --------------------------------- */ void init_mtext(void) { register int i, j; int a, b; scrtchp = (long)Malloc(2048L); mtext_mlen = (long)Malloc(-1L) - 75000; mtext_mem = (unsigned char *)Malloc(mtext_mlen); /*printf("\033H%lx\n", mtext_mem);*/ memset(mtext_mem, 0, mtext_mlen); pathes[0][0] = Dgetdrv(); pathes[0][1] = ':'; Dgetpath(pathes[0] + 2, 0); strcat(pathes[0] + 2, "\\"); pathes[0][0] += 'A'; strcpy(pathes[1], pathes[0]); strcpy(pathes[2], pathes[0]); strcpy(pathes[3], pathes[0]); pic_fpath[0] = pathes[0][0]; del_file[0] = font_path[0] = pathes[0][0]; for (i = 0; i < 68; txt_lineal[0][i++] = '.'); txt_lineal[0][68] = 0; strcpy(txt_lineal[1], txt_lineal[0]); strcpy(txt_lineal[2], txt_lineal[0]); strcpy(txt_lineal[3], txt_lineal[0]); strncpy(txt_linpar[0], "NPS110", 6); strncpy(txt_linpar[1], txt_linpar[0], 6); strncpy(txt_linpar[2], txt_linpar[0], 6); strncpy(txt_linpar[3], txt_linpar[0], 6); strcpy(txt_infol[0], " Seite: 999, Zeile: 99999, Spalte: 999 Einf�gen "); strcpy(txt_infol[1], txt_infol[0]); strcpy(txt_infol[2], txt_infol[0]); strcpy(txt_infol[3], txt_infol[0]); vst_alignment(vdi_handle, 0, 3, &a, &b); vsf_perimeter(vdi_handle, FALSE); load_cfg(); get_work(0); for (i = 0; i < 4; i++) { w_koor[i][0] = wx; w_koor[i][1] = wy; w_koor[i][2] = ww - (3 - i) * 10; w_koor[i][3] = wh - i * 10; } }
/* ---------------------- */ void button_mesag(void) { get_work(w_handles[akt_id]); if (pt_inrect(mousex, mousey, wx, wy, ww, wh)) if (ruler_flag && mousey - wy < 16 && mousey >= wy) { if (mousex < wx + 24) edit_aktruler(); else set_tab(); } else set_cursor(); }
static struct work *get_and_prepare_work(struct thr_info *thr) { struct cgpu_info *proc = thr->cgpu; struct device_drv *api = proc->drv; struct work *work; work = get_work(thr); if (!work) return NULL; if (api->prepare_work && !api->prepare_work(thr, work)) { free_work(work); applog(LOG_ERR, "%"PRIpreprv": Work prepare failed, disabling!", proc->proc_repr); proc->deven = DEV_RECOVER_ERR; run_cmd(cmd_idle); return NULL; } return work; }
static void *run(void *arg) { int hit = 0; struct grep_opt *opt = arg; while (1) { struct work_item *w = get_work(); if (!w) break; opt->output_priv = w; hit |= grep_source(opt, &w->source); grep_source_clear_data(&w->source); work_done(w); } free_grep_patterns(arg); free(arg); return (void*) (intptr_t) hit; }
void base::do_loop(void) { db::node *node(NULL); while(true) { while((node = get_work())) { do_work(node); finish_work(node); } assert_end_iteration(); // cout << id << " -------- END ITERATION ---------" << endl; // false from end_iteration ends program if(!end_iteration()) return; } }
/*===========================================================================* * main * *===========================================================================*/ int main(int argc, char **argv) { /* This is the main routine of this service. The main loop consists of * three major activities: getting new work, processing the work, and * sending the reply. The loop never terminates, unless a panic occurs. */ int result; /* SEF local startup. */ env_setargs(argc, argv); sef_local_startup(); /* Main loop - get work and do it, forever. */ while (TRUE) { /* Wait for incoming message, sets 'callnr' and 'who'. */ get_work(); if (is_notify(callnr)) { switch (_ENDPOINT_P(who_e)) { case TTY_PROC_NR: result = do_fkey_pressed(&m_in); break; default: /* FIXME: error message. */ result = EDONTREPLY; break; } } else { printf("IS: warning, got illegal request %d from %d\n", callnr, m_in.m_source); result = EDONTREPLY; } /* Finally send reply message, unless disabled. */ if (result != EDONTREPLY) { reply(who_e, result); } } return(OK); /* shouldn't come here */ }
static void *run(void *arg) { int hit = 0; struct grep_opt *opt = arg; while (1) { struct work_item *w = get_work(); if (!w) break; if (skip_binary(opt, (const char *)w->identifier)) continue; opt->output_priv = w; if (w->type == WORK_SHA1) { unsigned long sz; void* data = load_sha1(w->identifier, &sz, w->name); if (data) { hit |= grep_buffer(opt, w->name, data, sz); free(data); } } else if (w->type == WORK_FILE) { size_t sz; void* data = load_file(w->identifier, &sz); if (data) { hit |= grep_buffer(opt, w->name, data, sz); free(data); } } else { assert(0); } work_done(w); } free_grep_patterns(arg); free(arg); return (void*) (intptr_t) hit; }
static void *run(void *arg) { int hit = 0; struct grep_opt *opt = arg; while (1) { struct work_item *w = get_work(); if (!w) break; opt->output_priv = w; if (w->source.type == GREP_SOURCE_SUBMODULE) hit |= grep_submodule_launch(opt, &w->source); else hit |= grep_source(opt, &w->source); grep_source_clear_data(&w->source); work_done(w); } free_grep_patterns(arg); free(arg); return (void*) (intptr_t) hit; }
int main(void) { int cmd; /* initialize window size to defult */ window_size = DEFAULT_WINDOW_SIZE; message_to_send = NULL; /*pthread_t pthread_id[2]; pthread_attr_t attr;*/ /* * start named pipe, this is where the host will receive user commands. * it will be a producer/consumer design. pipe name should be passed as * command-line argument */ create_pipe(PIPE_NAME); int pipe = open_pipe(PIPE_NAME, O_RDONLY); /* * open a socket to do the communication. packet transaction will be * simulated above a normal connection. */ if (HOST == HOST_A) { open_socket(); send_message_to_other("Hello Client! You can start your simulation."); get_message_from_other(); printf("\n\n\n"); } else { open_connection(); get_message_from_other(); send_message_to_other("Hi Server."); printf("\n\n\n"); } /* * once connection is stablished we can start the SIM STATE MACHINE. * our state machine will start in CLOSED */ host_state = STATE_CLOSED; host_seq_number = rand(); /* * at this point we need to start our threads that will exchange * messages with the other host. */ /* thread to construct packets */ pthread_t pthread_id[10]; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(&pthread_id[0], &attr, (void *) &send_stuff_thread, (void *) NULL); /* pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(&pthread_id[0], &attr, (void *)&receive_tcp_packet_from_other, NULL); */ /* loop until gets work to do */ while (TRUE) { /* * get work from console. this is the link we have with the * outside world (client) */ fflush(stdout); cmd = get_work(pipe); int read_size; char buf[MAX_PIPE_DATA_SIZE]; switch (cmd) { case CMD_LISTEN: printf("got CMD_LISTEN\n"); cmd_listen(); break; case CMD_CONNECT: printf("got CMD_CONNECT\n"); cmd_connect(); break; case CMD_SEND_PKT: printf("got CMD_SEND_PKT\n"); sleep(1); /* get message to send over */ while ((read_size = pipe_read(pipe, buf)) < 1); message_to_send = malloc(read_size * sizeof(char)); strncpy(buf, message_to_send, read_size); break; case CMD_CHNG_WINDOW_SIZE: printf("changed window size to %d\n", window_size); break; case CMD_CLOSE: break; /* ACK packet */ default: printf("did not recognize cmd!\n"); } } }
/*===========================================================================* * main * *===========================================================================*/ int main(void) { /* This is the main program of the file system. The main loop consists of * three major activities: getting new work, processing the work, and sending * the reply. This loop never terminates as long as the file system runs. */ int transid; struct job *job; /* SEF local startup. */ sef_local_startup(); printf("Started VFS: %d worker thread(s)\n", NR_WTHREADS); /* This is the main loop that gets work, processes it, and sends replies. */ while (TRUE) { yield_all(); /* let other threads run */ self = NULL; job = NULL; send_work(); get_work(); transid = TRNS_GET_ID(m_in.m_type); if (IS_VFS_FS_TRANSID(transid)) { job = worker_getjob( (thread_t) transid - VFS_TRANSID); if (job == NULL) { printf("VFS: spurious message %d from endpoint %d\n", m_in.m_type, m_in.m_source); continue; } m_in.m_type = TRNS_DEL_ID(m_in.m_type); } if (job != NULL) { do_fs_reply(job); continue; } else if (who_e == PM_PROC_NR) { /* Calls from PM */ /* Special control messages from PM */ sys_worker_start(do_pm); continue; } else if (is_notify(call_nr)) { /* A task notify()ed us */ sys_worker_start(do_control_msgs); continue; } else if (who_p < 0) { /* i.e., message comes from a task */ /* We're going to ignore this message. Tasks should * send notify()s only. */ printf("VFS: ignoring message from %d (%d)\n", who_e, call_nr); continue; } /* At this point we either have results from an asynchronous device * or a new system call. In both cases a new worker thread has to be * started and there might not be one available from the pool. This is * not a problem (requests/replies are simply queued), except when * they're from an FS endpoint, because these can cause a deadlock. * handle_work() takes care of the details. */ if (IS_DEV_RS(call_nr)) { /* We've got results for a device request */ handle_work(do_async_dev_result); continue; } else { /* Normal syscall. */ handle_work(do_work); } } return(OK); /* shouldn't come here */ }
static int64_t hfa_scanwork(struct thr_info *thr) { struct cgpu_info *hashfast = thr->cgpu; struct hashfast_info *info = hashfast->device_data; int64_t hashes; int jobs, ret; if (unlikely(hashfast->usbinfo.nodev)) { applog(LOG_WARNING, "HFA %d: device disappeared, disabling", hashfast->device_id); return -1; } if (unlikely(thr->work_restart)) { restart: thr->work_restart = false; ret = hfa_send_frame(hashfast, HF_USB_CMD(OP_WORK_RESTART), 0, (uint8_t *)NULL, 0); if (unlikely(!ret)) { ret = hfa_reset(hashfast, info); if (unlikely(!ret)) { applog(LOG_ERR, "HFA %d: Failed to reset after write failure, disabling", hashfast->device_id); return -1; } } } jobs = hfa_jobs(info); if (!jobs) { ret = restart_wait(thr, 100); if (unlikely(!ret)) goto restart; jobs = hfa_jobs(info); } if (jobs) { applog(LOG_DEBUG, "HFA %d: Sending %d new jobs", hashfast->device_id, jobs); } while (jobs-- > 0) { struct hf_hash_usb op_hash_data; struct work *work; uint64_t intdiff; int i, sequence; uint32_t *p; /* This is a blocking function if there's no work */ work = get_work(thr, thr->id); /* Assemble the data frame and send the OP_HASH packet */ memcpy(op_hash_data.midstate, work->midstate, sizeof(op_hash_data.midstate)); memcpy(op_hash_data.merkle_residual, work->data + 64, 4); p = (uint32_t *)(work->data + 64 + 4); op_hash_data.timestamp = *p++; op_hash_data.bits = *p++; op_hash_data.starting_nonce = 0; op_hash_data.nonce_loops = 0; op_hash_data.ntime_loops = 0; /* Set the number of leading zeroes to look for based on diff. * Diff 1 = 32, Diff 2 = 33, Diff 4 = 34 etc. */ intdiff = (uint64_t)work->device_diff; for (i = 31; intdiff; i++, intdiff >>= 1); op_hash_data.search_difficulty = i; op_hash_data.group = 0; if ((sequence = info->hash_sequence_head + 1) >= info->num_sequence) sequence = 0; ret = hfa_send_frame(hashfast, OP_HASH, sequence, (uint8_t *)&op_hash_data, sizeof(op_hash_data)); if (unlikely(!ret)) { ret = hfa_reset(hashfast, info); if (unlikely(!ret)) { applog(LOG_ERR, "HFA %d: Failed to reset after write failure, disabling", hashfast->device_id); return -1; } } mutex_lock(&info->lock); info->hash_sequence_head = sequence; info->works[info->hash_sequence_head] = work; mutex_unlock(&info->lock); applog(LOG_DEBUG, "HFA %d: OP_HASH sequence %d search_difficulty %d work_difficulty %g", hashfast->device_id, info->hash_sequence_head, op_hash_data.search_difficulty, work->work_difficulty); } mutex_lock(&info->lock); hashes = info->hash_count; info->hash_count = 0; mutex_unlock(&info->lock); return hashes; }
static void hashratio_update_work(struct cgpu_info *hashratio) { struct hashratio_info *info = hashratio->device_data; struct thr_info *thr = hashratio->thr[0]; struct hashratio_pkg send_pkg; uint32_t tmp, range, start; struct work *work; struct pool *pool; applog(LOG_DEBUG, "hashratio: New stratum: restart: %d, update: %d", thr->work_restart, thr->work_update); thr->work_update = false; thr->work_restart = false; work = get_work(thr, thr->id); /* Make sure pool is ready */ discard_work(work); /* Don't leak memory */ pool = current_pool(); if (!pool->has_stratum) quit(1, "hashratio: Miner Manager have to use stratum pool"); if (pool->coinbase_len > HRTO_P_COINBASE_SIZE) quit(1, "hashratio: Miner Manager pool coinbase length have to less then %d", HRTO_P_COINBASE_SIZE); if (pool->merkles > HRTO_P_MERKLES_COUNT) quit(1, "hashratio: Miner Manager merkles have to less then %d", HRTO_P_MERKLES_COUNT); info->pool_no = pool->pool_no; cgtime(&info->last_stratum); cg_rlock(&pool->data_lock); info->pool_no = pool->pool_no; copy_pool_stratum(info, pool); hashratio_stratum_pkgs(hashratio, pool); cg_runlock(&pool->data_lock); /* Configure the parameter from outside */ memset(send_pkg.data, 0, HRTO_P_DATA_LEN); // fan. We're not measuring temperature so set a safe but not max value info->fan_pwm = HRTO_PWM_MAX * 2 / 3; tmp = be32toh(info->fan_pwm); memcpy(send_pkg.data, &tmp, 4); // freq tmp = be32toh(info->default_freq); memcpy(send_pkg.data + 4, &tmp, 4); applog(LOG_DEBUG, "set freq: %d", info->default_freq); /* Configure the nonce2 offset and range */ range = 0xffffffff / (total_devices + 1); start = range * (hashratio->device_id + 1); tmp = be32toh(start); memcpy(send_pkg.data + 8, &tmp, 4); tmp = be32toh(range); memcpy(send_pkg.data + 12, &tmp, 4); /* Package the data */ hashratio_init_pkg(&send_pkg, HRTO_P_SET, 1, 1); hashratio_send_pkgs(hashratio, &send_pkg); }
static int64_t avalon2_scanhash(struct thr_info *thr) { struct avalon2_pkg send_pkg; struct timeval current_stratum; struct pool *pool; struct cgpu_info *avalon2 = thr->cgpu; struct avalon2_info *info = avalon2->device_data; int64_t h; uint32_t tmp, range, start; int i; if (thr->work_restart || thr->work_update || !info->first) { applog(LOG_DEBUG, "Avalon2: New stratum: restart: %d, update: %d, first: %d", thr->work_restart, thr->work_update, info->first); thr->work_update = false; thr->work_restart = false; get_work(thr, thr->id); /* Make sure pool is ready */ pool = current_pool(); if (!pool->has_stratum) quit(1, "Avalon2: Miner Manager have to use stratum pool"); if (pool->coinbase_len > AVA2_P_COINBASE_SIZE) { applog(LOG_ERR, "Avalon2: Miner Manager pool coinbase length have to less then %d", AVA2_P_COINBASE_SIZE); return 0; } if (pool->merkles > AVA2_P_MERKLES_COUNT) { applog(LOG_ERR, "Avalon2: Miner Manager merkles have to less then %d", AVA2_P_MERKLES_COUNT); return 0; } cgtime(&info->last_stratum); cg_rlock(&pool->data_lock); info->pool_no = pool->pool_no; copy_pool_stratum(pool); avalon2_stratum_pkgs(info->fd, pool, thr); cg_runlock(&pool->data_lock); /* Configuer the parameter from outside */ adjust_fan(info); info->set_voltage = opt_avalon2_voltage_min; info->set_frequency = opt_avalon2_freq_min; /* Set the Fan, Voltage and Frequency */ memset(send_pkg.data, 0, AVA2_P_DATA_LEN); tmp = be32toh(info->fan_pwm); memcpy(send_pkg.data, &tmp, 4); applog(LOG_ERR, "Avalon2: Temp max: %d, Cut off temp: %d", get_current_temp_max(info), opt_avalon2_overheat); if (get_current_temp_max(info) >= opt_avalon2_overheat) tmp = encode_voltage(0); else tmp = encode_voltage(info->set_voltage); tmp = be32toh(tmp); memcpy(send_pkg.data + 4, &tmp, 4); tmp = be32toh(info->set_frequency); memcpy(send_pkg.data + 8, &tmp, 4); /* Configure the nonce2 offset and range */ range = 0xffffffff / total_devices; start = range * avalon2->device_id; tmp = be32toh(start); memcpy(send_pkg.data + 12, &tmp, 4); tmp = be32toh(range); memcpy(send_pkg.data + 16, &tmp, 4); /* Package the data */ avalon2_init_pkg(&send_pkg, AVA2_P_SET, 1, 1); while (avalon2_send_pkg(info->fd, &send_pkg, thr) != AVA2_SEND_OK) ; if (unlikely(info->first < 2)) info->first++; } /* Stop polling the device if there is no stratum in 3 minutes, network is down */ cgtime(¤t_stratum); if (tdiff(¤t_stratum, &(info->last_stratum)) > (double)(3.0 * 60.0)) return 0; polling(thr); h = 0; for (i = 0; i < AVA2_DEFAULT_MODULARS; i++) { h += info->enable[i] ? (info->local_work[i] - info->hw_work[i]) : 0; } return h * 0xffffffff; }
/*===========================================================================* * main * *===========================================================================*/ int main(int argc, char **argv) { /* This is the main routine of this service. The main loop consists of * three major activities: getting new work, processing the work, and * sending the reply. The loop never terminates, unless a panic occurs. */ message m_in; int result; sef_startup(); vector_init(&sem_list); Qvector_init(&waiting_list); stackInit(&sem_stack,5); /* Main loop - get work and do it, forever. */ while (TRUE) { /* Wait for incoming message, sets 'callnr' and 'who'. */ get_work(&m_in); //printf("SEM recieved message %d\n",callnr); if (is_notify(callnr)) { printf("SEM: warning, got illegal notify from: %d\n", m_in.m_source); result = EINVAL; goto send_reply; } int arg = m_in.m1_i1; switch(callnr) { case SEM_INIT: //printf("Sem_init called, semaphore size 3%d.\n",arg); result = sem_init(arg); break; case SEM_UP: //printf("Sem_up called on semaphore %d.\n",arg); result = sem_up(arg); break; case SEM_DOWN: //printf("Sem_down called on semaphore %d. source: %d\n",arg,who_e); result = sem_down(arg,m_in.m_source); break; case SEM_RELEASE: //printf("Sem_release called on semaphore %d.\n",arg); result = sem_release(arg); break; default: printf("SEMAPHORE: warning, got illegal request from %d\n", m_in.m_source); result = EINVAL; } send_reply: /* Finally send reply message, unless disabled. */ if (result != EDONTREPLY) { m_in.m_type = result; /* build reply message */ reply(who_e, &m_in); /* send it away */ } } Qvector_free(&waiting_list); vector_free(&sem_list); return(OK); /* shouldn't come here */ }
void master(const struct fracInfo info) { int ntasks, dest, msgsize; struct fracData *work = malloc(sizeof(*work)); MPI_Status status; int rowsTaken = 0; MPI_Comm_size(MPI_COMM_WORLD, &ntasks); size_t size = sizeof(unsigned char) * (unsigned long)info.nCols * (unsigned long)info.nRows; unsigned char *fractal = (unsigned char*)malloc(size); if(!fractal) { printf("fractal allocation failed, %lu bytes\n", size); exit(1); } // Allocate buffer int membersize, emptysize, fullsize; int position; char *buffer; MPI_Pack_size(1, MPI_INT, MPI_COMM_WORLD, &membersize); emptysize = membersize; MPI_Pack_size(1, MPI_INT, MPI_COMM_WORLD, &membersize); emptysize += membersize; MPI_Pack_size(get_max_work_size(&info), MPI_UNSIGNED_CHAR, MPI_COMM_WORLD, &membersize); fullsize = emptysize + membersize; buffer = malloc(fullsize); if(!buffer) { printf("buffer allocation failed, %d bytes\n",fullsize); exit(1); } // Send initial data for (dest = 1; dest < ntasks; dest++) { //Get next work item get_work(&info,&rowsTaken,work); //pack and send work position = 0; MPI_Pack(&work->startRow,1,MPI_INT,buffer,emptysize,&position,MPI_COMM_WORLD); MPI_Pack(&work->nRows,1,MPI_INT,buffer,emptysize,&position,MPI_COMM_WORLD); MPI_Send(buffer, position, MPI_PACKED, dest, WORKTAG, MPI_COMM_WORLD); } printf("sent initial work\n"); //Get next work item get_work(&info,&rowsTaken,work); int startRow, nRows; while(work->nRows) { // Recieve and unpack work MPI_Recv(buffer, fullsize, MPI_PACKED, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); position = 0; MPI_Get_count(&status, MPI_PACKED, &msgsize); MPI_Unpack(buffer, msgsize, &position, &startRow,1,MPI_INT,MPI_COMM_WORLD); MPI_Unpack(buffer, msgsize, &position, &nRows,1,MPI_INT,MPI_COMM_WORLD); MPI_Unpack(buffer, msgsize, &position, fractal+((unsigned long)startRow*info.nCols), nRows*info.nCols, MPI_UNSIGNED_CHAR, MPI_COMM_WORLD); //pack and send work position = 0; MPI_Pack(&work->startRow,1,MPI_INT,buffer,emptysize,&position,MPI_COMM_WORLD); MPI_Pack(&work->nRows,1,MPI_INT,buffer,emptysize,&position,MPI_COMM_WORLD); MPI_Send(buffer, position, MPI_PACKED, status.MPI_SOURCE, WORKTAG, MPI_COMM_WORLD); //Get next work item get_work(&info,&rowsTaken,work); if(status.MPI_SOURCE==1) printf("%d\n",work->startRow); } // Recieve all remaining work for (dest = 1; dest < ntasks; dest++) { // Recieve and unpack work MPI_Recv(buffer, fullsize, MPI_PACKED, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); position = 0; MPI_Get_count(&status, MPI_PACKED, &msgsize); MPI_Unpack(buffer, msgsize, &position, &startRow,1,MPI_INT,MPI_COMM_WORLD); MPI_Unpack(buffer, msgsize, &position, &nRows,1,MPI_INT,MPI_COMM_WORLD); // unpack pixel data MPI_Unpack(buffer, msgsize, &position, fractal+((unsigned long)startRow*info.nCols), nRows*info.nCols, MPI_UNSIGNED_CHAR, MPI_COMM_WORLD); // Kill slaves MPI_Send(0,0,MPI_INT,dest,DIETAG,MPI_COMM_WORLD); } free(work); free(buffer); //Save image as TIFF unsigned int nx = info.nCols; unsigned int ny = info.nRows; char fileName[] = "/home/pi/Mandelbrot/Mandelbrot.tiff"; TIFF *out = TIFFOpen(fileName, "w"); uint32 tileDim = 256; tsize_t tileBytes = tileDim*tileDim*sizeof(char); unsigned char *buf = (unsigned char *)_TIFFmalloc(tileBytes); char description[1024]; snprintf(description, sizeof(description),"xStart:%f yStart:%f spacing:%f AAx:%d",info.xStart,info.yStart,info.spacing,info.AA); TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, description); TIFFSetField(out, TIFFTAG_IMAGEWIDTH, (uint32) nx); TIFFSetField(out, TIFFTAG_IMAGELENGTH, (uint32) ny); TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 1); TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8); TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_LZW); TIFFSetField(out, TIFFTAG_TILEWIDTH, tileDim); TIFFSetField(out, TIFFTAG_TILELENGTH, tileDim); // TIFFSetField(out, TIFFTAG_PREDICTOR, PREDICTOR_HORIZONTAL); // TIFFSetField(out, TIFFTAG_XRESOLUTION, resolution); // TIFFSetField(out, TIFFTAG_YRESOLUTION, resolution); // TIFFSetField(out, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); unsigned long x,y,i,j; unsigned long tileStart; // Iterate through and write tiles for(y=0; y<ny; y+=tileDim) { for(x=0; x<nx; x+=tileDim) { // Fill tile with fractal data tileStart = y*nx+x; for(i=0; i<tileDim; i++) { for(j=0; j<tileDim; j++) { if(x+j < nx && y+i < ny) buf[i*tileDim+j] = fractal[(y+i)*nx+(x+j)]; else buf[i*tileDim+j] = (unsigned char)0; } } TIFFWriteTile(out, buf, x, y, 0, 0); } } TIFFClose(out); _TIFFfree(buf); free(fractal); }
static void *miner_thread(void *userdata) { struct thr_info *mythr = userdata; int thr_id = mythr->id; uint32_t max_nonce = 0xffffff; /* Set worker threads to nice 19 and then preferentially to SCHED_IDLE * and if that fails, then SCHED_BATCH. No need for this to be an * error if it fails */ setpriority(PRIO_PROCESS, 0, 19); drop_policy(); /* Cpu affinity only makes sense if the number of threads is a multiple * of the number of CPUs */ if (!(opt_n_threads % num_processors)) affine_to_cpu(mythr->id, mythr->id % num_processors); while (1) { struct work work __attribute__((aligned(128))); uint64_t hashes_done; struct timeval tv_start, tv_end, diff; uint64_t max64; bool rc; /* obtain new work from internal workio thread */ if (unlikely(!get_work(mythr, &work))) { applog(LOG_ERR, "work retrieval failed, exiting " "mining thread %d", mythr->id); goto out; } hashes_done = 0; gettimeofday(&tv_start, NULL); rc = scanhash(thr_id, work.data, work.target, max_nonce, &hashes_done); /* record scanhash elapsed time */ gettimeofday(&tv_end, NULL); timeval_subtract(&diff, &tv_end, &tv_start); hashmeter(thr_id, &diff, hashes_done); /* adjust max_nonce to meet target scan time */ if (diff.tv_usec > 500000) diff.tv_sec++; if (diff.tv_sec > 0) { max64 = (hashes_done / 65536 * opt_scantime) / diff.tv_sec; if (max64 > 0xfffffffaULL) max64 = 0xfffffffaULL; max_nonce = max64; } /* if nonce found, submit work */ if (rc && !submit_work(mythr, &work)) break; } out: tq_freeze(mythr->q); return NULL; }
/* ------------------- */ void init_rsc(void) { OBJECT *form; register int i, j; rsrc_gaddr(ROOT, SONDER_Z, &form); form[LINE3].ob_spec.free_string[1] = 0; form[LINEA].ob_spec.free_string[31] = 0x7F; for (i = LINE3; i <= LINEA; i++) for (j = 1; j < 33; j += 2) form[i].ob_spec.free_string[j] += 0x80; *form[SOND_EDT].ob_spec.tedinfo->te_ptext = 0; rsrc_gaddr(ROOT, SET_FONT, &form); form[FONT_S].ob_state |= SELECTED; rsrc_gaddr(ROOT, EINRUECK, &form); *form[EINR_NUM].ob_spec.tedinfo->te_ptext = 0; rsrc_gaddr(ROOT, FIND_REP, &form); form[SR_CURSR].ob_state |= SELECTED; form[SR_CRDWN].ob_state |= SELECTED; *form[FIND_STR].ob_spec.tedinfo->te_ptext = 0; *form[REPL_STR].ob_spec.tedinfo->te_ptext = 0; rsrc_gaddr(ROOT, DISK_FMT, &form); form[DRIVE_A].ob_state |= SELECTED; form[NORM_FMT].ob_state |= SELECTED; form[ONE_SIDE].ob_state |= SELECTED; rsrc_gaddr(ROOT, PRT_MENU, &form); form[TO_PRINT].ob_state |= SELECTED; form[NO_INHLT].ob_state |= SELECTED; form[NO_INDEX].ob_state |= SELECTED; form[PRT_PICS].ob_state |= SELECTED; form[NO_MAIL].ob_state |= SELECTED; form[PRT_DRFT].ob_state |= SELECTED; form[PRT_TEXT].ob_state |= SELECTED; rsrc_gaddr(ROOT, NOTE_DIA, &form); form[N_LOCK].ob_state |= SELECTED; for (i = N_LINE2; i <= N_LINE7; i++) { form[i].ob_spec.tedinfo->te_ptmplt = form[N_LINE1].ob_spec.tedinfo->te_ptmplt; form[i].ob_spec.tedinfo->te_pvalid = form[N_LINE1].ob_spec.tedinfo->te_pvalid; form[i].ob_spec.tedinfo->te_txtlen = 40; form[i].ob_spec.tedinfo->te_tmplen = 40; } rsrc_gaddr(ROOT, NEW_RULR, &form); *form[TAB_WDTH].ob_spec.tedinfo->te_ptext = 0; rsrc_gaddr(ROOT, TXT_INFO, &form); form[EINZ_SWT].ob_state |= SELECTED; form[PASS_SWT].ob_state |= SELECTED; for (i = TI_LINE1; i <= TI_LINE9; i++) { form[i].ob_spec.tedinfo->te_ptmplt = form[TI_LINE1].ob_spec.tedinfo->te_ptmplt; form[i].ob_spec.tedinfo->te_pvalid = form[TI_LINE1].ob_spec.tedinfo->te_pvalid; form[i].ob_spec.tedinfo->te_tmplen = 40; form[i].ob_spec.tedinfo->te_txtlen = 40; } form[TI_LINEA].ob_spec.tedinfo->te_txtlen = 34; form[TI_BEARE].ob_spec.tedinfo->te_txtlen = 29; rsrc_gaddr(ROOT, KOPFFUSS, &form); for (i = 0; i < 12; i++) { form[kf_anp[i]].ob_spec.tedinfo->te_ptmplt = form[G_LFT_1].ob_spec.tedinfo->te_ptmplt; form[kf_anp[i]].ob_spec.tedinfo->te_pvalid = form[G_LFT_1].ob_spec.tedinfo->te_pvalid; form[kf_anp[i]].ob_spec.tedinfo->te_txtlen = 26; form[kf_anp[i]].ob_spec.tedinfo->te_tmplen = 26; } rsrc_gaddr(ROOT, FLOSKEL, &form); for (i = FLSK_L1; i <= FLSK_L5; i++) { form[i].ob_spec.tedinfo->te_ptmplt = form[FLSK_L1].ob_spec.tedinfo->te_ptmplt; form[i].ob_spec.tedinfo->te_pvalid = form[FLSK_L1].ob_spec.tedinfo->te_pvalid; form[i].ob_spec.tedinfo->te_tmplen = 40; form[i].ob_spec.tedinfo->te_txtlen = 40; } get_work(0); rsrc_gaddr(ROOT, BACKGRND, &back); back[ROOT].ob_x = wx; back[ROOT].ob_y = wy; back[ROOT].ob_width = ww; back[ROOT].ob_height = wh; ww = (ww - 20) / 10; wx += 10; wy = wh - back[F1].ob_height - 20; for (i = 0; i < 40; i += 4) { back[F1 + i].ob_x = wx; back[F1 + i].ob_y = wy; back[F1 + i].ob_width = ww; back[F1_BUT + i].ob_width = ww; back[F1_BUT + i].ob_type = G_BOX; back[F1_BUT].ob_spec.index |= 0xFF0000; back[F1_TXT + i].ob_width = ww; back[F1_TXT + i].ob_spec.tedinfo->te_ptext = f_text[((i < 36) ? i / 4 + 1 : 0)]; wx += ww; } wind_set(0, WF_NEWDESK, back, 0, 0); full_redraw(); }
static int64_t hfa_scanwork(struct thr_info *thr) { struct cgpu_info *hashfast = thr->cgpu; struct hashfast_info *info = hashfast->device_data; int jobs, ret, cycles = 0; int64_t hashes; if (unlikely(hashfast->usbinfo.nodev)) { applog(LOG_WARNING, "%s %d: device disappeared, disabling", hashfast->drv->name, hashfast->device_id); return -1; } if (unlikely(last_getwork - hashfast->last_device_valid_work > 60)) { applog(LOG_WARNING, "%s %d: No valid hashes for over 1 minute, attempting to reset", hashfast->drv->name, hashfast->device_id); if (info->hash_clock_rate > HFA_CLOCK_DEFAULT) { info->hash_clock_rate -= 5; if (info->hash_clock_rate < opt_hfa_hash_clock) opt_hfa_hash_clock = info->hash_clock_rate; applog(LOG_WARNING, "%s %d: Decreasing clock speed to %d with reset", hashfast->drv->name, hashfast->device_id, info->hash_clock_rate); } ret = hfa_reset(hashfast, info); if (!ret) { applog(LOG_ERR, "%s %d: Failed to reset after hash failure, disabling", hashfast->drv->name, hashfast->device_id); return -1; } applog(LOG_NOTICE, "%s %d: Reset successful", hashfast->drv->name, hashfast->device_id); } if (unlikely(thr->work_restart)) { restart: info->last_restart = time(NULL); thr->work_restart = false; ret = hfa_send_frame(hashfast, HF_USB_CMD(OP_WORK_RESTART), 0, (uint8_t *)NULL, 0); if (unlikely(!ret)) { ret = hfa_reset(hashfast, info); if (unlikely(!ret)) { applog(LOG_ERR, "%s %d: Failed to reset after write failure, disabling", hashfast->drv->name, hashfast->device_id); return -1; } } /* Give a full allotment of jobs after a restart, not waiting * for the status update telling us how much to give. */ jobs = info->usb_init_base.inflight_target; } else { /* Only adjust die clocks if there's no restart since two * restarts back to back get ignored. */ hfa_temp_clock(hashfast, info); jobs = hfa_jobs(hashfast, info); } /* Wait on restart_wait for up to 0.5 seconds or submit jobs as soon as * they're required. */ while (!jobs && ++cycles < 5) { ret = restart_wait(thr, 100); if (unlikely(!ret)) goto restart; jobs = hfa_jobs(hashfast, info); } if (jobs) { applog(LOG_DEBUG, "%s %d: Sending %d new jobs", hashfast->drv->name, hashfast->device_id, jobs); } while (jobs-- > 0) { struct hf_hash_usb op_hash_data; struct work *work; uint64_t intdiff; int i, sequence; uint32_t *p; /* This is a blocking function if there's no work */ work = get_work(thr, thr->id); /* Assemble the data frame and send the OP_HASH packet */ memcpy(op_hash_data.midstate, work->midstate, sizeof(op_hash_data.midstate)); memcpy(op_hash_data.merkle_residual, work->data + 64, 4); p = (uint32_t *)(work->data + 64 + 4); op_hash_data.timestamp = *p++; op_hash_data.bits = *p++; op_hash_data.starting_nonce = 0; op_hash_data.nonce_loops = 0; op_hash_data.ntime_loops = 0; /* Set the number of leading zeroes to look for based on diff. * Diff 1 = 32, Diff 2 = 33, Diff 4 = 34 etc. */ intdiff = (uint64_t)work->device_diff; for (i = 31; intdiff; i++, intdiff >>= 1); op_hash_data.search_difficulty = i; op_hash_data.group = 0; if ((sequence = info->hash_sequence_head + 1) >= info->num_sequence) sequence = 0; ret = hfa_send_frame(hashfast, OP_HASH, sequence, (uint8_t *)&op_hash_data, sizeof(op_hash_data)); if (unlikely(!ret)) { ret = hfa_reset(hashfast, info); if (unlikely(!ret)) { applog(LOG_ERR, "%s %d: Failed to reset after write failure, disabling", hashfast->drv->name, hashfast->device_id); return -1; } } mutex_lock(&info->lock); info->hash_sequence_head = sequence; info->works[info->hash_sequence_head] = work; mutex_unlock(&info->lock); applog(LOG_DEBUG, "%s %d: OP_HASH sequence %d search_difficulty %d work_difficulty %g", hashfast->drv->name, hashfast->device_id, info->hash_sequence_head, op_hash_data.search_difficulty, work->work_difficulty); } /* Only count 2/3 of the hashes to smooth out the hashrate for cycles * that have no hashes added. */ mutex_lock(&info->lock); hashes = info->hash_count / 3 * 2; info->calc_hashes += hashes; info->hash_count -= hashes; mutex_unlock(&info->lock); return hashes; }
static void spondoolies_update_work_sp50(struct cgpu_info *cgpu) { struct spond_adapter *device = cgpu->device_data; struct thr_info *thr = cgpu->thr[0]; struct work *work = NULL; struct pool *pool = NULL; // setup thread flags SPONDLOG(LOG_DEBUG, "New stratum: restart: %d, update: %d", thr->work_restart, thr->work_update); thr->work_update = false; thr->work_restart = false; work = get_work(thr, thr->id); /* Make sure pool is ready */ discard_work(work); /* Don't leak memory */ // lets check pool job parameters pool = current_pool(); if (!pool->has_stratum) { quit(1, "%s: Miner Manager have to use stratum pool", sp50_drv.dname); } if (pool->coinbase_len > SPOND_MAX_COINBASE_LEN) { SPONDLOG(LOG_ERR, "Miner Manager pool coinbase length[%d] have to less then %d", pool->coinbase_len, SPOND_MAX_COINBASE_LEN); return; } if (pool->merkles > SPOND_MAX_MERKLES) { SPONDLOG(LOG_ERR, "Miner Manager merkles have to less then %d", SPOND_MAX_MERKLES); return; } // need to lock driver, since we may drop all jobs // ######### DEVICE LOCK // pthread_mutex_lock(&device->lock); // lock and copy pool data // in our case pool_no is always same number // but swork.job_id changes each job cg_rlock(&pool->data_lock); copy_pool_stratum(device, pool); cg_runlock(&pool->data_lock); /* * fill job and send it to miner */ pxgate_req_packet req_packet; memset(&req_packet, 0, sizeof(req_packet)); req_packet.header.protocol_version = pxgate_PROTOCOL_VERSION; req_packet.header.message_type = pxgate_MESSAGE_TYPE_JOB_REQ; req_packet.header.message_size = sizeof(req_packet)-sizeof(req_packet.header); // TODO: use MACRO req_packet.mask = 0x01; // 0x01 = first request, 0x2 = drop old work if (device->drop_old_jobs) { req_packet.mask |= 0x02; // drop old work device->drop_old_jobs = 0; } // currently we will send only one job fill_pxgate_request(&req_packet.req, cgpu); // ######### DEVICE UNLOCK // pthread_mutex_unlock(&device->lock); do_write(device->socket_fd, &req_packet, sizeof(req_packet)); /* * read the response from miner */ pxgate_gen_packet rsp_packet; uint32_t size = 0; if ((size = do_read_packet(device->socket_fd, &rsp_packet, sizeof(rsp_packet))) != sizeof(rsp_packet)) { quit(1, "%s: critical error, packet sent from miner is bad received size[%u] expected [%u], quiting...", sp50_drv.dname, size, sizeof(rsp_packet) ); } switch (rsp_packet.header.message_type) { case pxgate_MESSAGE_TYPE_JOB_REQ_ACK: SPONDLOG(LOG_DEBUG, "pxgate_MESSAGE_TYPE_JOB_REQ_ACK"); break; case pxgate_MESSAGE_TYPE_JOB_REQ_REJ: SPONDLOG(LOG_DEBUG, "pxgate_MESSAGE_TYPE_JOB_REQ_REJ"); break; default: SPONDLOG(LOG_ERR, "unexpected type[%x]", rsp_packet.header.message_type); return; } /* * everything is ok, we cache the job */ device->current_job_id = (device->current_job_id++) % MAX_SW_JOB_INDEX_IN_MINERGATE; }
/*===========================================================================* * main * *===========================================================================*/ int main(void) { /* This is the main routine of this service. The main loop consists of * three major activities: getting new work, processing the work, and * sending the reply. The loop never terminates, unless a panic occurs. */ message m; /* request message */ int ipc_status; /* status code */ int call_nr, who_e,who_p; /* call number and caller */ int result; /* result to return */ int s; /* SEF local startup. */ sef_local_startup(); if (OK != (s=sys_getmachine(&machine))) panic("couldn't get machine info: %d", s); if (OK != (s=sys_getkinfo(&kinfo))) panic("couldn't get kernel kinfo: %d", s); /* Main loop - get work and do it, forever. */ while (TRUE) { /* Wait for request message. */ get_work(&m, &ipc_status); who_e = m.m_source; if(rs_isokendpt(who_e, &who_p) != OK) { panic("message from bogus source: %d", who_e); } call_nr = m.m_type; //if(who_e == 11)printf("Message for SEM recieved in RS\n"); /* Now determine what to do. Four types of requests are expected: * - Heartbeat messages (notifications from registered system services) * - System notifications (synchronous alarm) * - User requests (control messages to manage system services) * - Ready messages (reply messages from registered services) */ /* Notification messages are control messages and do not need a reply. * These include heartbeat messages and system notifications. */ if (is_ipc_notify(ipc_status)) { switch (who_p) { case CLOCK: do_period(&m); /* check services status */ continue; default: /* heartbeat notification */ if (rproc_ptr[who_p] != NULL) { /* mark heartbeat time */ rproc_ptr[who_p]->r_alive_tm = m.NOTIFY_TIMESTAMP; } else { printf("RS: warning: got unexpected notify message from %d\n", m.m_source); } } } /* If we get this far, this is a normal request. * Handle the request and send a reply to the caller. */ else { if (call_nr != COMMON_GETSYSINFO && (call_nr < RS_RQ_BASE || call_nr >= RS_RQ_BASE+0x100)) { /* Ignore invalid requests. Do not try to reply. */ printf("RS: warning: got invalid request %d from endpoint %d\n", call_nr, m.m_source); continue; } /* Handler functions are responsible for permission checking. */ switch(call_nr) { /* User requests. */ case RS_UP: result = do_up(&m); break; case RS_DOWN: result = do_down(&m); break; case RS_REFRESH: result = do_refresh(&m); break; case RS_RESTART: result = do_restart(&m); break; case RS_SHUTDOWN: result = do_shutdown(&m); break; case RS_UPDATE: result = do_update(&m); break; case RS_CLONE: result = do_clone(&m); break; case RS_EDIT: result = do_edit(&m); break; case COMMON_GETSYSINFO: result = do_getsysinfo(&m); break; case RS_LOOKUP: result = do_lookup(&m); break; /* Ready messages. */ case RS_INIT: result = do_init_ready(&m); break; case RS_LU_PREPARE: result = do_upd_ready(&m); break; default: printf("RS: warning: got unexpected request %d from %d\n", m.m_type, m.m_source); result = EINVAL; } /* Finally send reply message, unless disabled. */ if (result != EDONTREPLY) { m.m_type = result; reply(who_e, NULL, &m); } } } }
/*===========================================================================* * main * *===========================================================================*/ int main(int argc, char *argv[]) { /* This is the main routine of this service. The main loop consists of * three major activities: getting new work, processing the work, and * sending the reply. The loop never terminates, unless a panic occurs. */ int ind, do_reply, transid; message pfs_m_in; message pfs_m_out; /* SEF local startup. */ env_setargs(argc, argv); sef_local_startup(); while(!unmountdone || !exitsignaled) { endpoint_t src; do_reply = 1; /* Wait for request message. */ get_work(&pfs_m_in); transid = TRNS_GET_ID(pfs_m_in.m_type); pfs_m_in.m_type = TRNS_DEL_ID(pfs_m_in.m_type); if (pfs_m_in.m_type == 0) { assert(!IS_VFS_FS_TRANSID(transid)); pfs_m_in.m_type = transid; transid = 0; } else assert(IS_VFS_FS_TRANSID(transid) || transid == 0); src = pfs_m_in.m_source; caller_uid = INVAL_UID; /* To trap errors */ caller_gid = INVAL_GID; req_nr = pfs_m_in.m_type; if (IS_DEV_RQ(req_nr)) { ind = req_nr - DEV_RQ_BASE; if (ind < 0 || ind >= DEV_CALL_VEC_SIZE) { printf("pfs: bad DEV request %d\n", req_nr); pfs_m_out.m_type = EINVAL; } else { int result; result = (*dev_call_vec[ind])(&pfs_m_in, &pfs_m_out); if (pfs_m_out.REP_STATUS == SUSPEND || result == SUSPEND) { /* Nothing to tell, so not replying */ do_reply = 0; } } } else if (IS_VFS_RQ(req_nr)) { ind = req_nr - VFS_BASE; if (ind < 0 || ind >= FS_CALL_VEC_SIZE) { printf("pfs: bad FS request %d\n", req_nr); pfs_m_out.m_type = EINVAL; } else { pfs_m_out.m_type = (*fs_call_vec[ind])(&pfs_m_in, &pfs_m_out); } } else { printf("pfs: bad request %d\n", req_nr); pfs_m_out.m_type = EINVAL; } if (do_reply) { if (IS_VFS_RQ(req_nr) && IS_VFS_FS_TRANSID(transid)) { pfs_m_out.m_type = TRNS_ADD_ID(pfs_m_out.m_type, transid); } reply(src, &pfs_m_out); } } return(OK); }
static int64_t avalon2_scanhash(struct thr_info *thr) { struct avalon2_pkg send_pkg; struct pool *pool; struct cgpu_info *avalon2 = thr->cgpu; struct avalon2_info *info = avalon2->device_data; int64_t h; uint32_t tmp, range, start; int i; if (thr->work_restart || thr->work_update || info->first) { info->new_stratum = true; applog(LOG_DEBUG, "Avalon2: New stratum: restart: %d, update: %d, first: %d", thr->work_restart, thr->work_update, info->first); thr->work_update = false; thr->work_restart = false; if (unlikely(info->first)) info->first = false; get_work(thr, thr->id); /* Make sure pool is ready */ pool = current_pool(); if (!pool->has_stratum) quit(1, "Avalon2: Miner Manager have to use stratum pool"); if (pool->swork.cb_len > AVA2_P_COINBASE_SIZE) quit(1, "Avalon2: Miner Manager pool coinbase length have to less then %d", AVA2_P_COINBASE_SIZE); if (pool->swork.merkles > AVA2_P_MERKLES_COUNT) quit(1, "Avalon2: Miner Manager merkles have to less then %d", AVA2_P_MERKLES_COUNT); info->diff = (int)pool->swork.diff - 1; info->pool_no = pool->pool_no; cg_wlock(&pool->data_lock); avalon2_stratum_pkgs(info->fd, pool, thr); cg_wunlock(&pool->data_lock); /* Configuer the parameter from outside */ info->fan_pwm = opt_avalon2_fan_min; info->set_voltage = opt_avalon2_voltage_min; info->set_frequency = opt_avalon2_freq_min; /* Set the Fan, Voltage and Frequency */ memset(send_pkg.data, 0, AVA2_P_DATA_LEN); tmp = be32toh(info->fan_pwm); memcpy(send_pkg.data, &tmp, 4); tmp = encode_voltage(info->set_voltage); tmp = be32toh(tmp); memcpy(send_pkg.data + 4, &tmp, 4); tmp = be32toh(info->set_frequency); memcpy(send_pkg.data + 8, &tmp, 4); /* Configure the nonce2 offset and range */ range = 0xffffffff / total_devices; start = range * avalon2->device_id; tmp = be32toh(start); memcpy(send_pkg.data + 12, &tmp, 4); tmp = be32toh(range); memcpy(send_pkg.data + 16, &tmp, 4); /* Package the data */ avalon2_init_pkg(&send_pkg, AVA2_P_SET, 1, 1); while (avalon2_send_pkg(info->fd, &send_pkg, thr) != AVA2_SEND_OK) ; info->new_stratum = false; } polling(thr); h = 0; for (i = 0; i < AVA2_DEFAULT_MODULARS; i++) { h += info->local_work[i]; } return h * 0xffffffff; }
/*===========================================================================* * main * *===========================================================================*/ int main(void) { /* This is the main program of the file system. The main loop consists of * three major activities: getting new work, processing the work, and sending * the reply. This loop never terminates as long as the file system runs. */ int transid; struct worker_thread *wp; /* SEF local startup. */ sef_local_startup(); printf("Started VFS: %d worker thread(s)\n", NR_WTHREADS); /* This is the main loop that gets work, processes it, and sends replies. */ while (TRUE) { worker_yield(); /* let other threads run */ send_work(); /* The get_work() function returns TRUE if we have a new message to * process. It returns FALSE if it spawned other thread activities. */ if (!get_work()) continue; transid = TRNS_GET_ID(m_in.m_type); if (IS_VFS_FS_TRANSID(transid)) { wp = worker_get((thread_t) transid - VFS_TRANSID); if (wp == NULL || wp->w_fp == NULL) { printf("VFS: spurious message %d from endpoint %d\n", m_in.m_type, m_in.m_source); continue; } m_in.m_type = TRNS_DEL_ID(m_in.m_type); do_reply(wp); continue; } else if (who_e == PM_PROC_NR) { /* Calls from PM */ /* Special control messages from PM */ service_pm(); continue; } else if (is_notify(call_nr)) { /* A task ipc_notify()ed us */ switch (who_e) { case DS_PROC_NR: /* Start a thread to handle DS events, if no thread * is pending or active for it already. DS is not * supposed to issue calls to VFS or be the subject of * postponed PM requests, so this should be no problem. */ if (worker_can_start(fp)) handle_work(ds_event); break; case KERNEL: mthread_stacktraces(); break; case CLOCK: /* Timer expired. Used only for select(). Check it. */ expire_timers(m_in.m_notify.timestamp); break; default: printf("VFS: ignoring notification from %d\n", who_e); } continue; } else if (who_p < 0) { /* i.e., message comes from a task */ /* We're going to ignore this message. Tasks should * send ipc_notify()s only. */ printf("VFS: ignoring message from %d (%d)\n", who_e, call_nr); continue; } if (IS_BDEV_RS(call_nr)) { /* We've got results for a block device request. */ bdev_reply(); } else if (IS_CDEV_RS(call_nr)) { /* We've got results for a character device request. */ cdev_reply(); } else { /* Normal syscall. This spawns a new thread. */ handle_work(do_work); } } return(OK); /* shouldn't come here */ }
static int64_t serial_fpga_scanwork(struct thr_info *thr) { struct cgpu_info *serial_fpga; int fd; int ret; struct FPGA_INFO *info; unsigned char ob_bin[44], nonce_buf[SERIAL_READ_SIZE]; char *ob_hex; uint32_t nonce; int64_t hash_count; struct timeval tv_start, tv_finish, elapsed, tv_end, diff; int curr_hw_errors, i, j; uint32_t * ob; ob = (uint32_t *)ob_bin; int count; double Hs, W, fullnonce; int read_count; int64_t estimate_hashes; uint32_t values; int64_t hash_count_range; struct work *work; applog(LOG_DEBUG, "serial_fpga_scanwork..."); if (thr->cgpu->deven == DEV_DISABLED) return -1; serial_fpga = thr->cgpu; info = serial_fpga->device_data; work = get_work(thr, thr->id); if (info->device_fd == -1) { applog(LOG_INFO, "Attemping to Reopen Serial FPGA on %s", serial_fpga->device_path); fd = serial_open(serial_fpga->device_path, SERIAL_IO_SPEED, SERIAL_READ_TIMEOUT, false); if (unlikely(-1 == fd)) { applog(LOG_ERR, "Failed to open Serial FPGA on %s", serial_fpga->device_path); return -1; } else info->device_fd = fd; } fd = info->device_fd; memset(ob_bin, 0, sizeof(ob_bin)); // Currently, extra nonces are not supported // memset((unsigned char*)work->data + 144, 0, 12); // // calc_midstate(work); memcpy(ob_bin, work->midstate, 32); // Midstate memcpy(ob_bin + 32, work->data + 128, 12); // Remaining Bytes From Block Header // Send Bytes To FPGA In Reverse Order unsigned char swap[44]; uint32_t * sw; sw = (uint32_t *)swap; for (j=0; j<8; j++) { sw[j] = swab32(ob[j]); } memcpy(swap + 32, ob_bin + 32, 12); for (j=0; j<44; j++) { ob_bin[j] = swap[j]; } //unsigned char* b = (unsigned char*)(ob_bin); //applog(LOG_WARNING, "swap: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", b[28],b[29],b[30],b[31],b[32],b[33],b[34],b[35],b[36],b[37],b[38],b[39],b[40],b[41],b[42],b[43]); //applog(LOG_WARNING, "swap: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", b[0],b[1],b[2],b[3],b[4],b[5],b[6],b[7],b[8],b[9],b[10],b[11],b[12],b[13],b[14],b[15],b[16],b[17],b[18],b[19],b[20],b[21],b[22],b[23],b[24],b[25],b[26],b[27],b[28],b[29],b[30],b[31],b[32],b[33],b[34],b[35],b[36],b[37],b[38],b[39],b[40],b[41],b[42],b[43]); //#ifndef WIN32 // tcflush(fd, TCOFLUSH); //#endif // Send Data To FPGA ret = write(fd, ob_bin, sizeof(ob_bin)); if (ret != sizeof(ob_bin)) { applog(LOG_ERR, "%s%i: Serial Send Error (ret=%d)", serial_fpga->drv->name, serial_fpga->device_id, ret); serial_fpga_close(thr); dev_error(serial_fpga, REASON_DEV_COMMS_ERROR); return 0; } if (opt_debug) { ob_hex = bin2hex(ob_bin, sizeof(ob_bin)); applog(LOG_DEBUG, "Serial FPGA %d sent: %s", serial_fpga->device_id, ob_hex); free(ob_hex); } elapsed.tv_sec = 0; elapsed.tv_usec = 0; cgtime(&tv_start); applog(LOG_DEBUG, "%s%i: Begin Scan For Nonces", serial_fpga->drv->name, serial_fpga->device_id); while (thr && !thr->work_restart) { memset(nonce_buf,0,4); // Check Serial Port For 1/10 Sec For Nonce ret = read(fd, nonce_buf, SERIAL_READ_SIZE); // Calculate Elapsed Time cgtime(&tv_end); timersub(&tv_end, &tv_start, &elapsed); if (ret == 0) { // No Nonce Found if (elapsed.tv_sec > info->timeout) { applog(LOG_DEBUG, "%s%i: End Scan For Nonces - Time = %d sec", serial_fpga->drv->name, serial_fpga->device_id, elapsed.tv_sec); break; } continue; } else if (ret < SERIAL_READ_SIZE) { applog(LOG_ERR, "%s%i: Serial Read Error (ret=%d)", serial_fpga->drv->name, serial_fpga->device_id, ret); serial_fpga_close(thr); dev_error(serial_fpga, REASON_DEV_COMMS_ERROR); break; } memcpy((char *)&nonce, nonce_buf, SERIAL_READ_SIZE); #if !defined (__BIG_ENDIAN__) && !defined(MIPSEB) nonce = swab32(nonce); #endif curr_hw_errors = serial_fpga->hw_errors; applog(LOG_INFO, "%s%i: Nonce Found - %08X (%5.1fMhz)", serial_fpga->drv->name, serial_fpga->device_id, nonce, (double)(1/(info->Hs * 1000000))); submit_nonce(thr, work, nonce); // Update Hashrate if (serial_fpga->hw_errors == curr_hw_errors) info->Hs = ((double)(elapsed.tv_sec) + ((double)(elapsed.tv_usec))/((double)1000000)) / (double)nonce; } // Estimate Number Of Hashes hash_count = ((double)(elapsed.tv_sec) + ((double)(elapsed.tv_usec))/((double)1000000)) / info->Hs; free_work(work); return hash_count; }
// pool switching code bool pool_switch(int thr_id, int pooln) { int prevn = cur_pooln; bool algo_switch = false; struct pool_infos *prev = &pools[cur_pooln]; struct pool_infos* p = NULL; // save prev stratum connection infos (struct) if (prev->type & POOL_STRATUM) { // may not be the right moment to free, // to check if required on submit... stratum_free_job(&stratum); prev->stratum = stratum; } if (pooln < num_pools) { cur_pooln = pooln; p = &pools[cur_pooln]; } else { applog(LOG_ERR, "Switch to inexistant pool %d!", pooln); return false; } // save global attributes prev->allow_mininginfo = allow_mininginfo; prev->allow_gbt = allow_gbt; prev->check_dups = check_dups; pthread_mutex_lock(&stratum_work_lock); free(rpc_user); rpc_user = strdup(p->user); free(rpc_pass); rpc_pass = strdup(p->pass); free(rpc_url); rpc_url = strdup(p->url); short_url = p->short_url; // just a pointer, no alloc opt_scantime = p->scantime; opt_max_diff = p->max_diff; opt_max_rate = p->max_rate; opt_shares_limit = p->shares_limit; opt_time_limit = p->time_limit; want_stratum = have_stratum = (p->type & POOL_STRATUM) != 0; // yiimp stats reporting opt_stratum_stats = (strstr(p->pass, "stats") != NULL) || (strcmp(p->user, "benchmark") == 0); pthread_mutex_unlock(&stratum_work_lock); // algo "blind" switch without free, not proper // todo: barrier required to free algo resources if (p->algo != (int) opt_algo) { if (opt_algo != ALGO_AUTO) { algo_switch = true; pthread_mutex_lock(&stats_lock); for (int n=0; n<opt_n_threads; n++) thr_hashrates[n] = 0.; stats_purge_all(); if (check_dups) hashlog_purge_all(); pthread_mutex_unlock(&stats_lock); } opt_algo = (enum sha_algos) p->algo; } if (prevn != cur_pooln) { pool_switch_count++; net_diff = 0; g_work_time = 0; g_work.data[0] = 0; pool_is_switching = true; stratum_need_reset = true; // used to get the pool uptime firstwork_time = time(NULL); restart_threads(); // reset wait states for (int n=0; n<opt_n_threads; n++) conditional_state[n] = false; // restore flags allow_gbt = p->allow_gbt; allow_mininginfo = p->allow_mininginfo; check_dups = p->check_dups; if (want_stratum) { // temporary... until stratum code cleanup stratum = p->stratum; stratum.pooln = cur_pooln; // unlock the stratum thread tq_push(thr_info[stratum_thr_id].q, strdup(rpc_url)); applog(LOG_BLUE, "Switch to stratum pool %d: %s", cur_pooln, strlen(p->name) ? p->name : p->short_url); } else { applog(LOG_BLUE, "Switch to pool %d: %s", cur_pooln, strlen(p->name) ? p->name : p->short_url); } // will unlock the longpoll thread on /LP url receive want_longpoll = (p->type & POOL_LONGPOLL) || !(p->type & POOL_STRATUM); if (want_longpoll) { pthread_mutex_lock(&stratum_work_lock); // will issue a lp_url request to unlock the longpoll thread have_longpoll = false; get_work(&thr_info[0], &g_work); pthread_mutex_unlock(&stratum_work_lock); } } return true; }
static void *miner_thread(void *thr_id_int) { int thr_id = (unsigned long) thr_id_int; int failures = 0; uint32_t max_nonce = 0xffffff, max_nonce2; CURL *curl; if (opt_randomize) { srandom(time(0)); } curl = curl_easy_init(); if (!curl) { fprintf(stderr, "CURL initialization failed\n"); return NULL; } while (1) { struct work work __attribute__((aligned(128))); unsigned long hashes_done; struct timeval tv_start, tv_end, diff; bool rc; /* obtain new work from bitcoin */ if (!get_work(curl, &work)) { fprintf(stderr, "json_rpc_call failed, "); if ((opt_retries >= 0) && (++failures > opt_retries)) { fprintf(stderr, "terminating thread\n"); return NULL; /* exit thread */ } /* pause, then restart work loop */ fprintf(stderr, "retry after %d seconds\n", opt_fail_pause); sleep(opt_fail_pause); continue; } if (!validate_midstate(work.data, work.midstate)) { printf("SERVER PROBLEM: work.midstate does not equal SHA256 state after first 64-byte chunk\n"); } hashes_done = 0; gettimeofday(&tv_start, NULL); if (opt_randomize) { max_nonce2 = max_nonce*(1.0 + (double)random()/(RAND_MAX+1.0) - 0.5); } else { max_nonce2 = max_nonce; } /* scan nonces for a proof-of-work hash */ switch (opt_algo) { case ALGO_C: rc = scanhash_c(work.midstate, work.data + 64, work.hash1, work.hash, work.target, max_nonce2, &hashes_done); break; #ifdef WANT_SSE2_4WAY case ALGO_4WAY: { unsigned int rc4 = ScanHash_4WaySSE2(work.midstate, work.data + 64, work.hash1, work.hash, work.target, max_nonce2, &hashes_done); rc = (rc4 == -1) ? false : true; } break; #endif #ifdef WANT_VIA_PADLOCK case ALGO_VIA: rc = scanhash_via(work.data, work.target, max_nonce2, &hashes_done); break; #endif case ALGO_CRYPTOPP: rc = scanhash_cryptopp(work.midstate, work.data + 64, work.hash1, work.hash, work.target, max_nonce2, &hashes_done); break; #ifdef WANT_CRYPTOPP_ASM32 case ALGO_CRYPTOPP_ASM32: rc = scanhash_asm32(work.midstate, work.data + 64, work.hash1, work.hash, work.target, max_nonce2, &hashes_done); break; #endif default: /* should never happen */ return NULL; } /* record scanhash elapsed time */ gettimeofday(&tv_end, NULL); timeval_subtract(&diff, &tv_end, &tv_start); hashmeter(thr_id, &diff, hashes_done); /* adjust max_nonce to meet target scan time */ if (diff.tv_sec > (opt_scantime * 2)) max_nonce /= 2; /* large decrease */ else if ((diff.tv_sec > opt_scantime) && (max_nonce > 1500000)) max_nonce -= 1000000; /* small decrease */ else if ((diff.tv_sec < opt_scantime) && (max_nonce < 0xffffec76)) max_nonce += 100000; /* small increase */ /* if nonce found, submit work */ if (rc) submit_work(curl, &work); failures = 0; } curl_easy_cleanup(curl); return NULL; }