@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 monitor(EProc self, EObject how, EObject object) throws Pausable { if (how != am_process) throw ERT.badarg(how, object); // case 1: object is a PID EHandle h = EHandle.cast(object); if (h != null) { ERef ref = ERT.getLocalNode().createRef(); if (!self.monitor(h, h, ref)) { self.mbox_send(ETuple.make(ERT.am_DOWN, ref, am_process, object, ERT.am_noproc)); } return ref; } // case 2: object is a name EAtom name; if (h == null && (name = object.testAtom()) != null) { ERef ref = ERT.getLocalNode().createRef(); boolean success = false; object = new ETuple2(name, ErlDist.node()); if ((h = ERT.whereis(name).testHandle()) != null) { success = self.monitor(h, object, ref); } if (!success) { self.mbox_send(ETuple.make(ERT.am_DOWN, ref, am_process, object, ERT.am_noproc)); } return ref; } // case 3: object is {name, node} ETuple tup; EAtom node; if ((tup = object.testTuple()) != null && tup.arity() == 2 && (name = tup.elm(1).testAtom()) != null && (node = tup.elm(2).testAtom()) != null) { if (node == ErlDist.node()) { ERef ref = ERT.getLocalNode().createRef(); boolean success = false; if ((h = ERT.whereis(name).testHandle()) != null) { success = self.monitor(h, object, ref); } if (!success) { self.mbox_send(ETuple.make(ERT.am_DOWN, ref, am_process, object, ERT.am_noproc)); } return ref; } else { EPeer peer = (EPeer) EPeer.get(node); if (peer != null) { ERef ref = ERT.getLocalNode().createRef(); self.monitor(tup, ref); peer.dsig_monitor(self.self_handle(), name, ref); return ref; } return ErlDist.dmonitor_p2_trap.invoke(self, new EObject[] {how, object}); } } throw ERT.badarg(how, object); }