void Server::onDispatch(Event *e) { DBGENTER(_SERVER_DBG_LEV); AbsRTTask *newExe = sched_->getFirst(); DBGPRINT("Current situation"); DBGPRINT_2("newExe: ", taskname(newExe)); DBGPRINT_2("currExe_: ", taskname(currExe_)); if (newExe != currExe_) { if (currExe_ != NULL) currExe_->deschedule(); currExe_ = newExe; if (newExe != NULL) newExe->schedule(); //sched_->notify(newExe); } DBGPRINT_2("Now Running: ", taskname(newExe)); if (currExe_ == NULL) { sched_->notify(NULL); executing_releasing(); kernel->suspend(this); kernel->dispatch(); } }
int main(void) { int i, indx[NTASKS]; unsigned long mytask_name = nam2num("MASTER"); signal(SIGINT, endme); if (!(mytask = rt_task_init(mytask_name, 1, 0, 0))) { printf("CANNOT INIT TASK %lu\n", mytask_name); exit(1); } printf("MASTER INIT: name = %lu, address = %p.\n", mytask_name, mytask); sem = rt_sem_init(10000, 0); rt_set_oneshot_mode(); // rt_set_periodic_mode(); start_rt_timer(0); for (i = 0; i < ntasks; i++) { indx[i] = i; if (!(task[i] = rt_thread_create(thread_fun, &indx[i], 10000))) { printf("ERROR IN CREATING THREAD %d\n", indx[i]); exit(1); } } for (i = 0; i < ntasks; i++) { while (!rt_get_adr(taskname(i))) { rt_sleep(nano2count(20000000)); } } for (i = 0; i < ntasks; i++) { rt_send(rt_get_adr(taskname(i)), (unsigned long)sem); } for (i = 0; i < ntasks; i++) { rt_sem_wait(sem); } for (i = 0; i < ntasks; i++) { while (rt_get_adr(taskname(i))) { rt_sleep(nano2count(20000000)); } } for (i = 0; i < ntasks; i++) { rt_thread_join(task[i]); } rt_sem_delete(sem); stop_rt_timer(); rt_task_delete(mytask); printf("MASTER %lu %p ENDS\n", mytask_name, mytask); return 0; }
int Server_run() { int rc = 0; Server *srv = Server_queue_latest(); check(srv != NULL, "Failed to get a server from the configured queue."); int listen_fd = srv->listen_fd; taskname("SERVER"); while(RUNNING) { rc = Server_accept(listen_fd); if(rc == -1 && RUNNING) { log_err("Server accept failed, attempting to clear out dead weight: %d", RUNNING); int cleared = Register_cleanout(); if(cleared == 0) { taskdelay(1000); } } } return 0; error: return -1; }
thread_status_t Thread::bootstrap(void* _self) { Thread* self = (Thread*)_self; Log::debug("clc.thread", "Thread \"%s\" bootstrap", self->m_name.c_str()); self->m_stateChange.lock(); #ifdef USE_LIBTASK taskname((char*)"%s", self->m_name.c_str()); if (self->m_flags & DAEMON) tasksystem(); #elif defined(__BEOS__) || defined(__HAIKU__) // nothing #else if (self->m_flags & DAEMON) pthread_detach(self->m_thread); #endif Log::debug("clc.thread", "Thread \"%s\" is running", self->m_name.c_str()); self->m_state = RUNNING; self->m_stateChange.notify(); self->m_stateChange.unlock(); try { self->run(); } catch (...) { Log::warn("clc.thread", "Thread \"%s\" threw exception", self->m_name.c_str()); } Log::debug("clc.thread", "Thread \"%s\" is stopped", self->m_name.c_str()); self->m_stateChange.lock(); self->m_state = STOPPED; self->m_stateChange.notify(); self->m_stateChange.unlock(); #ifndef USE_LIBTASK return 0; #endif }
void tickertask(void *v) { (void)v; taskname("ticker"); while(!task_was_signaled()) { THE_CURRENT_TIME_IS = time(NULL); int min_wait = Setting_get_int("limits.tick_timer", 10); taskdelay(min_wait * 1000); // avoid doing this during a reload attempt if(!RELOAD) { // don't bother if these are all 0 int min_ping = Setting_get_int("limits.min_ping", DEFAULT_MIN_PING); int min_write_rate = Setting_get_int("limits.min_write_rate", DEFAULT_MIN_READ_RATE); int min_read_rate = Setting_get_int("limits.min_read_rate", DEFAULT_MIN_WRITE_RATE); if(min_ping > 0 || min_write_rate > 0 || min_read_rate > 0) { int cleared = Register_cleanout(); if(cleared > 0) { log_warn("Timeout task killed %d tasks, waiting %d seconds for more.", cleared, min_wait); } else { debug("No connections timed out."); } } // do a server queue cleanup to get rid of dead servers Server_queue_cleanup(); } } }
void server_task(void* arg) { struct cornet_config_t* config; struct client_config_t cconfig; int cfd, fd; char remote[16]; int rport; config = (struct cornet_config_t*)arg; if (!config->name) { config->name = "server_task"; } taskname(config->name); if ((fd = netannounce(config->istcp, config->server, config->port)) < 0) { fprintf(stderr, "cannot announce on tcp port %d: %s\n", config->port, strerror(errno)); taskexitall(1); } cconfig.h = config->h; while((cfd = netaccept(fd, remote, &rport)) >= 0){ fprintf(stderr, "connection from %s:%d\n", remote, rport); cconfig.fd = cfd; taskcreate(client_task, &cconfig, config->stack_size); } close(fd); printf("Exiting server task: %d\n", taskid()); }
void *thread_fun(void *arg) { RTIME start_time, period; RTIME t0, t; SEM *sem; RT_TASK *mytask; unsigned long mytask_name; int mytask_indx, jit, maxj, maxjp, count; mytask_indx = *((int *)arg); mytask_name = taskname(mytask_indx); cpus_allowed = 1 - cpus_allowed; if (!(mytask = rt_task_init_schmod(mytask_name, 1, 0, 0, SCHED_FIFO, 1 << cpus_allowed))) { printf("CANNOT INIT TASK %lu\n", mytask_name); exit(1); } printf("THREAD INIT: index = %d, name = %lu, address = %p.\n", mytask_indx, mytask_name, mytask); mlockall(MCL_CURRENT | MCL_FUTURE); if (!(mytask_indx%2)) { rt_make_hard_real_time(); } rt_receive(0, (unsigned long *)((void *)&sem)); period = nano2count(PERIOD); start_time = rt_get_time() + nano2count(10000000); rt_task_make_periodic(mytask, start_time + (mytask_indx + 1)*period, ntasks*period); // start of task body { count = maxj = 0; t0 = rt_get_cpu_time_ns(); while(count++ < LOOPS) { rt_task_wait_period(); t = rt_get_cpu_time_ns(); if ((jit = t - t0 - ntasks*(RTIME)PERIOD) < 0) { jit = -jit; } if (count > 1 && jit > maxj) { maxj = jit; } t0 = t; // rtai_print_to_screen("THREAD: index = %d, count %d\n", mytask_indx, count); } maxjp = (maxj + 499)/1000; } // end of task body rt_sem_signal(sem); if (!(mytask_indx%2)) { rt_make_soft_real_time(); } rt_task_delete(mytask); printf("THREAD %lu ENDS, LOOPS: %d MAX JIT: %d (us)\n", mytask_name, count, maxjp); return 0; }
int connection_identify_request(Connection *conn) { int next = CLOSE; if(Request_is_xml(conn->req)) { if(biseq(Request_path(conn->req), &POLICY_XML_REQUEST)) { debug("XML POLICY CONNECTION: %s", bdata(Request_path(conn->req))); conn->type = CONN_TYPE_SOCKET; taskname("XML"); next = SOCKET_REQ; } else { debug("XML MESSAGE"); conn->type = CONN_TYPE_MSG; taskname("MSG"); next = MSG_REQ; } } else if(Request_is_json(conn->req)) { debug("JSON SOCKET MESSAGE"); conn->type = CONN_TYPE_MSG; taskname("MSG"); next = MSG_REQ; } else if(Request_is_websocket(conn->req)) { debug("WEBSOCKET MESSAGE"); conn->type = CONN_TYPE_SOCKET; taskname("WS"); next = WS_REQ; } else if(Request_is_http(conn->req)) { debug("HTTP MESSAGE"); conn->type = CONN_TYPE_HTTP; taskname("HTTP"); next = HTTP_REQ; } else { error_response(conn, 500, "Invalid code branch, tell Zed."); } return next; error: return CLOSE; }
void client_task(void* arg) { struct client_config_t* config; int fd; config = (struct client_config_t*)arg; fd = config->fd; printf("Entering client task: %d (fd= %d)\n", taskid(), fd); taskname("client_task"); config->h(fd); printf("Exiting client task: %d, closing fd= %d\n", taskid(), fd); close(fd); }
void Action_task(void *v) { Action *action = (Action *)v; int rc = 0; pid_t child = 0; Profile *prof = Profile_load(action->profile_dir); taskname(bdata(action->name)); taskstate("depends"); rc = Rampart_wait(action->before); check(rc != -1, "A dependency failed to start, we can't start."); Rampart_running(&action->after); taskstate("ready"); debug("STARTED %s", bdata(action->name)); while(RUNNING) { taskstate("starting"); if(Unixy_still_running(prof->pid_file, &child)) { debug("Looks like %s is already running, we'll just leave it alone.", bdata(action->name)); } else { Unixy_remove_dead_pidfile(prof->pid_file); Action_exec(action, prof); } if(access(bdatae(prof->pid_file, ""), R_OK) != 0) { log_warn("%s didn't make pidfile %s. Waiting then trying again.", bdata(action->name), bdata(prof->pid_file)); Action_sleep(2); } taskstate("waiting"); while(Unixy_still_running(prof->pid_file, &child) && RUNNING) { Action_sleep(1); } if(!prof->restart) { break; } taskstate("restarting"); Action_sleep(1); } debug("ACTION %s exited.", bdata(action->name)); error: Rampart_failed(&action->after); return; }
static void *thread_fun(void *arg) { int mytask_indx; unsigned long msg; pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); mytask_indx = ((int *)arg)[0]; if (!(mytask[mytask_indx] = rt_thread_init(taskname(mytask_indx), 0, 0, SCHED_FIFO, 0x1))) { printf("CANNOT INIT TASK %u\n", taskname(mytask_indx)); exit(1); } mlockall(MCL_CURRENT | MCL_FUTURE); rt_make_hard_real_time(); hrt[mytask_indx] = 1; while (!end) { switch (change) { case 0: rt_task_suspend(mytask[mytask_indx]); break; case 1: rt_sem_wait(sem); break; case 2: rt_receive(NULL, &msg); break; case 3: rt_return(rt_receive(NULL, &msg), 0); break; } } rt_make_soft_real_time(); rt_task_delete(mytask[mytask_indx]); hrt[mytask_indx] = 0; return (void*)0; }
static inline int ident_and_register(Connection *conn, int reg_too) { int next = CLOSE; if(Request_is_xml(conn->req)) { if(biseq(Request_path(conn->req), &POLICY_XML_REQUEST)) { debug("XML POLICY CONNECTION"); conn->type = CONN_TYPE_SOCKET; taskname("XML"); next = SOCKET_REQ; } else { debug("XML MESSAGE"); conn->type = CONN_TYPE_MSG; taskname("MSG"); next = MSG_REQ; } } else if(Request_is_json(conn->req)) { debug("JSON SOCKET MESSAGE"); conn->type = CONN_TYPE_MSG; taskname("MSG"); next = MSG_REQ; } else if(Request_is_http(conn->req)) { debug("HTTP MESSAGE"); conn->type = CONN_TYPE_HTTP; taskname("HTTP"); next = HTTP_REQ; } else { error_response(conn, 500, "Invalid code branch, tell Zed."); } if(reg_too) Register_connect(IOBuf_fd(conn->iob), (void*)conn); return next; error: return CLOSE; }
void fdtask(void *v) { int i, ms; PollResult result; int rc = 0; FDTASK = taskself(); rc = PollResult_init(POLL, &result); check(rc == 0, "Failed to initialize the poll result."); tasksystem(); taskname("fdtask"); for(;;){ /* let everyone else run */ while(taskyield() > 0) ; /* we're the only one runnable - poll for i/o */ errno = 0; taskstate("poll"); ms = next_task_sleeptime(500); if(task_was_signaled()) { fdtask_shutdown(); task_clear_signal(); break; } else { rc = SuperPoll_poll(POLL, &result, ms); check(rc != -1, "SuperPoll failure, aborting."); for(i = 0; i < rc; i++) { taskready(result.hits[i].data); } wake_sleepers(); } } PollResult_clean(&result); FDTASK = NULL; return; error: taskexitall(1); }
void fdtask(void *v) { int i, ms; PollResult result; int rc = 0; rc = PollResult_init(POLL, &result); check(rc == 0, "Failed to initialize the poll result."); tasksystem(); taskname("fdtask"); for(;;){ /* let everyone else run */ while(taskyield() > 0) ; /* we're the only one runnable - poll for i/o */ errno = 0; taskstate("poll"); ms = next_task_sleeptime(500); if(SIGNALED) { for(i = 0; i < SuperPoll_active_hot(POLL); i++) { Task *target = (Task *)SuperPoll_data(POLL, i); if(target) taskready(target); SuperPoll_compact_down(POLL, i); } } else { rc = SuperPoll_poll(POLL, &result, ms); check(rc != -1, "SuperPoll failure, aborting."); for(i = 0; i < rc; i++) { taskready(result.hits[i].data); } } wake_sleepers(); } PollResult_clean(&result); taskexit(0); error: taskexitall(1); }
int Handler_setup(Handler *handler) { taskname("Handler_task"); handler->task = taskself(); handler->send_socket = Handler_send_create(bdata(handler->send_spec), bdata(handler->send_ident)); check(handler->send_socket, "Failed to create handler socket."); handler->recv_socket = Handler_recv_create(bdata(handler->recv_spec), bdata(handler->recv_ident)); check(handler->recv_socket, "Failed to create listener socket."); return 0; error: return -1; }
// // This is the router for all new incoming connections. The overall flow // for what we're doing here is as follows: // // First, we'll read the request message that comes in off the new connection. // // If a server ID is in the request, we'll attempt to lookup the server task // in the context routing hash table. If the server task exists in the hash // table, we'll create a new connection task and add it to the server's // connection list. // // If the server ID is not in the context's routing hash table, we respond to // the new connection with a suggestion to have the client ask the location // quorum where the server may be located at. If possible, we should send the // address and port number of the last known location quorum leader (or any // location quorum member if the leader is not known). // // If the client doesn't send a server ID at all, we'll then try to determine // what the client wants to do. The remaining options to attempt at this point // are the following: // // 1. Become a client-server instance. // 2. Respond with the address and port of the location quorum leader (or a // location quorum member if the leader is not known). // 3. Create a new location quorum by becoming a location quorum leader. // void TDB_routing_task(TDB_router_t* router) { TDB_msg_client_control_t control_msg_data; char new_uuid_string[UUID_STR_LEN]; uuid_t new_uuid; TDB_replica_t* new_replica; taskname("router"); if(TDB_proto_handle_connect_msg(router->accept_fd) != TDB_SUCCESS) { LOG(TDB_LOG_ERR, "Did not receive a valid connect message while routing."); taskexit(TDB_ERROR); } if(TDB_proto_receive_control_msg(router->accept_fd, &control_msg_data) != TDB_SUCCESS) { LOG(TDB_LOG_ERR, "Did not receive a valid control message while routing."); taskexit(TDB_ERROR); } else { if(TDB_proto_send_control_resp_msg(router->accept_fd) != TDB_SUCCESS) { LOG(TDB_LOG_ERR, "Failed to send a response to the control message."); taskexit(TDB_ERROR); } else { LOG(TDB_LOG_DBG, "Sent response to control message."); } } switch(control_msg_data.action) { case TDB_PROTO_CTRL_ATTACH_APPEND: case TDB_PROTO_CTRL_ATTACH_DATA: case TDB_PROTO_CTRL_ATTACH_VOTE: if(TDB_replica_attach(router, control_msg_data.uuid, control_msg_data.action) != TDB_SUCCESS) { uuid_unparse(control_msg_data.uuid, new_uuid_string); LOG(TDB_LOG_ERR, "Failed to attach to UUID `%s'.", new_uuid_string); } else { LOG(TDB_LOG_DBG, "Attach completed."); } break; case TDB_PROTO_CTRL_PROXY: LOG(TDB_LOG_DBG, "Handling control proxy message."); LOG(TDB_LOG_ERR, "Not implemented yet."); break; case TDB_PROTO_CTRL_FOLLOWER: LOG(TDB_LOG_DBG, "Handling control follower message."); LOG(TDB_LOG_ERR, "Not implemented yet."); break; case TDB_PROTO_CTRL_LEADER: TDB_replica_init(&new_replica); if(TDB_bootstrap_leader(new_replica, router->ctx, \ &new_uuid, control_msg_data.path) == TDB_SUCCESS) { uuid_unparse(new_uuid, new_uuid_string); LOG(TDB_LOG_ERR, "Quorum leader created with UUID `%s'.", new_uuid_string); //TODO: return uuid to requestor? } else { LOG(TDB_LOG_ERR, "Failed to bootstrap a quorum leader."); } break; case TDB_PROTO_CTRL_LOCATION: TDB_replica_init(&new_replica); if(TDB_bootstrap_location(new_replica, router->ctx, \ &new_uuid) == TDB_SUCCESS) { uuid_unparse(new_uuid, new_uuid_string); LOG(TDB_LOG_ERR, "Location quorum leader created with UUID `%s'.", new_uuid_string); //TODO: return uuid to requestor? } else { LOG(TDB_LOG_ERR, "Failed to bootstrap a location quorum leader."); } break; case TDB_PROTO_CTRL_EXIT: LOG(TDB_LOG_DBG, "Handling control exit message."); LOG(TDB_LOG_ERR, "Not implemented yet."); break; case TDB_PROTO_CTRL_DESTROY: LOG(TDB_LOG_DBG, "Handling control destroy message."); LOG(TDB_LOG_ERR, "Not implemented yet."); break; default: LOG(TDB_LOG_ERR, "Encountered unrecognized control message type of `%d'.", \ control_msg_data.action); taskexit(TDB_ERROR); } LOG(TDB_LOG_DBG, "Completed routing. Exiting task."); TDB_free_router(router); taskexit(TDB_SUCCESS); }
// 主协程 static void taskmainstart(void *v) { taskname("taskmain"); taskmain(taskargc, taskargv); }
void fdtask(void *v) { int i, ms; Task *t; uvlong now; tasksystem(); taskname("fdtask"); struct epoll_event events[20000]; for(;;){ /* let everyone else run */ while(taskyield() > 0) ; /* we're the only one runnable - epoll for i/o */ errno = 0; taskstate("epoll"); if(sleeping.head == nil && blocking.head == nil) ms = -1; else{ /* sleep at most 100ms */ now = nsec(); if (t) { if(now >= t->alarmtime) ms = 0; else if(now+500*1000*1000LL >= t->alarmtime) ms = (t->alarmtime - now)/1000000; else ms = 500; }else{ ms = 500; } } int nevents; if((nevents = epoll_wait(epfd, events, 20000, ms)) < 0){ if(errno == EINTR) continue; fprint(2, "epoll: %s\n", strerror(errno)); taskexitall(0); } /* wake up the guys who deserve it */ for(i=0; i<nevents; i++){ //deleting it from blocking queue for (t = blocking.head; t!= nil && t!= events[i].data.ptr; t=t->next) ; if(t==events[i].data.ptr) deltask(&blocking,t); taskready((Task *)events[i].data.ptr); } now = nsec(); while((t=sleeping.head) && now >= t->alarmtime){ deltask(&sleeping, t); if(!t->system && --sleepingcounted == 0) taskcount--; taskready(t); } /*wake up the guys who are blocked */ while((t=blocking.head) && now >= t->alarmtime){ deltask(&blocking, t); if(!t->system && --blockingcounted == 0) taskcount--; taskready(t); } } }
void fdtask(void *v) { int i, ms; Task *t; uvlong now; tasksystem(); taskname("fdtask"); for(;;){ //fprintf(stderr,"pooling0\n"); /* let everyone else run */ taskyield(); //fprintf(stderr,"\n after yield %d\n", maysamYieldRet); //while(taskyield() > 0); /* we're the only one runnable - poll for i/o */ errno = 0; taskstate("poll"); //Added by Maysam Yabandeh //taskname("fdtask(%d)",npollfd); if((t=sleeping.head) == nil) ms = -1; else{ /* sleep at most 5s */ now = nsec(); if(now >= t->alarmtime) ms = 0; else if(now+5*1000*1000*1000LL >= t->alarmtime) ms = (t->alarmtime - now)/1000000; else ms = 5000; } //Added by Maysam Yabandeh //if (ms == -1 && maysamYieldRet == 0) ms = 0; if (ms == -1) ms = 0; //fprintf(stderr,"pooling ms is %d npollfd is %d\n", ms, npollfd); #ifndef USE_SHM if(poll(pollfd, npollfd, ms) < 0){ //fprintf(stderr,"pooling error\n"); if(errno == EINTR) continue; fprint(2, "poll: %s\n", strerror(errno)); taskexitall(0); } //fprintf(stderr,"pooling2\n"); /* wake up the guys who deserve it */ for(i=0; i<npollfd; i++){ while(i < npollfd && pollfd[i].revents){ //fprintf(stderr,"pooling3\n"); taskready(polltask[i]); --npollfd; pollfd[i] = pollfd[npollfd]; polltask[i] = polltask[npollfd]; } } #else /* wake up the guys who deserve it */ //extern mpass::MessageEndPoint msg_end_point; mpass::MessageEndPoint *end_point = &mpass::msg_end_point; for(i=0; i<npollfd; i++){ int &fd = pollfd[i].fd; bool read = pollfd[i].events & POLLIN; mpass::Connection *conn = &end_point->conn_array[fd]; if ( (read && !conn->rcv_q->is_empty()) || (!read && !conn->snd_q->is_full()) ) { taskready(polltask[i]); --npollfd; pollfd[i] = pollfd[npollfd]; polltask[i] = polltask[npollfd]; } } #endif //fprintf(stderr,"pooling4\n"); now = nsec(); while((t=sleeping.head) && now >= t->alarmtime){ //fprintf(stderr,"pooling5\n"); deltask(&sleeping, t); if(!t->system && --sleepingcounted == 0) taskcount--; taskready(t); } } }