⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 erl_process.h

📁 OTP是开放电信平台的简称
💻 H
📖 第 1 页 / 共 3 页
字号:
erts_proc_lock(Process *p, Uint32 lock_flags){    Uint32 locks = lock_flags & ERTS_PROC_LOCKS_ALL;    erts_proc_lock_t *lckp = &erts_proc_locks[ERTS_PID2LOCKIX(p->id)];    erts_smp_mtx_lock(&lckp->mtx);    if (p->lock_flags & locks)	(void) erts_proc_get_locks(p, lckp, lock_flags, 1);#ifdef ERTS_ENABLE_LOCK_CHECK    else	erts_proc_lc_lock(p, locks);#endif    p->lock_flags |= lock_flags;    erts_smp_mtx_unlock(&lckp->mtx);}ERTS_GLB_INLINE interts_proc_trylock(Process *p, Uint32 lock_flags){    int res;    Uint32 locks = lock_flags & ERTS_PROC_LOCKS_ALL;    erts_proc_lock_t *lckp = &erts_proc_locks[ERTS_PID2LOCKIX(p->id)];    erts_smp_mtx_lock(&lckp->mtx);#ifdef ERTS_ENABLE_LOCK_CHECK    if (erts_proc_lc_trylock_force_busy(p, locks)) {	res = EBUSY; /* Make sure caller can handle the situation without			causing a lock order violation to occur */    }    else#endif    if (p->lock_flags & locks) {	res = EBUSY;    }    else {	p->lock_flags |= lock_flags;	res = 0;    }#ifdef ERTS_ENABLE_LOCK_CHECK    erts_proc_lc_trylock(p, locks, res == 0);#endif    erts_smp_mtx_unlock(&lckp->mtx);    return res;}ERTS_GLB_INLINE voiderts_proc_unlock(Process *p, Uint32 lock_flags){    erts_proc_lock_t *lckp = &erts_proc_locks[ERTS_PID2LOCKIX(p->id)];    erts_smp_mtx_lock(&lckp->mtx);#ifdef ERTS_ENABLE_LOCK_CHECK    erts_proc_lc_unlock(p, lock_flags & ERTS_PROC_LOCKS_ALL);#endif    p->lock_flags &= ~lock_flags;    if (p->lock_flags & ERTS_PROC_LOCK_FLAG_WAITERS) {	erts_smp_cnd_broadcast(&lckp->cnd); /* erts_smp_cnd_signal() won't do					       since mtx, cnd pair is used for					       multiple locks. */	p->lock_flags &= ~ERTS_PROC_LOCK_FLAG_WAITERS;    }    erts_smp_mtx_unlock(&lckp->mtx);}#endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */interts_proc_safelock(Process * this_proc,		   Uint32 this_have_locks,		   Uint32 this_need_locks,		   int allow_this_exiting,		   Uint32 other_pid,		   Process *other_proc,		   Uint32 other_have_locks,		   Uint32 other_need_locks,		   int allow_other_exiting);#endif /* #ifdef ERTS_SMP */#define ERTS_P2P_FLG_ALLOW_OTHER_X	(((Uint32) 1) <<  0)#ifdef ERTS_SMP/* * erts_pid2proc_opt(): * * Looks up the process structure of a pid and at the same time * acquires process locks. Locks on currently executing process and * looked up process are taken according to the lock order, i.e., * locks on currently executing process may have be released and * reacquired. Since all locks on currently executing process may * have to be released, it may become exiting. * *   Arguments: *	this_proc:		Normally currently executing process, *				but it can be any proc. *	this_have_locks:	currently aqired locks on this_proc *	pid:			pid of process to lookup *	pid_need_locks:		locks to acquire on looked up process *	allow_this_exiting:	If != 0, ignore if this_proc becomes *				exiting. * *   Return value:		A pointer to process struct of *				pid. *				  If a value != NULL is returned, *				this_have_locks are acquired on this_proc *				and pid_need_locks on looked up process. *				Both processes are valid processes, *				i.e. not in the states exiting or free. *				  If NULL is returned, either this_proc *				became exiting, or no process could be *				looked up. this_have_locks are acquired, *				on this_proc. *				  If allow_other_exiting != 0, lookup *				will proceed even if this_proc becomes *				exiting, i.e., this_proc may have become *				exiting	even if a value != NULL is *				returned. */ERTS_GLB_INLINE Process *erts_pid2proc_opt(Process *c_p, Uint32 c_p_have_locks,		  Eterm pid, Uint32 pid_need_locks, int flags);#if ERTS_GLB_INLINE_INCL_FUNC_DEFERTS_GLB_INLINE Process *erts_pid2proc_opt(Process *c_p, Uint32 c_p_have_locks,		  Eterm pid, Uint32 pid_need_locks, int flags){    erts_proc_lock_t *lckp;    Uint32 need_locks;    Uint pix;    Process *proc;    if (is_not_internal_pid(pid))	return NULL;    pix = internal_pid_index(pid);    if(pix >= erts_max_processes)	return NULL;    lckp = &erts_proc_locks[ERTS_PID2LOCKIX(pid)];    erts_smp_mtx_lock(&lckp->mtx);    need_locks = pid_need_locks & ERTS_PROC_LOCKS_ALL;    if (c_p && c_p->id == pid) {	need_locks &= ~c_p_have_locks;	proc = c_p;	ASSERT(c_p->id != ERTS_INVALID_PID);	ASSERT(c_p == process_tab[pix]);    }    else	proc = process_tab[pix];    if (!proc	|| proc->id != pid	|| ((proc->lock_flags & ERTS_PROC_LOCK_FLAG_EXITING)	    && !(flags & ERTS_P2P_FLG_ALLOW_OTHER_X))) {	proc = NULL;	goto done;    }    if (#ifdef ERTS_ENABLE_LOCK_CHECK	erts_proc_lc_trylock_force_busy(proc, need_locks) ||	/* Make sure erts_proc_safelock() is enough to handle	   a potential lock order violation situation... */#endif	(proc->lock_flags & need_locks)) {	erts_smp_mtx_unlock(&lckp->mtx);	if (!erts_proc_safelock(c_p,				c_p_have_locks,				c_p_have_locks,				1,				pid,				proc,				0,				need_locks,				flags & ERTS_P2P_FLG_ALLOW_OTHER_X))	    proc = NULL;    }    else {	/* Got them all at once... */	proc->lock_flags |= need_locks;#ifdef ERTS_ENABLE_LOCK_CHECK	if (need_locks)	    erts_proc_lc_trylock(proc, need_locks, 1);#endif    done:	erts_smp_mtx_unlock(&lckp->mtx);    }    return proc;}#endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */Process *erts_pid2proc_not_running(Process *, Uint32, Eterm, Uint32);#ifdef DEBUG#define ERTS_SMP_ASSERT_IS_NOT_EXITING(P) \  do { ASSERT(!(P)->is_exiting); } while (0)#else#define ERTS_SMP_ASSERT_IS_NOT_EXITING(P)#endif/* NOTE: At least one process lock has to be held on P! */#ifdef ERTS_ENABLE_LOCK_CHECK#define ERTS_PROC_IS_EXITING(P) \  (ERTS_SMP_LC_ASSERT(erts_proc_lc_my_proc_locks((P)) != 0), \   (P)->is_exiting)#else#define ERTS_PROC_IS_EXITING(P) ((P)->is_exiting)#endif#else /* !ERTS_SMP */#define ERTS_PROC_IS_EXITING(P) ((P)->status == P_EXITING)#define ERTS_SMP_ASSERT_IS_NOT_EXITING(P)#define erts_pid2proc_not_running erts_pid2proc#endif#define erts_pid2proc(PROC, HL, PID, NL) \  erts_pid2proc_opt((PROC), (HL), (PID), (NL), 0)ERTS_GLB_INLINE Process *#ifdef ERTS_SMPerts_pid2proc_unlocked_opt(Eterm pid, int flags);#elseerts_pid2proc_opt(Process *c_p_unused,		  Uint32 c_p_have_locks_unused,		  Eterm pid,		  Uint32 pid_need_locks_unused,		  int flags);#endif#if ERTS_GLB_INLINE_INCL_FUNC_DEFERTS_GLB_INLINE Process *#ifdef ERTS_SMPerts_pid2proc_unlocked_opt(Eterm pid, int flags)#elseerts_pid2proc_opt(Process *c_p_unused,		  Uint32 c_p_have_locks_unused,		  Eterm pid,		  Uint32 pid_need_locks_unused,		  int flags)#endif{    Uint pix;    Process *proc;    if (is_not_internal_pid(pid))	return NULL;    pix = internal_pid_index(pid);    if(pix >= erts_max_processes)	return NULL;    proc = process_tab[pix];    if (proc) {	if (proc->id != pid	    || (!(flags & ERTS_P2P_FLG_ALLOW_OTHER_X)		&& proc->status == P_EXITING))	    proc = NULL;    }    return proc;}#endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */#ifdef ERTS_SMP#define erts_pid2proc_unlocked(PID) erts_pid2proc_unlocked_opt((PID), 0)#else#define erts_pid2proc_unlocked(PID) erts_pid2proc_opt(NULL, 0, (PID), 0, 0)#endif/* Minimum NUMBER of processes for a small system to start */#ifdef ERTS_SMP#define ERTS_MIN_PROCESSES		ERTS_PROC_LOCKS_BITS#else#define ERTS_MIN_PROCESSES		16#endif/* Process locks */ERTS_GLB_INLINE void erts_smp_proc_lock(Process *p, Uint32 locks);ERTS_GLB_INLINE void erts_smp_proc_unlock(Process *p, Uint32 locks);ERTS_GLB_INLINE int  erts_smp_proc_trylock(Process *p, Uint32 locks);ERTS_GLB_INLINE void erts_smp_proc_tab_lock(void);ERTS_GLB_INLINE void erts_smp_proc_tab_unlock(void);#ifdef ERTS_INCLUDE_SCHEDULER_INTERNALS/* Scheduling lock */extern erts_smp_mtx_t schdlq_mtx;#ifdef ERTS_SMPextern int erts_all_schedulers_waiting;#endifERTS_GLB_INLINE int  erts_smp_sched_trylock(void);ERTS_GLB_INLINE void erts_smp_sched_lock(void);ERTS_GLB_INLINE void erts_smp_sched_unlock(void);ERTS_GLB_INLINE void erts_smp_notify_inc_runq(void);#if defined(ERTS_SMP) && defined(ERTS_ENABLE_LOCK_CHECK)int erts_smp_is_sched_locked(void);#endifvoid erts_wake_one_scheduler(void);#endif /* ERTS_INCLUDE_SCHEDULER_INTERNALS */#if ERTS_GLB_INLINE_INCL_FUNC_DEFERTS_GLB_INLINE voiderts_smp_proc_lock(Process *p, Uint32 locks){#ifdef ERTS_SMP    erts_proc_lock(p, locks);#endif}ERTS_GLB_INLINE voiderts_smp_proc_unlock(Process *p, Uint32 locks){#ifdef ERTS_SMP    erts_proc_unlock(p, locks);#endif}ERTS_GLB_INLINE interts_smp_proc_trylock(Process *p, Uint32 locks){#ifdef ERTS_SMP    return erts_proc_trylock(p, locks);#else    return 0;#endif}ERTS_GLB_INLINE voiderts_smp_proc_tab_lock(void){#ifdef ERTS_SMP    int i;    for (i = 0; i < ERTS_PROC_LOCKS_NO_OF; i++)	erts_smp_mtx_lock(&erts_proc_locks[i].mtx);#endif}ERTS_GLB_INLINE voiderts_smp_proc_tab_unlock(void){#ifdef ERTS_SMP    int i;    for (i = ERTS_PROC_LOCKS_NO_OF - 1; i >= 0; i--)	erts_smp_mtx_unlock(&erts_proc_locks[i].mtx);#endif}#ifdef ERTS_INCLUDE_SCHEDULER_INTERNALSERTS_GLB_INLINE interts_smp_sched_trylock(void){#ifdef ERTS_SMP    return erts_smp_mtx_trylock(&schdlq_mtx);#else    return 0;#endif}ERTS_GLB_INLINE voiderts_smp_sched_lock(void){#ifdef ERTS_SMP    erts_smp_mtx_lock(&schdlq_mtx);#endif}ERTS_GLB_INLINE voiderts_smp_sched_unlock(void){#ifdef ERTS_SMP    erts_smp_mtx_unlock(&schdlq_mtx);#endif}ERTS_GLB_INLINE voiderts_smp_notify_inc_runq(void){#ifdef ERTS_SMP    ERTS_SMP_LC_ASSERT(erts_smp_is_sched_locked());    if (erts_all_schedulers_waiting)	erts_wake_one_scheduler();#endif}#endif /* ERTS_INCLUDE_SCHEDULER_INTERNALS */#endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */#undef ERTS_INCLUDE_SCHEDULER_INTERNALS#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -