📄 erl_process.h
字号:
extern Process** erts_active_procs;#endifextern Uint erts_max_processes;extern Uint erts_process_tab_index_mask;extern Uint erts_default_process_flags;/* If any of the erts_system_monitor_* variables are set (enabled),** erts_system_monitor must be != NIL, to allow testing on just** the erts_system_monitor_* variables.*/extern Eterm erts_system_monitor;extern Uint erts_system_monitor_long_gc;extern Uint erts_system_monitor_large_heap;struct erts_system_monitor_flags_t { unsigned int busy_port : 1; unsigned int busy_dist_port : 1;};extern struct erts_system_monitor_flags_t erts_system_monitor_flags;extern erts_smp_atomic_t erts_tot_proc_mem;#define INVALID_PID(p, pid) ((p) == NULL \ || (p)->id != (pid) \ || (p)->status == P_EXITING) #define IS_TRACED(p) ( (p)->tracer_proc != NIL )#define ARE_TRACE_FLAGS_ON(p,tf) ( ((p)->trace_flags & (tf|F_SENSITIVE)) == (tf) )#define IS_TRACED_FL(p,tf) ( IS_TRACED(p) && ARE_TRACE_FLAGS_ON(p,tf) )/* process priorities */#define PRIORITY_MAX 0#define PRIORITY_HIGH 1#define PRIORITY_NORMAL 2#define PRIORITY_LOW 3#define NPRIORITY_LEVELS 4/* times to reschedule low prio process before running */#define RESCHEDULE_LOW 8/* process flags */#define F_TRAPEXIT (1 << 0)#define F_INSLPQUEUE (1 << 1) /* Set if in timer queue */#define F_TIMO (1 << 2) /* Set if timeout */#define F_HEAP_GROW (1 << 3)#define F_NEED_FULLSWEEP (1 << 4) /* If process has old binaries & funs. */#define F_USING_DB (1 << 5) /* If have created tables */#define F_DISTRIBUTION (1 << 6) /* Process used in distribution */#define F_USING_DDLL (1 << 7) /* Process has used the DDLL interface */#define F_HAVE_BLCKD_MSCHED (1 << 8) /* Process have blocked multi-scheduling *//* process trace_flags */#define F_SENSITIVE (1 << 0)#define F_TRACE_SEND (1 << 1) #define F_TRACE_RECEIVE (1 << 2)#define F_TRACE_SOS (1 << 3) /* Set on spawn */#define F_TRACE_SOS1 (1 << 4) /* Set on first spawn */#define F_TRACE_SOL (1 << 5) /* Set on link */#define F_TRACE_SOL1 (1 << 6) /* Set on first link */#define F_TRACE_CALLS (1 << 7)#define F_TIMESTAMP (1 << 8)#define F_TRACE_PROCS (1 << 9)#define F_TRACE_FIRST_CHILD (1 << 10)#define F_TRACE_SCHED (1 << 11)#define F_TRACE_GC (1 << 12)#define F_TRACE_ARITY_ONLY (1 << 13)#define F_TRACE_RETURN_TO (1 << 14) /* Return_to trace when breakpoint tracing */#define F_TRACE_SILENT (1 << 15) /* No call trace msg suppress */#define F_TRACER (1 << 16) /* May be (has been) tracer */#define F_EXCEPTION_TRACE (1 << 17) /* May have exception trace on stack */#define F_NUM_FLAGS 18#ifdef DEBUG# define F_INITIAL_TRACE_FLAGS (5 << F_NUM_FLAGS)#else# define F_INITIAL_TRACE_FLAGS 0#endif#define TRACEE_FLAGS ( F_TRACE_PROCS | F_TRACE_CALLS \ | F_TRACE_SOS | F_TRACE_SOS1| F_TRACE_RECEIVE \ | F_TRACE_SOL | F_TRACE_SOL1 | F_TRACE_SEND | \ F_TRACE_SCHED | F_TIMESTAMP | F_TRACE_GC | \ F_TRACE_ARITY_ONLY | F_TRACE_RETURN_TO | \ F_TRACE_SILENT)/* Sequential trace flags */#define SEQ_TRACE_SEND (1 << 0)#define SEQ_TRACE_RECEIVE (1 << 1)#define SEQ_TRACE_PRINT (1 << 2)#define SEQ_TRACE_TIMESTAMP (1 << 3)#ifdef ERTS_SMP/* Status flags ... */#define ERTS_PROC_SFLG_PENDADD2SCHEDQ (((Uint32) 1) << 0) /* Pending add to schedule q */#define ERTS_PROC_SFLG_INRUNQ (((Uint32) 1) << 1) /* Process is in run q */#define ERTS_PROC_SFLG_TRAPEXIT (((Uint32) 1) << 2) /* Process is trapping exit */#define ERTS_PROC_SFLG_SCHEDULED (((Uint32) 1) << 3) /* Process is scheduled *//* Scheduler flags in process struct... */#define ERTS_PROC_SCHED_FLG_SCHEDULED (((Uint32) 1) << 0) /* Process is scheduled */#endif#ifdef ERTS_SMP#define ERTS_PROC_IS_TRAPPING_EXITS(P) \ (ERTS_SMP_LC_ASSERT(erts_proc_lc_my_proc_locks((P)) \ & ERTS_PROC_LOCK_STATUS), \ (P)->status_flags & ERTS_PROC_SFLG_TRAPEXIT)#define ERTS_PROC_SET_TRAP_EXIT(P) \ (ERTS_SMP_LC_ASSERT(((ERTS_PROC_LOCK_MAIN|ERTS_PROC_LOCK_STATUS) \ & erts_proc_lc_my_proc_locks((P))) \ == (ERTS_PROC_LOCK_MAIN|ERTS_PROC_LOCK_STATUS)), \ (P)->status_flags |= ERTS_PROC_SFLG_TRAPEXIT, \ (P)->flags |= F_TRAPEXIT, \ 1)#define ERTS_PROC_UNSET_TRAP_EXIT(P) \ (ERTS_SMP_LC_ASSERT(((ERTS_PROC_LOCK_MAIN|ERTS_PROC_LOCK_STATUS) \ & erts_proc_lc_my_proc_locks((P))) \ == (ERTS_PROC_LOCK_MAIN|ERTS_PROC_LOCK_STATUS)), \ (P)->status_flags &= ~ERTS_PROC_SFLG_TRAPEXIT, \ (P)->flags &= ~F_TRAPEXIT, \ 0)#else#define ERTS_PROC_IS_TRAPPING_EXITS(P) ((P)->flags & F_TRAPEXIT)#define ERTS_PROC_SET_TRAP_EXIT(P) ((P)->flags |= F_TRAPEXIT, 1)#define ERTS_PROC_UNSET_TRAP_EXIT(P) ((P)->flags &= ~F_TRAPEXIT, 0)#endif/* Option flags to erts_send_exit_signal() */#define ERTS_XSIG_FLG_IGN_KILL (((Uint32) 1) << 0)#define ERTS_XSIG_FLG_NO_IGN_NORMAL (((Uint32) 1) << 1)/* Process status values */#define P_FREE 0#define P_RUNABLE 1#define P_WAITING 2#define P_RUNNING 3#define P_EXITING 4#define P_GARBING 5#define P_SUSPENDED 6#define CANCEL_TIMER(p) \ do { \ if ((p)->flags & (F_INSLPQUEUE)) \ cancel_timer(p); \ else \ (p)->flags &= ~F_TIMO; \ } while (0)void erts_pre_init_process(void);#ifdef ERTS_SMPint erts_block_multi_scheduling(Process *, Uint32, int, int);int erts_is_multi_scheduling_blocked(void);Eterm erts_multi_scheduling_blockers(Process *);void erts_start_schedulers(Uint);void erts_smp_notify_check_children_needed(void);#endifvoid erts_init_process(void);Eterm erts_process_status(Process *, Uint32, Process *, Eterm);int sched_q_len(void);void add_to_schedule_q(Process*);Process *schedule(Process*, int);void erts_schedule_misc_op(void (*)(void *), void *);Eterm erl_create_process(Process*, Eterm, Eterm, Eterm, ErlSpawnOpts*);void erts_do_exit_process(Process*, Eterm);void set_timer(Process*, Uint);void cancel_timer(Process*);Uint erts_process_count(void);void erts_init_empty_process(Process *p);void erts_cleanup_empty_process(Process* p);#ifdef DEBUGvoid erts_debug_verify_clean_empty_process(Process* p);#endifvoid erts_stack_dump(int to, void *to_arg, Process *);void erts_program_counter_info(int to, void *to_arg, Process *);Eterm erts_get_process_priority(Process *p);Eterm erts_set_process_priority(Process *p, Eterm prio);Uint erts_get_total_context_switches(void);void erts_get_total_reductions(Uint *, Uint *);void erts_get_exact_total_reductions(Process *, Uint *, Uint *);void erts_suspend(Process*, Uint32, struct port*);void erts_resume(Process*, Uint32);int erts_send_exit_signal(Process *, Eterm, Process *, Uint32 *, Eterm, Eterm, Process *, Uint32);#ifdef ERTS_SMPvoid erts_handle_pending_exit(Process *, Uint32);#define ERTS_PROC_PENDING_EXIT(P) \ (ERTS_SMP_LC_ASSERT(erts_proc_lc_my_proc_locks((P)) & ERTS_PROC_LOCK_STATUS),\ (P)->pending_exit.reason != THE_NON_VALUE)#else#define ERTS_PROC_PENDING_EXIT(P) 0#endif#ifdef ERTS_SMPProcess *erts_suspend_another_process(Process *c_p, Uint32 c_p_locks, Eterm suspendee, Uint32 suspendee_locks);#endifvoid erts_deep_process_dump(int, void *);Sint erts_test_next_pid(int, Uint);#ifdef ERTS_SMP# define ERTS_GET_SCHEDULER_DATA_FROM_PROC(PROC) ((PROC)->scheduler_data)#else# define ERTS_GET_SCHEDULER_DATA_FROM_PROC(PROC) (&erts_scheduler_data)#endif#if defined(ERTS_SMP) || defined(USE_THREADS)ErtsSchedulerData *erts_get_scheduler_data(void);#elseERTS_GLB_INLINE ErtsSchedulerData *erts_get_scheduler_data(void);#if ERTS_GLB_INLINE_INCL_FUNC_DEFERTS_GLB_INLINEErtsSchedulerData *erts_get_scheduler_data(void){ return &erts_scheduler_data;}#endif#endifERTS_GLB_INLINE Process *erts_get_current_process(void);ERTS_GLB_INLINE Eterm erts_get_current_pid(void);#if ERTS_GLB_INLINE_INCL_FUNC_DEFERTS_GLB_INLINEProcess *erts_get_current_process(void){ ErtsSchedulerData *esdp = erts_get_scheduler_data(); return esdp ? esdp->current_process : NULL;}ERTS_GLB_INLINEEterm erts_get_current_pid(void){ Process *proc = erts_get_current_process(); return proc ? proc->id : THE_NON_VALUE;}#endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF *//* * Process locks. */#define ERTS_PROC_LOCK_MAX_BIT 3/* Process lock flags *//* * Main lock: * The main lock is held by the scheduler running a process. It * is used to protect all fields in the process structure except * for those fields protected by other process locks (follows). */#define ERTS_PROC_LOCK_MAIN (((Uint32) 1) << 0)/* * Link lock: * Protects the following fields in the process structure: * * nlinks * * monitors */#define ERTS_PROC_LOCK_LINK (((Uint32) 1) << 1)/* * Message queue lock: * Protects the following fields in the process structure: * * msg_inq * * bif_timers */#define ERTS_PROC_LOCK_MSGQ (((Uint32) 1) << 2)/* * Status lock: * Protects the following fields in the process structure: * * status * * rstatus * * status_flags */#define ERTS_PROC_LOCK_STATUS (((Uint32) 1) << ERTS_PROC_LOCK_MAX_BIT)/* * Special fields: * * The following fields are read only and can be read if at * least one process lock (whichever one doesn't matter) * is held: * * id * * The following fields are only allowed to be written if * all process locks are held, and are allowed to be read if * at least one process lock (whichever one doesn't matter) * is held: * * tracer_proc * * tracer_flags * * The following fields are only allowed to be accessed if * both the schedule queue lock and at least one process lock * (whichever one doesn't matter) are held: * * prio * * next * * scheduler_flags *//* * Other rules regarding process locking: * * Exiting processes: * When changing status to P_EXITING on a process, you are required * to take all process locks (ERTS_PROC_LOCKS_ALL). Thus, by holding * at least one process lock (whichever one doesn't matter) you * are guaranteed that the process won't exit until the lock you are * holding has been released. * At the same time as status is changed to P_EXITING, also the * field 'is_exiting' in the process structure is set to a value != 0 * and the lock flag ERTS_PROC_LOCK_FLAG_EXITING is set. * * Lock order: * Process locks with low numeric values has to be locked before * process locks with high numeric values. E.g., main locks has * to be locked before message queue locks. * * When process locks with the same numeric value are to be locked * on multiple processes, locks on processes with low process ids * have to be locked before locks on processes with high process * ids. E.g., if the main and the message queue locks are to be * locked on processes p1 and p2 and p1->id < p2->id, then locks * should be locked in the following order: * 1. main lock on p1 * 2. main lock on p2 * 3. message queue lock on p1 * 4. message queue lock on p2 *//* Other lock flags */#define ERTS_PROC_LOCK_FLAG_EXITING (((Uint32) 1) << 31)#define ERTS_PROC_LOCK_FLAG_WAITERS (((Uint32) 1) << 30)/* ERTS_PROC_LOCKS_* are combinations of process locks */#define ERTS_PROC_LOCKS_MSG_RECEIVE (ERTS_PROC_LOCK_MSGQ \ | ERTS_PROC_LOCK_STATUS)#define ERTS_PROC_LOCKS_MSG_SEND (ERTS_PROC_LOCK_MSGQ \ | ERTS_PROC_LOCK_STATUS)#define ERTS_PROC_LOCKS_XSIG_SEND (ERTS_PROC_LOCK_MSGQ \ | ERTS_PROC_LOCK_STATUS)#define ERTS_PROC_LOCKS_ALL \ ((((Uint32) 1) << (ERTS_PROC_LOCK_MAX_BIT + 1)) - 1)#define ERTS_PROC_LOCKS_ALL_MINOR (ERTS_PROC_LOCKS_ALL \ & ~ERTS_PROC_LOCK_MAIN)#define ERTS_CHK_HAVE_NO_PROC_LOCKS#define ERTS_CHK_HAVE_ONLY_MAIN_PROC_LOCK(PID)#if defined(ERTS_SMP) && defined(ERTS_ENABLE_LOCK_CHECK)#define ERTS_SMP_CHK_NO_PROC_LOCKS \ erts_proc_lc_chk_no_proc_locks(__FILE__, __LINE__)#else#define ERTS_SMP_CHK_NO_PROC_LOCKS#endif#ifdef ERTS_SMP#ifdef ERTS_ENABLE_LOCK_CHECKvoid erts_proc_lc_lock(Process *p, Uint32 locks);void erts_proc_lc_trylock(Process *p, Uint32 locks, int locked);void erts_proc_lc_unlock(Process *p, Uint32 locks);void erts_proc_lc_chk_have_proc_locks(Process *p, Uint32 locks);void erts_proc_lc_chk_proc_locks(Process *p, Uint32 locks);void erts_proc_lc_chk_only_proc_main(Process *p);void erts_proc_lc_chk_no_proc_locks(char *file, int line);Uint32 erts_proc_lc_my_proc_locks(Process *p);int erts_proc_lc_trylock_force_busy(Process *p, Uint32 locks);#endif#define ERTS_PROC_LOCKS_BITS 7#define ERTS_PROC_LOCKS_NO_OF (1 << ERTS_PROC_LOCKS_BITS)#define ERTS_PIX2LOCKIX(PIX) \ ((PIX) & ((1 << ERTS_PROC_LOCKS_BITS) - 1))#define ERTS_PID2LOCKIX(PID) \ (ERTS_PIX2LOCKIX(internal_pid_data((PID))))typedef struct { erts_smp_mtx_t mtx; erts_smp_cnd_t cnd;} erts_proc_lock_t;extern erts_proc_lock_t erts_proc_locks[ERTS_PROC_LOCKS_NO_OF];Uint32 erts_proc_get_locks(Process *, erts_proc_lock_t *, Uint32, int);ERTS_GLB_INLINE void erts_proc_lock(Process *p, Uint32 lock_flags);ERTS_GLB_INLINE int erts_proc_trylock(Process *p, Uint32 lock_flags);ERTS_GLB_INLINE void erts_proc_unlock(Process *p, Uint32 lock_flags);#if ERTS_GLB_INLINE_INCL_FUNC_DEFERTS_GLB_INLINE void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -