在具有许多SC_THREAD
进程的SystemC模拟(> 32000)的上下文中,我在运行Ubuntu 15.04的Intel X86平台上的Accellera 2.3.1实施中面临以下错误:
sc_cor_qt.cpp:114: virtual void sc_core::sc_cor_qt::stack_protect(bool)
Assertion `ret == 0' failed
SystemC 内核的默认实现使用用户级线程(也称为协程)来实现 SystemC 进程。静态进程(SC_THREAD
和SC_CTHREAD
)在sc_simcontext.cpp
行759中初始化thread_p->prepare_for_simulation()
此函数将创建用户级线程对象,然后启用堆栈保护。
用户级线程的堆栈由以下行cor->m_stack = new char[cor->m_stack_size]
在 SystemC 模拟进程的堆中分配
我面临的问题发生在创建后的堆栈保护功能中,该功能使用 mprotect
系统调用使用户级线程堆栈之后的页面(再次,在 Linux 进程的堆中)根本无法访问(PROT_NONE
)。我从mprotect
那里收到的错误(ENOMEM
)说我们要保护的这个页面从未映射到进程中,或者内核在运行mprotect
调用时无法分配一些内部结构。不幸的是,我无法知道这两个错误中的哪一个发生以及如何解决它。
此外,在进行mprotect
调用之前,我看不到这个额外的页面在 Linux 进程的堆中分配的位置。
有谁知道发生了什么和/或我能做些什么来进一步调试这个问题?
问题是单个进程允许的最大内存映射数。每个mprotect
调用都会导致单个内存映射,从而导致映射总数大于系统的默认限制。要增加此限制,必须使用:
sudo sysctl vm/max_map_count=524240
存储应该在堆上,但请尝试增加堆栈大小,以防限制某些 SC 对象的分配。
检查当前堆栈大小:(来自 csh)
限制(或来自 sh:ulimit -a)
如果不是无限制的,请通过以下之一增加:
限制堆栈大小 1024M(来自 SH:ULIMIT -S 1024000)
限制堆栈大小无限制(来自 sh:ulimit -s unlimited)