예제 #1
0
파일: ERT.java 프로젝트: trifork/erjang
  public static void do_trace(EProc proc, EAtom what, EObject info) throws Pausable {

    EPID pid = proc.get_trace_flags().tracer;

    EObject msg = ETuple4.make_tuple(am_trace, proc.self_handle(), what, info);

    pid.send(proc.self_handle(), msg);
  }
예제 #2
0
파일: ERT.java 프로젝트: trifork/erjang
 /**
  * @param s
  * @return
  */
 public static EPID loopkup_pid(ESeq name) {
   String str = name.stringValue();
   for (EProc p : EProc.all_tasks.values()) {
     if (p.self_handle().toString().equals(str)) {
       return p.self_handle();
     }
   }
   throw ERT.badarg(name);
 }
예제 #3
0
파일: ERT.java 프로젝트: trifork/erjang
  public static EObject apply_list_last(EProc proc, EObject mod, EObject fun, ESeq seq, int len)
      throws Pausable {
    EAtom f = fun.testAtom();
    ESeq a = seq.testSeq();

    if (f == null || a == null) throw ERT.badarg(mod, fun, seq);

    EFun found = resolve_fun(mod, fun, len);

    if (len > 9) {
      // TODO: make it real tail recursion in stead
      return found.invoke(proc, a.toArray());
    }

    proc.tail = found;
    a = a.reverse();

    switch (len) {
      default:
        throw new NotImplemented();
      case 9:
        proc.arg8 = a.head();
        a = a.tail();
      case 8:
        proc.arg7 = a.head();
        a = a.tail();
      case 7:
        proc.arg6 = a.head();
        a = a.tail();
      case 6:
        proc.arg5 = a.head();
        a = a.tail();
      case 5:
        proc.arg4 = a.head();
        a = a.tail();
      case 4:
        proc.arg3 = a.head();
        a = a.tail();
      case 3:
        proc.arg2 = a.head();
        a = a.tail();
      case 2:
        proc.arg1 = a.head();
        a = a.tail();
      case 1:
        proc.arg0 = a.head();
        a = a.tail();
      case 0:
    }

    return EProc.TAIL_MARKER;
  }
예제 #4
0
파일: ERT.java 프로젝트: trifork/erjang
  /** wait for howlong, for one more message to be available */
  public static boolean wait_timeout(EProc proc, EObject howlong) throws Pausable {
    try {
      proc.check_exit();

      if (ipclog.isLoggable(Level.FINE))
        ipclog.fine("WAIT| " + proc + " waits for messages for " + howlong + " ms");
      if (howlong == am_infinity) {
        proc.mbox.untilHasMessages(proc.midx + 1);
        proc.check_exit();
        if (ipclog.isLoggable(Level.FINE)) ipclog.fine("WAIT| " + proc + " wakes up on message");
        return true;
      } else {
        long now = System.currentTimeMillis();
        if (proc.midx == 0 || proc.timeout_start == 0L) {
          proc.timeout_start = now;
        }

        EInteger ei;
        if ((ei = howlong.testInteger()) == null)
          throw new ErlangError(EAtom.intern("timeout_value"));

        long end = proc.timeout_start + ei.longValue();
        long left = end - now;

        if (left < 0) {
          return false;
        }

        if (!proc.in_receive) {
          Task.sleep(left);
          return false;
        } else {

          if (ipclog.isLoggable(Level.FINE))
            ipclog.fine(
                "WAIT| " + proc + " waiting for " + left + "ms for msg #" + (proc.midx + 1));
          boolean res = proc.mbox.untilHasMessages(proc.midx + 1, left);
          proc.check_exit();
          if (ipclog.isLoggable(Level.FINE))
            ipclog.fine("WAIT| " + proc + " wakes up " + (res ? "on message" : "after timeout"));

          return res;
        }
      }
    } finally {
      proc.in_receive = false;
    }
  }
예제 #5
0
파일: ERT.java 프로젝트: trifork/erjang
  private static EObject send_to_remote(
      EProc proc, ETuple dest, EAtom node_name, EAtom reg_name, EObject msg, EObject options)
      throws Pausable {
    // INVARIANT: t == ETuple.make(node_name, reg_name)

    if (node_name == getLocalNode().node) { // We're talking to ourselves
      send_to_locally_registered(proc, reg_name, msg);
      return am_ok; // Even if the process does not exist.
      // TODO: Return 'noconnect' if options contain noconnect?...
    } else { // We're talking to another node
      if (ipclog.isLoggable(Level.FINE)) {
        ipclog.fine("sending msg " + dest + " ! " + msg);
      }

      EAbstractNode node = EPeer.get(node_name);
      if (node == null) {
        EObject[] args =
            (options != null
                ? new EObject[] {dest, msg, options}
                : new EObject[] {dest, msg, ERT.NIL});
        return erlang__dsend__3.invoke(proc, args);
      } else {
        node.dsig_reg_send(proc.self_handle(), reg_name, msg);
        return am_ok;
      }
    }
  }
예제 #6
0
파일: ERT.java 프로젝트: trifork/erjang
  @BIF
  public static EObject send(EProc proc, final EObject pid, final EObject msg, EObject options)
      throws Pausable {
    // TODO handle ports also?
    proc.check_exit();

    // log.log(Level.FINER, "ignored options to send: " + options);

    EHandle handle;
    EAtom reg_name;
    if ((handle = pid.testHandle()) != null) {
      send_to_handle(proc, handle, msg);
      return am_ok;
    } else if ((reg_name = pid.testAtom()) != null) {
      boolean ok = send_to_locally_registered(proc, reg_name, msg);
      if (ok) return am_ok;
      else throw badarg(pid, msg);
    } else {
      ETuple t;
      EAtom node_name;
      if ((t = pid.testTuple()) != null
          && t.arity() == 2
          && (reg_name = t.elm(1).testAtom()) != null
          && (node_name = t.elm(2).testAtom()) != null) {
        return send_to_remote(proc, t, node_name, reg_name, msg, options);
      } else { // PID was of a bad type.
        ipclog.info("trying to send message to " + pid + " failed.");
        throw badarg(pid, msg);
      }
    }
  }
예제 #7
0
파일: ERT.java 프로젝트: trifork/erjang
  /**
   * @param owner
   * @param make
   * @throws Pausable
   */
  @BIF(name = "!")
  public static EObject send(EProc proc, EObject pid, EObject msg) throws Pausable {
    // TODO handle ports also?
    proc.check_exit();

    // log.log(Level.FINER, "ignored options to send: " + options);

    EHandle p;
    EAtom reg_name;
    if ((p = pid.testHandle()) != null) {
      send_to_handle(proc, p, msg);
    } else if ((reg_name = pid.testAtom()) != null) {
      send_to_locally_registered(proc, reg_name, msg);
    } else {
      ETuple t;
      EAtom node_name;
      if ((t = pid.testTuple()) != null
          && t.arity() == 2
          && (reg_name = t.elm(1).testAtom()) != null
          && (node_name = t.elm(2).testAtom()) != null) {
        send_to_remote(proc, t, node_name, reg_name, msg, null);
      } else { // PID was of a bad type.
        ipclog.info("trying to send message to " + pid + " failed.");
        throw badarg(pid, msg);
      }
    }
    // Arguments were of valid types; return the message:
    return msg;
  }
예제 #8
0
파일: ERT.java 프로젝트: trifork/erjang
 /** peek mbox at current index (proc.midx), which is 0 upon entry to the loop. */
 public static EObject loop_rec(EProc proc) {
   int idx = proc.midx;
   proc.in_receive = true;
   EObject msg = proc.mbox.peek(idx);
   if (ipclog.isLoggable(Level.FINE))
     ipclog.fine("WAIT| entered loop #" + idx + " message=" + msg);
   return msg;
 }
예제 #9
0
파일: ERT.java 프로젝트: trifork/erjang
  @BIF
  public static EInteger trace(EProc self_proc, EObject arg0, EObject arg1, EObject arg2) {
    EInternalPID pid = arg0.testInternalPID();
    EAtom all = arg0.testAtom();
    EObject how = arg1.testBoolean();
    ESeq flags = arg2.testSeq();

    if ((pid == null && all != am_all) || how == null || flags == null) {
      throw ERT.badarg(arg0, arg1, arg2);
    }

    EInternalPID self = self_proc.self_handle();

    if (all == am_all) {
      ESeq allprocs = EProc.processes();
      int result = allprocs.length();
      global_trace_flags.update(how == ERT.TRUE, flags, self);
      while (!allprocs.isNil()) {
        EProc proc = allprocs.head().testInternalPID().task();
        allprocs = allprocs.tail();

        if (proc.trace_flags != null) {
          proc.trace_flags.update(how == ERT.TRUE, flags, self);
        }
      }

      return ERT.box(result);

    } else {
      EProc proc = pid.task();

      if (!proc.is_alive_dirtyread()) {
        return ESmall.ZERO;
      }

      if (proc.trace_flags == null) {
        proc.trace_flags = global_trace_flags.clone();
      }

      proc.trace_flags.update(how == ERT.TRUE, flags, self);

      return ESmall.ONE;
    }
  }
예제 #10
0
파일: ERT.java 프로젝트: trifork/erjang
 /** wait forever, for one more message to be available */
 public static void wait(EProc proc) throws Pausable {
   try {
     int idx = proc.midx + 1;
     if (ipclog.isLoggable(Level.FINE))
       ipclog.fine("WAIT| " + proc + " waits for " + idx + " messages");
     proc.mbox.untilHasMessages(idx);
     if (ipclog.isLoggable(Level.FINE))
       ipclog.fine("WAIT| " + proc + " wakes up after timeout; now has " + (idx));
   } finally {
     proc.in_receive = false;
   }
 }
예제 #11
0
파일: ERT.java 프로젝트: trifork/erjang
  @BIF
  public static EInteger trace_pattern(EProc proc, EObject arg0, EObject arg1, EObject arg2) {

    ETuple3 mfa = ETuple3.cast(arg0);
    EAtom mod, fun;

    if (mfa == null
        || (mod = mfa.elem1.testAtom()) == null
        || (fun = mfa.elem2.testAtom()) == null) {
      throw ERT.badarg(arg0, arg1, arg2);
    }

    int count = EModuleManager.trace_pattern(proc.self_handle(), mod, fun, mfa.elem3, arg1, arg2);

    return ERT.box(count);
  }
예제 #12
0
파일: ERT.java 프로젝트: trifork/erjang
 /** message did not match incoming, goto next message (will be followed by goto top-of-loop) */
 public static void loop_rec_end(EProc proc) {
   proc.midx += 1;
 }
예제 #13
0
파일: ERT.java 프로젝트: trifork/erjang
 /** remove current message, and reset message index */
 public static void remove_message(EProc proc) {
   proc.mbox.remove(proc.midx);
   proc.midx = 0;
   proc.timeout_start = 0L;
   proc.in_receive = false;
 }
예제 #14
0
파일: ERT.java 프로젝트: trifork/erjang
 /** message reception timed out, reset message index */
 public static void timeout(EProc proc) {
   if (ipclog.isLoggable(Level.FINE)) ipclog.fine("WAIT| " + proc + " timed out");
   proc.midx = 0;
   proc.timeout_start = 0L;
   proc.in_receive = false;
 }
예제 #15
0
파일: ERT.java 프로젝트: trifork/erjang
 private static void send_to_handle(EProc proc, EHandle handle, EObject msg) throws Pausable {
   int penalty = handle.send(proc.self_handle(), msg);
   proc.bump_reductions(penalty);
 }
예제 #16
0
파일: ERT.java 프로젝트: trifork/erjang
 public static void check_exit(EProc p) {
   p.check_exit();
 }
예제 #17
0
파일: ERT.java 프로젝트: trifork/erjang
  public static void print_all_stack_traces() {
    System.err.println("== Trace ==");

    Mailbox<EObject> mbox = new Mailbox<>(EProc.process_count());

    ESeq all = EProc.processes();
    for (EObject o : all) {
      EInternalPID pid = (EInternalPID) o;
      pid.task().printStackTrace(mbox);
    }

    while (true) {
      EObject o = mbox.getb(1000);
      if (o == null) break;

      ETuple2 tup = ETuple2.cast(o);
      EHandle handle = tup.elm(1).testHandle();
      ESeq stack = tup.elm(2).testSeq();

      System.err.println("\n == " + handle + " : " + handle.name);
      for (EObject elm : stack) {

        ETuple4 tup4 = ETuple4.cast(elm);

        if (tup4 != null) {
          ESeq args = tup4.elem3.testSeq();
          ESmall arity = tup4.elem3.testSmall();
          if (arity == null && args != null) {
            arity = ERT.box(args.length());
          }

          StringBuffer file_line = new StringBuffer();

          ESeq info = tup4.elem4.testSeq();
          if (info != null) {
            String file = "?";
            int line = -1;
            for (EObject inf : info) {
              ETuple2 t;
              if ((t = ETuple2.cast(inf)) != null) {
                ESmall n;
                EString f;
                if (t.elem1 == ErlangException.am_line && ((n = t.elem2.testSmall()) != null)) {
                  line = n.value;
                } else if (t.elem1 == ErlangException.am_file
                    && ((f = t.elem2.testString()) != null)) {
                  file = f.stringValue();
                }
              }
            }
            if (line != -1) {
              file_line.append('(').append(file).append(':').append(line).append(')');
            }
          }

          String module = tup4.elem1.toString();
          String mfa;
          System.err.print(mfa = make_width(20, module) + ":" + tup4.elem2 + "/" + arity);
          System.err.println(" " + make_width(65 - mfa.length(), file_line.toString()));
        } else {
          System.err.println(elm);
        }
      }
    }
  }