“OTP 源码编译”的版本间的差异

来自Dennis的知识库
跳转到: 导航搜索
erl_process.c
 
(未显示1个用户的5个中间版本)
第48行: 第48行:
 
</pre>
 
</pre>
  
=== erl_lock_check.c ===
+
* 垃圾回收也消耗 reductions:
 +
 
 +
<pre>
 +
int cost = scheduler_gc_proc(p, reds);
 +
calls += cost;
 +
reds -= cost;
 +
</pre>
 +
 
 +
=== erl_lock_check.c 和锁 ===
 
*  确保 BEAM 的加锁顺序是一致的,防止死锁。
 
*  确保 BEAM 的加锁顺序是一致的,防止死锁。
 
<pre>
 
<pre>
第58行: 第66行:
 
  *              intended to be enabled when debugging.
 
  *              intended to be enabled when debugging.
 
</pre>
 
</pre>
 +
 +
 +
* include/internal/ 下面是各平台的锁的实现,比如 spinlock, rwlock, x86 平台在 i386 目录下,比如 spinlock.h,使用 xchgb 指令汇编实现
 +
 +
<pre>
 +
static ETHR_INLINE int
 +
ethr_native_spin_trylock(ethr_native_spinlock_t *lock)
 +
{
 +
    char tmp = 1;
 +
    __asm__ __volatile__(
 +
"xchgb %b0, %1"
 +
: "=q"(tmp), "=m"(lock->lock)
 +
: "0"(tmp) : "memory");
 +
    return tmp == 0;
 +
}
 +
static ETHR_INLINE void
 +
ethr_native_spin_lock(ethr_native_spinlock_t *lock)
 +
{
 +
    for(;;) {
 +
if (__builtin_expect(ethr_native_spin_trylock(lock) != 0, 1))
 +
    break;
 +
do {
 +
    __asm__ __volatile__("rep;nop" : "=m"(lock->lock) : : "memory");
 +
} while (ethr_native_spin_is_locked(lock));
 +
    }
 +
}
 +
 +
</pre>
 +
 +
如果没有特定平台的实现,那就使用  pthread_spin_lock, native 的实现没有采用 backoff 或者 queue 技术来优化。但是 "rep;nop" 等价于 pause 指令,这是为了 spinlock 性能优化引入的。参考 http://stackoverflow.com/questions/7086220/what-does-rep-nop-mean-in-x86-assembly

2017年1月7日 (六) 12:45的最后版本

目录

[编辑] OTP 源码阅读杂记

[编辑] 编译

git clone https://github.com/erlang/otp.git
cd otp
export ERL_TOP=`pwd`
./otp_build  setup
brew install fop openssl
./configure --help #查看编译选项
./configure --with-ssl=/usr/local/opt/openssl
make

[编辑] erl_process.c

  • 优先运行 port 直到完成。
	/*
	 * Find a new port to run.
	 */

	if (RUNQ_READ_LEN(&rq->ports.info.len)) {
	    int have_outstanding_io;
	    have_outstanding_io = erts_port_task_execute(rq, &esdp->current_port);
	    if ((!erts_eager_check_io
		 && have_outstanding_io
		 && fcalls > 2*input_reductions)
		|| rq->halt_in_progress) {
		/*
		 * If we have performed more than 2*INPUT_REDUCTIONS since
		 * last call to erl_sys_schedule() and we still haven't
		 * handled all I/O tasks we stop running processes and
		 * focus completely on ports.
		 *
		 * One could argue that this is a strange behavior. The
		 * reason for doing it this way is that it is similar
		 * to the behavior before port tasks were introduced.
		 * We don't want to change the behavior too much, at
		 * least not at the time of writing. This behavior
		 * might change in the future.
		 *
		 * /rickard
		 */
		goto check_activities_to_run;
	    }
	}
  • 垃圾回收也消耗 reductions:
int cost = scheduler_gc_proc(p, reds);
		calls += cost;
		reds -= cost;

[编辑] erl_lock_check.c 和锁

  • 确保 BEAM 的加锁顺序是一致的,防止死锁。
 * Description: A lock checker that checks that each thread acquires
 *              locks according to a predefined global lock order. The
 *              global lock order is used to prevent deadlocks. If the
 *              lock order is violated, an error message is printed
 *              and the emulator aborts. The lock checker is only
 *              intended to be enabled when debugging.


  • include/internal/ 下面是各平台的锁的实现,比如 spinlock, rwlock, x86 平台在 i386 目录下,比如 spinlock.h,使用 xchgb 指令汇编实现
static ETHR_INLINE int
ethr_native_spin_trylock(ethr_native_spinlock_t *lock)
{
    char tmp = 1;
    __asm__ __volatile__(
	"xchgb %b0, %1"
	: "=q"(tmp), "=m"(lock->lock)
	: "0"(tmp) : "memory");
    return tmp == 0;
}
static ETHR_INLINE void
ethr_native_spin_lock(ethr_native_spinlock_t *lock)
{
    for(;;) {
	if (__builtin_expect(ethr_native_spin_trylock(lock) != 0, 1))
	    break;
	do {
	    __asm__ __volatile__("rep;nop" : "=m"(lock->lock) : : "memory");
	} while (ethr_native_spin_is_locked(lock));
    }
}

如果没有特定平台的实现,那就使用 pthread_spin_lock, native 的实现没有采用 backoff 或者 queue 技术来优化。但是 "rep;nop" 等价于 pause 指令,这是为了 spinlock 性能优化引入的。参考 http://stackoverflow.com/questions/7086220/what-does-rep-nop-mean-in-x86-assembly

个人工具
名字空间

变换
操作
导航
工具箱