Exemple #1
0
int p_share_work(void) {
  int worker_q = LOCAL_share_request;
  int son;

  if (! BITMAP_member(OrFr_members(REMOTE_top_or_fr(worker_q)), worker_id) ||
      B == REMOTE_top_cp(worker_q) ||
      (LOCAL_load <= DELAYED_RELEASE_LOAD && OrFr_nearest_livenode(LOCAL_top_or_fr) == NULL)) {
    /* refuse sharing request */
    REMOTE_reply_signal(LOCAL_share_request) = no_sharing;
    LOCAL_share_request = MAX_WORKERS;
    PUT_OUT_REQUESTABLE(worker_id);
    return TRUE;
  }
  /* sharing request accepted */
  REMOTE_reply_signal(worker_q) = sharing;
  share_private_nodes(worker_q);
  if ((son = fork()) == 0) {
    worker_id = worker_q;  /* child becomes requesting worker */
    LOCAL = REMOTE + worker_id;
    LOCAL_reply_signal = ready;
    PUT_IN_REQUESTABLE(worker_id);
    PUT_BUSY(worker_id);

    return FALSE;
  } else {
    worker_pid(worker_q) = son;
    LOCAL_share_request = MAX_WORKERS;
    PUT_IN_REQUESTABLE(worker_id);

    return TRUE;
  }
}
Exemple #2
0
static inline void
worker_write_input_cb(EV_P_ ev_io *w, int revents, struct worker *worker,
                   struct writeq *writeq, enum msg_type type)
{
    int rc;

    if (worker->session == NULL) {
        printf("ERROR: worker without session!\n");
        worker_stop(EV_A_ worker);
        return;
    }

    if ((revents & EV_ERROR)) {
        goto err;
    }

    rc = writeq_write(writeq, w->fd);
    if (rc < 0) {
        goto err;
    } else if (rc > 0) {
        /* disarm writes. */
        ev_io_stop(EV_A_ w);
        return;
    }
    return;

 err:
    DEBUGF(0, "WARNING: worker pid %d input pipe fd=%d error\n",
           worker_pid(worker), w->fd);
    ev_io_stop(EV_A_ w);
    session_on_worker_pipe_err_cb(EV_A_ worker->session, type);
}
Exemple #3
0
/* スレッドの起動 (MT-unsafe) */
void launch_lmn_workers(LmnWorkerGroup *wp)
{
  unsigned long i, core_num;

  core_num = workers_entried_num(wp);
  for (i = 0; i < core_num; i++) { /** start */
    if (i == LMN_PRIMARY_ID) continue;
    lmn_thread_create(&worker_pid(workers_get_worker(wp, i)),
                      lmn_worker_start,
                      workers_get_worker(wp, i));
  }
  if (lmn_env.profile_level >= 1) profile_start_exec();

  lmn_worker_start((void *)workers_get_worker(wp, LMN_PRIMARY_ID));

  if (lmn_env.profile_level >= 1) profile_finish_exec();
  for (i = 0; i < core_num; i++) {
    if (i == LMN_PRIMARY_ID) continue;
    lmn_thread_join(worker_pid(workers_get_worker(wp, i)));
  }
}
Exemple #4
0
void init_workers(void) {
    int proc;
#ifdef THREADS
    return;
#endif
    NOfThreads = number_workers;
#ifdef ACOW
    if (number_workers > 1) {
        int son;
        son = fork();
        if (son == -1)
            Yap_Error(FATAL_ERROR, TermNil, "fork error (init_workers)");
        if (son > 0) {
            /* I am the father, I must stay here and wait for my children to all die */
            struct sigaction sigact;

            GLOBAL_master_worker = getpid();
            sigact.sa_handler = SIG_DFL;
            sigemptyset(&sigact.sa_mask);
            sigact.sa_flags = SA_RESTART;
            sigaction(SIGINT, &sigact, NULL);
            pause();
            exit(0);
        } else worker_pid(0) = getpid();
    }
#endif /* ACOW */
    for (proc = 1; proc < number_workers; proc++) {
        int son;
        son = fork();
        if (son == -1)
            Yap_Error(FATAL_ERROR, TermNil, "fork error (init_workers)");
        if (son == 0) {
            /* new worker */
            worker_id = proc;
            remap_memory();
            break;
        }
        else worker_pid(proc) = son;
    }
}
Exemple #5
0
void
worker_stop(EV_P_ struct worker *worker)
{
    LOGF(3, "=== %d: worker stopped\n", worker_pid(worker));

    if (worker->f_alive) {
        LOGF(1, "=== %d: worker still alive - sending SIGKILL\n",
             worker_pid(worker));
        kill(worker_pid(worker), SIGKILL);
    }
    writeq_uninit(&worker->stdin_writeq);
    writeq_uninit(&worker->msgin_writeq);
    if (ev_is_active(&worker->child_watcher)) {
        ev_child_stop(EV_A_ &worker->child_watcher);
    }
    if (ev_is_active(&worker->stdin_w)) {
        ev_io_stop(EV_A_ &worker->stdin_w);
    }
    if (ev_is_active(&worker->stdout_w)) {
        ev_io_stop(EV_A_ &worker->stdout_w);
    }
    if (ev_is_active(&worker->stderr_w)) {
        ev_io_stop(EV_A_ &worker->stderr_w);
    }
    if (ev_is_active(&worker->msgin_w)) {
        ev_io_stop(EV_A_ &worker->msgin_w);
    }
    if (ev_is_active(&worker->msgout_w)) {
        ev_io_stop(EV_A_ &worker->msgout_w);
    }
    close(worker->stdin_w.fd);
    close(worker->stdout_w.fd);
    close(worker->stderr_w.fd);
    close(worker->msgin_w.fd);
    close(worker->msgout_w.fd);
    free(worker);
}
Exemple #6
0
static void
worker_exited_cb(EV_P_ ev_child *w, int revents)
{
    struct worker *worker = CONTAINER_OF(w, struct worker, child_watcher);

    LOGF(3, "=== %d: worker ended, status=%d\n", worker_pid(worker),
         w->rstatus);

    ev_child_stop(EV_A_ w);
    worker->f_alive = false;

    if (worker->session == NULL) {
        printf("WARNING: worker without session!\n");
        return;
    }

    session_on_worker_exited_cb(EV_A_ worker->session, w->rstatus);
}
Exemple #7
0
static inline void
worker_read_output_cb(EV_P_ ev_io *w, int revents, struct worker *worker,
                      enum msg_type type)
{
    struct worker_read_ctx ctx = {
        .session = worker->session,
        .type = type,
    };
    int rc;

    if (worker->session == NULL) {
        printf("ERROR: worker without session!\n");
        worker_stop(EV_A_ worker);
        return;
    }

    if ((revents & EV_ERROR)) {
        goto err;
    }

    rc = rbuf_read_chunks(EV_A_ w->fd, worker_rbuf_read_cb, &ctx);
    if (rc < 0) {
        goto err;
    } else if (rc > 0) {
        /* EOF - disarm reads. */
        ev_io_stop(EV_A_ w);
//        session_on_worker_output_cb(EV_A_ worker->session, NULL, 0, 0, type);
    }
    return;

 err:
    DEBUGF(0, "WARNING: worker pid %d output pipe fd=%d error\n",
           worker_pid(worker), w->fd);
    ev_io_stop(EV_A_ w);
    session_on_worker_pipe_err_cb(EV_A_ worker->session, type);
}
Exemple #8
0
struct worker *
worker_start(EV_P_ struct session *session)
{
    struct worker *w;
    pid_t pid;
    int stdin_fds [2] = {-1, -1};
    int stdout_fds[2] = {-1, -1};
    int stderr_fds[2] = {-1, -1};
    int msgin_fds [2] = {-1, -1};
    int msgout_fds[2] = {-1, -1};

#if WORKER_TIMINGS
    uint64_t _start = now_us();
#endif

    if ((w = calloc(1, sizeof(*w))) == NULL) {
        goto fail;
    }
    w->session = session;
    writeq_init(&w->stdin_writeq);
    writeq_init(&w->msgin_writeq);

    if (pipe(stdin_fds ) < 0 ||
        pipe(stdout_fds) < 0 ||
        pipe(stderr_fds) < 0 ||
        pipe(msgin_fds ) < 0 ||
        pipe(msgout_fds) < 0) {
        LOG_ERRNO("pipe()");
        goto fail;
    }
    maxfd_update(stdin_fds [0]);
    maxfd_update(stdin_fds [1]);
    maxfd_update(stdout_fds[0]);
    maxfd_update(stdout_fds[1]);
    maxfd_update(stderr_fds[0]);
    maxfd_update(stderr_fds[1]);
    maxfd_update(msgin_fds [0]);
    maxfd_update(msgin_fds [1]);
    maxfd_update(msgout_fds[0]);
    maxfd_update(msgout_fds[1]);


    pid = fork();
    if (pid < 0) {
        LOG_ERRNO("fork()");
        goto fail;
    }
    if (pid == 0) {
        /* child. */
        if (dup2(stdin_fds [0], 0) < 0 ||
            dup2(stdout_fds[1], 1) < 0 ||
            dup2(stderr_fds[1], 2) < 0 ||
            dup2(msgin_fds [0], 3) < 0 ||
            dup2(msgout_fds[1], 4) < 0) {
            exit(EXIT_FAILURE);
        }
        maxfd_closeall(5);
        pyenv_child_after_fork();
        exit(EXIT_SUCCESS);
    } else {
        /* parent. */
        close(stdin_fds [0]);
        close(stdout_fds[1]);
        close(stderr_fds[1]);
        close(msgin_fds [0]);
        close(msgout_fds[1]);

        set_fd_nonblocking(stdin_fds [1]);
        set_fd_nonblocking(stdout_fds[0]);
        set_fd_nonblocking(stderr_fds[0]);
        set_fd_nonblocking(msgin_fds [1]);
        set_fd_nonblocking(msgout_fds[0]);

        ev_child_init(&w->child_watcher, worker_exited_cb, pid, 0);
        ev_child_start(EV_A_ &w->child_watcher);

        ev_io_init(&w->stdin_w , worker_write_stdin_cb, stdin_fds [1],
                   EV_WRITE);
        ev_io_init(&w->stdout_w, worker_read_stdout_cb, stdout_fds[0],
                   EV_READ);
        ev_io_init(&w->stderr_w, worker_read_stderr_cb, stderr_fds[0],
                   EV_READ);
        ev_io_init(&w->msgin_w , worker_write_msgin_cb, msgin_fds [1],
                   EV_WRITE);
        ev_io_init(&w->msgout_w, worker_read_msgout_cb, msgout_fds[0],
                   EV_READ);
        ev_io_start(EV_A_ &w->stdout_w);
        ev_io_start(EV_A_ &w->stderr_w);
        ev_io_start(EV_A_ &w->msgout_w);

        LOGF(3, "=== %d: worker started, fds=[%d, %d, %d, %d, %d]\n",
             worker_pid(w), stdin_fds[1], stdout_fds[0], stderr_fds[0],
             msgin_fds[1], msgout_fds[0]);

        w->f_alive = true;
    }
#if WORKER_TIMINGS
    worker_start_time += now_us() - _start;
    worker_start_calls++;
#endif

    return w;

 fail:
    close(stdin_fds [0]);
    close(stdin_fds [1]);
    close(stdout_fds[0]);
    close(stdout_fds[1]);
    close(stderr_fds[0]);
    close(stderr_fds[1]);
    close(msgin_fds [0]);
    close(msgin_fds [1]);
    close(msgout_fds[0]);
    close(msgout_fds[1]);
    free(w);
    return NULL;
}
Exemple #9
0
void Yap_init_global(int max_table_size, int n_workers, int sch_loop, int delay_load) {
    int i;

    /* global data related to memory management */
#ifdef LIMIT_TABLING
    if (max_table_size)
        GLOBAL_MAX_PAGES = ((max_table_size - 1) * 1024 * 1024 / SHMMAX + 1) * SHMMAX / Yap_page_size;
    else
        GLOBAL_MAX_PAGES = -1;
#endif /* LIMIT_TABLING */
    INIT_PAGES(GLOBAL_PAGES_void, void *);
#ifdef YAPOR
    INIT_PAGES(GLOBAL_PAGES_or_fr, struct or_frame);
    INIT_PAGES(GLOBAL_PAGES_qg_sol_fr, struct query_goal_solution_frame);
    INIT_PAGES(GLOBAL_PAGES_qg_ans_fr, struct query_goal_answer_frame);
#endif /* YAPOR */
#ifdef TABLING_INNER_CUTS
    INIT_PAGES(GLOBAL_PAGES_tg_sol_fr, struct table_subgoal_solution_frame);
    INIT_PAGES(GLOBAL_PAGES_tg_ans_fr, struct table_subgoal_answer_frame);
#endif /* TABLING_INNER_CUTS */
#ifdef TABLING
#ifdef GLOBAL_TRIE
    INIT_PAGES(GLOBAL_PAGES_gt_node, struct global_trie_node);
    INIT_PAGES(GLOBAL_PAGES_gt_hash, struct global_trie_hash);
#endif /* GLOBAL_TRIE */
    INIT_PAGES(GLOBAL_PAGES_tab_ent, struct table_entry);
    INIT_PAGES(GLOBAL_PAGES_sg_fr, struct subgoal_frame);
    INIT_PAGES(GLOBAL_PAGES_sg_node, struct subgoal_trie_node);
    INIT_PAGES(GLOBAL_PAGES_ans_node, struct answer_trie_node);
    INIT_PAGES(GLOBAL_PAGES_sg_hash, struct subgoal_trie_hash);
    INIT_PAGES(GLOBAL_PAGES_ans_hash, struct answer_trie_hash);
    INIT_PAGES(GLOBAL_PAGES_dep_fr, struct dependency_frame);
#endif /* TABLING */
#if defined(YAPOR) && defined(TABLING)
    INIT_PAGES(GLOBAL_PAGES_susp_fr, struct suspension_frame);
#endif /* YAPOR && TABLING */

#ifdef YAPOR
    /* global static data */
    number_workers = n_workers;
    worker_pid(0) = getpid();
    for (i = 1; i < number_workers; i++) worker_pid(i) = 0;
    SCHEDULER_LOOP = sch_loop;
    DELAYED_RELEASE_LOAD = delay_load;

    /* global data related to or-performance */
    GLOBAL_number_goals = 0;
    GLOBAL_best_times(0) = 0;
    GLOBAL_performance_mode = PERFORMANCE_OFF;

    /* global data related to or-parallelism */
    BITMAP_clear(GLOBAL_bm_present_workers);
    for (i = 0; i < number_workers; i++)
        BITMAP_insert(GLOBAL_bm_present_workers, i);
    BITMAP_copy(GLOBAL_bm_idle_workers, GLOBAL_bm_present_workers);
    BITMAP_clear(GLOBAL_bm_root_cp_workers);
    BITMAP_clear(GLOBAL_bm_invisible_workers);
    BITMAP_clear(GLOBAL_bm_requestable_workers);
    BITMAP_clear(GLOBAL_bm_executing_workers);
    BITMAP_copy(GLOBAL_bm_finished_workers, GLOBAL_bm_present_workers);
    INIT_LOCK(GLOBAL_LOCKS_bm_idle_workers);
    INIT_LOCK(GLOBAL_LOCKS_bm_root_cp_workers);
    INIT_LOCK(GLOBAL_LOCKS_bm_invisible_workers);
    INIT_LOCK(GLOBAL_LOCKS_bm_requestable_workers);
    INIT_LOCK(GLOBAL_LOCKS_bm_executing_workers);
    INIT_LOCK(GLOBAL_LOCKS_bm_finished_workers);
#ifdef TABLING_INNER_CUTS
    INIT_LOCK(GLOBAL_LOCKS_bm_pruning_workers);
#endif /* TABLING_INNER_CUTS */
    GLOBAL_LOCKS_who_locked_heap = MAX_WORKERS;
    INIT_LOCK(GLOBAL_LOCKS_heap_access);
    INIT_LOCK(GLOBAL_LOCKS_alloc_block);
#if defined(YAPOR_ERRORS) || defined(TABLING_ERRORS)
    INIT_LOCK(GLOBAL_LOCKS_stderr_messages);
#endif /* YAPOR_ERRORS || TABLING_ERRORS */
    if (number_workers == 1)
        PARALLEL_EXECUTION_MODE = FALSE;
    else
        PARALLEL_EXECUTION_MODE = TRUE;
#endif /* YAPOR */

#ifdef TABLING
    /* global data related to tabling */
    GLOBAL_root_tab_ent = NULL;
#ifdef GLOBAL_TRIE
    new_global_trie_node(GLOBAL_root_gt, 0, NULL, NULL, NULL);
#endif /* GLOBAL_TRIE */
#ifdef LIMIT_TABLING
    GLOBAL_first_sg_fr = NULL;
    GLOBAL_last_sg_fr = NULL;
    GLOBAL_check_sg_fr = NULL;
#endif /* LIMIT_TABLING */
    GLOBAL_root_dep_fr = NULL;
    for (i = 0; i < MAX_TABLE_VARS; i++) {
        CELL *pt = GLOBAL_table_var_enumerator_addr(i);
        RESET_VARIABLE(pt);
    }
#ifdef TABLE_LOCK_AT_WRITE_LEVEL
    for (i = 0; i < TABLE_LOCK_BUCKETS; i++)
        INIT_LOCK(GLOBAL_table_lock(i));
#endif /* TABLE_LOCK_AT_WRITE_LEVEL */
#endif /* TABLING */

    return;
}