@BIF static EPort open_port(EProc proc, EObject portName, EObject portSetting) { ETuple t; if ((t = portName.testTuple()) == null) throw ERT.badarg(portName, portSetting); ETuple2 name; if ((name = ETuple2.cast(t)) == null) throw ERT.badarg(portName, portSetting); if (name.elem1 == am_spawn) { throw new ErlangError(ERT.AM_NOT_IMPLEMENTED, portName, portSetting); } else if (name.elem1 == am_spawn_driver) { throw new NotImplemented(); } else if (name.elem1 == am_spawn_executable) { ETask<? extends EPort> task = new EExecDriverTask(proc, name, portSetting); return task.self(); } throw ERT.badarg(portName, portSetting); }
@BIF static EObject system_info(EProc proc, EObject type) { if (type == am_machine) { // we report BEAM so that the compiler emits BEAM files return EString.fromString("BEAM"); } else if (type == am_smp_support) { return ERT.TRUE; } else if (type == am_schedulers) { return ERT.box(ERT.threadPoolSize()); } else if (type == am_process_limit) { return ERT.box(ERT.processLimit()); } else if (type == am_fullsweep_after) { return ERT.box(65535); } else if (type == am_schedulers_online) { return ERT.box(Math.max(1, ERT.threadPoolSize())); } else if (type == am_threads) { return ERT.box(true); } else if (type == am_thread_pool_size) { return ERT.box(ERT.asyncThreadPoolSize()); } else if (type == am_break_ignored) { return ERT.box(false); } else if (type == am_compat_rel) { // we return same value as R14 return new ESmall(14); } ETuple2 tup; if (type == am_allocated_areas) { ECons res = ERT.NIL; List<MemoryPoolMXBean> bean2 = ManagementFactory.getMemoryPoolMXBeans(); if (bean2 == null) { MemoryMXBean bean = ManagementFactory.getMemoryMXBean(); if (bean != null) { MemoryUsage mu = bean.getHeapMemoryUsage(); res = res.cons(ETuple.make(am_heap, ERT.box(mu.getCommitted()), ERT.box(mu.getUsed()))); mu = bean.getNonHeapMemoryUsage(); res = res.cons(ETuple.make(am_non_heap, ERT.box(mu.getCommitted()), ERT.box(mu.getUsed()))); } return res; } for (MemoryPoolMXBean mb : bean2) { String name = mb.getName(); MemoryUsage mu = mb.getUsage(); if (mu == null) continue; String name2 = (mb.getType() == MemoryType.HEAP ? "heap:" : "non_heap:") + name; res = res.cons( ETuple.make( EAtom.intern(name2), ERT.box(mu.getCommitted()), ERT.box(mu.getUsed()))); } return res; } else if (type == am_allocator) { return am_jvm; } else if (type == am_heap_type) { return am_shared; } else if (type == am_smp_support) { return ERT.TRUE; } else if (type == am_thread_pool_size) { // TODO: hook up to thread pool return new ESmall(ERT.threadPoolSize()); } else if (type == am_os_type) { String os = System.getProperty("os.name"); if (os.startsWith("Windows")) { return ETuple.make(am_win32, new EString(os)); } else { return ETuple.make(am_unix, new EString(os)); } } else if (type == am_threads) { return ERT.TRUE; } else if (type == am_version) { String erts_version = ERT.runtime_info.erts_version; // remove prefix String prefix = "erts-"; if (erts_version.startsWith(prefix)) { erts_version = erts_version.substring(prefix.length()); } return EString.fromString(erts_version); } else if (type == am_otp_release) { return new EString(ERT.runtime_info.otp_version); } else if (type == am_logical_processors) { // TODO: be smarter somehow return ERT.box(Runtime.getRuntime().availableProcessors()); } else if (type == am_global_heaps_size) { return ERT.box(Runtime.getRuntime().totalMemory()); } else if (type == am_process_count) { return ERT.box(EProc.process_count()); } else if (type == am_system_architecture) { return new EString(Main.SYSTEM_ARCHITECTURE); } else if (type == am_driver_version) { // TODO: be smarter somehow return new EString(Main.DRIVER_VERSION); } else if (type == am_wordsize) { return new ESmall(4); } else if (type == am_debug_compiled || type == am_lock_checking) { throw ERT.badarg(type); } else if (type == am_hipe_architecture) { return am_undefined; } else if (type == am_build_type) { return EAtom.intern("opt"); } else if (type == am_system_version) { return new EString("Erjang [" + ERT.runtime_info.erts_version + "]"); } else if ((tup = ETuple2.cast(type)) != null) { if (tup.elem1 == am_allocator) { if (tup.elem2 == am_ets_alloc) { return ERT.FALSE; } } else if (tup.elem1 == am_error_checker) { throw ERT.badarg(type); } return am_undefined; } else { log.info("erlang:system_info(" + type + ") unknown"); throw ERT.badarg(type); } }
@BIF public static EObject spawn_opt(EProc self, EObject tup) throws Pausable { ETuple t; EAtom m; EAtom f; ESeq a; ESeq o; if ((t = tup.testTuple()) == null || t.arity() != 4 || (m = t.elm(1).testAtom()) == null || (f = t.elm(2).testAtom()) == null || (a = t.elm(3).testSeq()) == null || (o = t.elm(4).testSeq()) == null) throw ERT.badarg(tup); boolean link = false; boolean monitor = false; EAtom priority = null; for (; !o.isNil(); o = o.tail()) { EObject val = o.head(); ETuple2 t2; if (val == am_link) { link = true; } else if (val == am_monitor) { monitor = true; } else if ((t2 = ETuple2.cast(val)) != null) { if (t2.elm(1) == am_priority) { EAtom am = t2.elm(2).testAtom(); if (am != null) priority = am; } // ignore full_sweep_after and min_heap_size } } EProc p2 = new EProc(self.group_leader(), m, f, a); if (link) { self.link_to(p2); } if (priority != null) { // may throw badarg! p2.process_flag(am_priority, priority); } ERef ref = null; if (monitor) { ref = ERT.getLocalNode().createRef(); if (!self.monitor(p2.self_handle(), p2.self_handle(), ref)) { throw new InternalError("cannot monitor new process?"); // self.mbox_send(ETuple.make(ERT.am_DOWN, ref, p2.self_handle(), ERT.am_noproc)); } } ERT.run(p2); if (monitor) { return new ETuple2(p2.self_handle(), ref); } else { return p2.self_handle(); } }