void* lcs_length_pthreads(lcs_task_t* task) { int p = task->p; int r = task->r; prodcon_queue_t* q = task->q; grid_t* grid = task->grid; int w = ceil((double)grid->m / (p*p)); int h = ceil((double)grid->n / p); int y = r*h + 1; prodcon_queue_init( &q[r], ceil((double)grid->m /w) ); pthread_barrier_wait( task-> bar ); int next = 0; while( next <= grid->m ) { if(r == 0) { next = (next == 0 ? 1 : next + w); } else { next = queue_consume( &q[r] ); } //printf("%i: next=%i\n", r, next); if( next <= grid->m) { int x = next; if(x + w > grid->m) { w = grid->m - x + 1; } if(y + h > grid->n) { h = grid->n - y + 1; } // calculate this block //printf("%i: calc block y=[%i,%i], x=[%i,%i]\n", r, y, y + h - 1, x, x + w - 1); lcs_length_block(grid, y, x, h, w); } if(r != p - 1) { queue_produce( &q[r+1], next ); } } prodcon_queue_destroy( &q[r] ); }
void lcs_backtrack_pthreads(lcs_task_t* task) { int p = task->p; int r = task->r; prodcon_queue_t* q = task->q; grid_t* grid = task->grid; char* res = task->res; int h = ceil((double)grid->n / p); int y = r*h + 1; if(y + h > grid->n) { h = grid->n - y + 1; } prodcon_queue_init( &q[r], 2 ); pthread_barrier_wait( task->bar ); backtrack_state_t* state; if(r == p - 1) { state = malloc( sizeof(backtrack_state_t) ); state->i = grid->n; state->j = grid->m; state->pos = 0; state->res = res; } else { state = queue_consume( &q[r] ); } int min_i = r*h; int min_j = 0; lcs_backtrack_block(grid, state, min_i, min_j); if( r != 0 ) { queue_produce( &q[r-1], state ); } else { strrev(state->res); free( state ); } prodcon_queue_destroy( &q[r] ); }
void* dispatcher_main (void* arg) { int thread_id = *((int*)arg); free(arg); while (1) { printf("Waiting...\n"); char* name = (char*)malloc( MAX_REQUEST ); // Buffer for filename int fd; if ((fd = accept_connection()) < 0) { fprintf(stderr, "Connection failure.\n"); pthread_exit((void*)NULL); } printf("Got connection!\n"); if( get_request(fd, name) != 0) { // request error! fprintf( stderr, "get_request failed\n"); continue; } // create a request object. this is free'd in prefetch if caching is enabled // or worker if not. request_t* req = (request_t*)malloc( sizeof(request_t) ); req->fd = fd; req->filename = name; req->req_num = server_stats_incr_req_num( &stats ); printf( "Dispatcher: putting request in queue\n" ); if (queue_produce( &request_queue, req ) == -1) { fprintf(stderr, "Dispatcher: error placing request in queue.\n"); } } }
void *producer_thread(void *data) { producer_data_t *pdata = (producer_data_t*)data; int c; ssize_t res = read(pdata->sockfd, &c, sizeof(c)); assert(res == sizeof(c)); c = ntohl((uint32_t)c); if (c < 0) { assert(c < -10); queue_close(pdata->q); close(pdata->closefd); } else { queue_produce(pdata->q, c); } close(pdata->sockfd); free(pdata); return NULL; }
int ctldev_handle(int ctrl_fd) { int rc; struct iscsi_uevent *ev; struct qelem *item; uiscsi_session_t *session = NULL; uiscsi_conn_t *conn = NULL; unsigned long recv_handle; struct nlmsghdr nlh; int ev_size; if ((rc = nl_read(ctrl_fd, &nlh, MSG_PEEK)) < 0) { log_error("can not read nlmsghdr, error %d", rc); return rc; } ev_size = nlh.nlmsg_len - NLMSG_ALIGN(sizeof(struct nlmsghdr)); recv_handle = (unsigned long)calloc(1, ev_size); if (!recv_handle) { log_error("can not allocate memory for receive handle"); return -ENOMEM; } log_debug(6, "message real length is %d bytes, recv_handle %p", nlh.nlmsg_len, (void*)recv_handle); if ((rc = nlpayload_read(ctrl_fd, (void*)recv_handle, ev_size, 0)) < 0) { log_error("can not read from NL socket, error %d", rc); return rc; } ev = (struct iscsi_uevent *)recv_handle; /* verify connection */ item = provider[0].sessions.q_forw; while (item != &provider[0].sessions) { int i; session = (uiscsi_session_t *)item; for (i=0; i<ISCSI_CNX_MAX; i++) { if (&session->cnx[i] == (uiscsi_conn_t*) iscsi_ptr(ev->r.recv_req.cnx_handle) || &session->cnx[i] == (uiscsi_conn_t*) iscsi_ptr(ev->r.cnxerror.cnx_handle)) { conn = &session->cnx[i]; break; } } item = item->q_forw; } if (ev->type == ISCSI_KEVENT_RECV_PDU) { if (conn == NULL) { log_error("could not verify connection 0x%p for " "event RECV_PDU", conn); return -ENXIO; } /* produce an event, so session manager will handle */ queue_produce(session->queue, EV_CNX_RECV_PDU, conn, sizeof(unsigned long), &recv_handle); actor_schedule(&session->mainloop); } else if (ev->type == ISCSI_KEVENT_CNX_ERROR) { if (conn == NULL) { log_error("could not verify connection 0x%p for " "event CNX_ERR", conn); return -ENXIO; } /* produce an event, so session manager will handle */ queue_produce(session->queue, EV_CNX_ERROR, conn, sizeof(unsigned long), (void*)&ev->r.cnxerror.error); actor_schedule(&session->mainloop); } else { log_error("unknown kernel event %d", ev->type); return -EEXIST; } return 0; }
void* worker_main (void* arg) { int thread_id = *((int*)arg); free(arg); while (1) { void* item = queue_consume( &request_queue ); // this happens only if queue_consume_all() was called and no items remain. if( item == (void*)-1 ) { printf( "Worker exiting.\n" ); pthread_exit( (void*)NULL ); } request_t* req = (request_t*)item; char* buf = NULL; // if cache is enabled then try to get the cached entry. int size = config.cache_enabled ? get_cache( req->filename, &buf ) : -1; int cache_hit = (size != -1); // if it wasn't a hit, try to get the data from file. if( !cache_hit ) { size = get_file_data( req->filename, &buf ); if( size == -1 ) { // file does not exist. send result and move on. log_message( thread_id, req->req_num, req->fd, cache_hit, req->filename, 404); return_error( req->fd, "404 - File not found" ); continue; } // if cache is enabled then put the value into the cache. if( config.cache_enabled ) { if( put_cache( req->filename, buf, size ) == -1 ) { // error. I think we can keep going? fprintf( stderr, "error putting into cache %s\n", req->filename ); // do not escape. this is not a fatal error, so continue sending // request to client. } } } char* content_type = get_content_type( req->filename ); // send result and log. log_message(thread_id, req->req_num, req->fd, cache_hit, req->filename, size); if (return_result( req->fd, content_type, buf, size ) != 0) { fprintf(stderr, "Error returning request to client."); } // only put stuff into prefetch if cache is enabled. otherwise just free the request. if( config.cache_enabled ) { if( queue_produce( &prefetch_queue, req ) == -1 ) { fprintf( stderr, "Error putting request into prefetch queue '%s'\n", req->filename ); } } else { // free request created by dispatch. free( req->filename ); free( req ); // free the buffer. free( buf ); } } }