u64 object_reserve_oid(Worker *worker) { assert(storage_server_count > 0); /* is someone else in the process of requesting new oids? */ while (object_reserve_wait != NULL) cond_wait(object_reserve_wait); /* do we need to request a fresh batch of oids? */ if (object_reserve_remaining == 0) { /* the first storage server is considered the master */ Transaction *trans = trans_new(storage_servers[0], NULL, message_new()); struct Rsreserve *res; pthread_cond_t *wait; trans->out->tag = ALLOCTAG; trans->out->id = TSRESERVE; wait = object_reserve_wait = cond_new(); send_request(trans); object_reserve_wait = NULL; cond_broadcast(wait); res = &trans->in->msg.rsreserve; object_reserve_next = res->firstoid; object_reserve_remaining = res->count; } object_reserve_remaining--; return object_reserve_next++; }
int session_mgr_start(session_mgr_t *mgr) { if (mgr == NULL) { LOG_ERROR("Invalid session mgr"); return ZISS_ERROR; } int is_ok = ZISS_ERROR; do { if (thread_new(&mgr->thread) == ZISS_ERROR) { LOG_ERROR("Fail to new thread"); break; } if (cond_new(&mgr->exit_cond) == ZISS_ERROR) { LOG_ERROR("Fail to new cond"); break; } if (thread_start(mgr->thread, _session_mgr_thread, mgr) == ZISS_ERROR) { cond_delete(mgr->exit_cond); LOG_ERROR("Fail to start thread"); break; } is_ok = ZISS_OK; } while (0); if (is_ok == ZISS_ERROR) { session_mgr_stop(mgr); } return is_ok; }
static void object_fetch_iter(struct object_fetch_env *env, Transaction *trans) { struct Rsread *res; int x; assert(trans->in != NULL && trans->in->id == RSREAD); res = &trans->in->msg.rsread; while (env->wait != NULL) cond_wait(env->wait); env->wait = cond_new(); unlock(); x = lseek(env->file->fd, trans->out->msg.tsread.offset, SEEK_SET); assert(x >= 0); x = write(env->file->fd, res->data, res->count); assert(res->count == (u32) x); lock(); raw_delete(trans->in->raw); trans->in->raw = NULL; cond_broadcast(env->wait); env->wait = NULL; }
void worker_create(void (*func)(Worker *, void *), void *arg) { if (null(worker_thread_pool)) { pthread_t newthread; pthread_attr_t attr; Worker *t = GC_NEW(Worker); assert(t != NULL); t->sleep = cond_new(); t->func = func; t->arg = arg; t->priority = worker_next_priority++; t->blocking = NULL; pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, max(PTHREAD_STACK_MIN, 1024 * 1024)); pthread_create(&newthread, &attr, (void *(*)(void *)) worker_loop, (void *) t); pthread_detach(newthread); } else { Worker *t = car(worker_thread_pool); worker_thread_pool = cdr(worker_thread_pool); t->func = func; t->arg = arg; t->priority = worker_next_priority++; t->blocking = NULL; if (!heap_isempty(worker_ready_to_run)) { /* wait for older threads that are ready to run */ worker_wake_up_next(); heap_add(worker_ready_to_run, t); } else { cond_signal(t->sleep); } } }