📄 erl_process.h
字号:
/* ``The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved via the world wide web at http://www.erlang.org/. * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Initial Developer of the Original Code is Ericsson Utvecklings AB. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings * AB. All Rights Reserved.'' * * $Id$ */#ifndef __PROCESS_H__#define __PROCESS_H__#undef ERTS_INCLUDE_SCHEDULER_INTERNALS#if (defined(ERL_PROCESS_C__) \ || defined(ERL_PORT_TASK_C__) \ || (ERTS_GLB_INLINE_INCL_FUNC_DEF \ && defined(ERTS_DO_INCL_GLB_INLINE_FUNC_DEF)))#define ERTS_INCLUDE_SCHEDULER_INTERNALS#endif#include "sys.h"#include "erl_vm.h"#include "erl_message.h"#include "erl_process_dict.h"#include "erl_node_container_utils.h"#include "erl_node_tables.h"#include "erl_monitors.h"#include "erl_bif_timer.h"#include "erl_time.h"#ifdef ERTS_SMP#include "erl_vm.h"#include "erl_term.h"#include "erl_threads.h"#endif#ifdef HIPE#include "hipe_process.h"#endifstruct ErtsNodesMonitor_;struct port;#define ERTS_MAX_NO_OF_SCHEDULERS 1024#define ERTS_DEFAULT_MAX_PROCESSES (1 << 15)Uint erts_get_tot_proc_mem(void);#define ERTS_PROC_MORE_MEM(Size) \ (erts_smp_atomic_add(&erts_tot_proc_mem, (long) (Size)))#define ERTS_PROC_LESS_MEM(Size) \ (ASSERT_EXPR(erts_smp_atomic_read(&erts_tot_proc_mem) >= (long) (Size)), \ erts_smp_atomic_add(&erts_tot_proc_mem, -((long) (Size))))#define ERTS_HEAP_ALLOC(Type, Size) \ (ERTS_PROC_MORE_MEM((Size)), \ erts_alloc((Type), (Size)))#define ERTS_HEAP_REALLOC(Type, Ptr, OldSize, NewSize) \ (ERTS_PROC_LESS_MEM((OldSize)), \ ERTS_PROC_MORE_MEM((NewSize)), \ erts_realloc((Type), (Ptr), (NewSize)))#define ERTS_HEAP_FREE(Type, Ptr, Size) \ (ERTS_PROC_LESS_MEM((Size)), \ erts_free((Type), (Ptr)))#define INITIAL_MOD 0#define INITIAL_FUN 1#define INITIAL_ARI 2struct saved_calls { int len; int n; int cur; Export *ct[1];};extern Export exp_send, exp_receive, exp_timeout;extern Uint erts_no_of_schedulers;#ifdef ERTS_SMP/* XXX: mutually recursive .h files break when abstract types are 'typedefs'. This #define kludge works around this particular cycle, but spelling out 'struct foo*' in more places works better in the long run IMO. */struct process;#define Process struct process#include "erl_bits.h"#undef Process#endiftypedef struct ErtsSchedulerData_ ErtsSchedulerData;struct ErtsSchedulerData_ {#ifdef ERTS_SMP ErtsSchedulerData *next; /* Next scheduler data */ ErtsSchedulerData *prev; /* Prev scheduler data */ ethr_tid tid; /* Thread id */ Uint no; /* Scheduler number */ Eterm save_reg[ERTS_X_REGS_ALLOCATED]; /* X registers */ FloatDef freg[MAX_REG]; /* Floating point registers. */ struct erl_bits_state erl_bits_state; /* erl_bits.c state */ void *match_pseudo_process; /* erl_db_util.c:db_prog_match() */ struct process *free_process;#endif struct process *current_process;#ifdef ERTS_SMP_SCHEDULERS_NEED_TO_CHECK_CHILDREN /* NOTE: These fields are modified under held mutexes by other threads */ int check_children; /* schdlq mutex */ int blocked_check_children; /* multi_scheduling_block mutex */#endif};#ifndef ERTS_SMPextern ErtsSchedulerData erts_scheduler_data;#endiftypedef struct _process_list { Eterm pid; /* Waiting process. (internal pid) */ struct _process_list* next; /* Next waiting process. */} ProcessList;typedef struct { Eterm reason; ErlHeapFragment *bp;} ErtsPendExit;typedef struct process { /* All fields in the PCB that differs between different heap * architectures, have been moved to the end of this struct to * make sure that as few offsets as possible differ. Different * offsets between memory architectures in this struct, means that * native code have to use functions instead of constants. */ Eterm* htop; /* Heap top */ Eterm* stop; /* Stack top */ Eterm* heap; /* Heap start */ Eterm* hend; /* Heap end */ Uint heap_sz; /* Size of heap in words */ Uint min_heap_size; /* Minimum size of heap (in words). */#if !defined(NO_FPE_SIGNALS) volatile int fp_exception;#endif#ifdef HIPE /* HiPE-specific process fields. Put it early in struct process, to enable smaller & faster addressing modes on the x86. */ struct hipe_process_state hipe;#endif /* * Saved x registers. */ Uint arity; /* Number of live argument registers (only valid * when process is *not* running). */ Eterm* arg_reg; /* Pointer to argument registers. */ unsigned max_arg_reg; /* Maximum number of argument registers available. */ Eterm def_arg_reg[6]; /* Default array for argument registers. */ Eterm* cp; /* Continuation pointer (for threaded code). */ Eterm* i; /* Program counter for threaded code. */ Sint catches; /* Number of catches on stack */ Sint fcalls; /* * Number of reductions left to execute. * Only valid for the current process. */ Uint32 status; /* process STATE */ Uint32 rstatus; /* process resume STATE */ int rcount; /* suspend count */ Eterm id; /* The pid of this process */ int prio; /* Priority of process */ int skipped; /* Times a low prio process has been rescheduled */ Uint reds; /* No of reductions for this process */ Eterm error_handler; /* Module atom for the error handler */ Eterm tracer_proc; /* If proc is traced, this is the tracer (can NOT be boxed) */ Uint trace_flags; /* Trace flags (used to be in flags) */ Eterm group_leader; /* Pid in charge (can be boxed) */ Uint flags; /* Trap exit, etc (no trace flags anymore) */ Eterm fvalue; /* Exit & Throw value (failure reason) */ Uint freason; /* Reason for detected failure */ Eterm ftrace; /* Latest exception stack trace dump */ DistEntry *dist_entry; /* Distribution slot to use if F_DISTRIBUTION */ struct process *next; /* Pointer to next process in list */ struct reg_proc *reg; /* NULL iff not registered */ ErtsLink *nlinks; ErtsMonitor *monitors; /* The process monitors, both ends */ struct ErtsNodesMonitor_ *nodes_monitors; ErlMessageQueue msg; /* Message queue */ ErtsBifTimer *bif_timers; /* Bif timers aiming at this process */ ProcDict *dictionary; /* Process dictionary, may be NULL */ ProcDict *debug_dictionary; /* Process dictionary-like debugging * information, private to OTP applications */ struct saved_calls *ct; Uint seq_trace_clock; Uint seq_trace_lastcnt; Eterm seq_trace_token; /* Sequential trace token (tuple size 5 see below) */ Eterm initial[3]; /* Initial module(0), function(1), arity(2) */ Eterm* current; /* Current Erlang function: * module(0), function(1), arity(2) * (module and functions are tagged atoms; * arity an untagged integer). */ /* * Information mainly for post-mortem use (erl crash dump). */ Eterm parent; /* Pid of process that created this process. */ long started; /* Time when started. */ /* This is the place, where all fields that differs between memory * architectures, have gone to. */ Eterm *high_water; Eterm *old_hend; /* Heap pointers for generational GC. */ Eterm *old_htop; Eterm *old_heap; Uint16 gen_gcs; /* Number of (minor) generational GCs. */ Uint16 max_gen_gcs; /* Max minor gen GCs before fullsweep. */ ErlOffHeap off_heap; /* Off-heap data updated by copy_struct(). */ ErlHeapFragment* mbuf; /* Pointer to message buffer list */ Uint mbuf_sz; /* Size of all message buffers */#if !defined(HEAP_FRAG_ELIM_TEST) /* * Secondary heap for arithmetic operations. */ Eterm* arith_heap; /* Current heap pointer. */ Uint arith_avail; /* Available space on arithmetic heap. */#if (defined(DEBUG) || defined(PURIFY)) char* arith_file; int arith_line; Eterm* arith_check_me; /* Address to check for overwrite. */#endif#endif#ifdef ERTS_SMP ErtsSmpPTimer *ptimer;#else ErlTimer tm; /* Timer entry */#endif#ifdef ERTS_SMP ErtsSchedulerData *scheduler_data; int is_exiting; Uint32 scheduler_flags; Uint32 status_flags; Uint32 lock_flags; ErlMessageInQueue msg_inq; Eterm suspendee; ProcessList *pending_suspenders; ErtsPendExit pending_exit;#ifdef HIPE struct hipe_process_state_smp hipe_smp;#endif#endif#ifdef HYBRID Eterm *rrma; /* Remembered roots to Message Area */ Eterm **rrsrc; /* The source of the root */ Uint nrr; /* Number of remembered roots */ Uint rrsz; /* Size of root array */#endif#ifdef HYBRID Uint active; /* Active since last major collection? */ Uint active_index; /* Index in the active process array */#endif #ifdef INCREMENTAL struct process *active_next; /* Active processes to scan for roots */ struct process *active_prev; /* in collection of the message area */ Eterm *scan_top;#endif#ifdef CHECK_FOR_HOLES Eterm* last_htop; /* No need to scan the heap below this point. */ ErlHeapFragment* last_mbuf; /* No need to scan beyond this mbuf. */#endif} Process;#ifdef CHECK_FOR_HOLES# define INIT_HOLE_CHECK(p) \do { \ (p)->last_htop = 0; \ (p)->last_mbuf = 0; \} while (0)# define ERTS_HOLE_CHECK(p) erts_check_for_holes((p))void erts_check_for_holes(Process* p);#else# define INIT_HOLE_CHECK(p)# define ERTS_HOLE_CHECK(p)#endif/* * The MBUF_GC_FACTOR decides how easily a process is subject to GC * due to message buffers allocated outside the heap. * The larger the factor, the easier the process gets GCed. * On a small memory system with lots of processes, this makes a significant * difference, especially since the GCs help fragmentation quite a bit too. */#if defined(SMALL_MEMORY)#define MBUF_GC_FACTOR 4#else#define MBUF_GC_FACTOR 1#endif/* * The weight of binaries outside the heap (for p->overhead calculation). */#define BINARY_OVERHEAD_FACTOR 16/* * Force a garbage collection for the given process. */#define FORCE_GC(p) ((p)->off_heap.overhead = p->heap_sz)#define SEQ_TRACE_TOKEN(p) ((p)->seq_trace_token)/* The sequential tracing token is a tuple of size 5: * * {Flags, Label, Serial, Sender} */#define SEQ_TRACE_TOKEN_ARITY(p) (arityval(*(tuple_val(SEQ_TRACE_TOKEN(p)))))#define SEQ_TRACE_TOKEN_FLAGS(p) (*(tuple_val(SEQ_TRACE_TOKEN(p)) + 1))#define SEQ_TRACE_TOKEN_LABEL(p) (*(tuple_val(SEQ_TRACE_TOKEN(p)) + 2))#define SEQ_TRACE_TOKEN_SERIAL(p) (*(tuple_val(SEQ_TRACE_TOKEN(p)) + 3))#define SEQ_TRACE_TOKEN_SENDER(p) (*(tuple_val(SEQ_TRACE_TOKEN(p)) + 4))#define SEQ_TRACE_TOKEN_LASTCNT(p) (*(tuple_val(SEQ_TRACE_TOKEN(p)) + 5))/* used when we have unit32 token */#define SEQ_TRACE_T_ARITY(token) (arityval(*(tuple_val(token))))#define SEQ_TRACE_T_FLAGS(token) (*(tuple_val(token) + 1))#define SEQ_TRACE_T_LABEL(token) (*(tuple_val(token) + 2))#define SEQ_TRACE_T_SERIAL(token) (*(tuple_val(token) + 3))#define SEQ_TRACE_T_SENDER(token) (*(tuple_val(token) + 4))#define SEQ_TRACE_T_LASTCNT(token) (*(tuple_val(token) + 5))/* * Possible flags for the flags field in ErlSpawnOpts below. */#define SPO_LINK 1#define SPO_USE_ARGS 2#define SPO_MONITOR 4/* * The following struct contains options for a process to be spawned. */typedef struct { Uint flags; int error_code; /* Error code returned from create_process(). */ Eterm mref; /* Monitor ref returned (if SPO_MONITOR was given). */ /* * The following items are only initialized if the SPO_USE_ARGS flag is set. */ Uint min_heap_size; /* Minimum heap size (must be a valued returned * from next_heap_size()). */ int priority; /* Priority for process. */ Uint16 max_gen_gcs; /* Maximum number of gen GCs before fullsweep. */} ErlSpawnOpts;/* * The KILL_CATCHES(p) macro kills pending catches for process p. */#define KILL_CATCHES(p) (p)->catches = -1void erts_arith_shrink(Process* p, Eterm* hp);Eterm* erts_heap_alloc(Process* p, Uint need);#ifdef CHECK_FOR_HOLESEterm* erts_set_hole_marker(Eterm* ptr, Uint sz);#endifextern Process** process_tab;#ifdef HYBRIDextern Uint erts_num_active_procs;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -