aboutsummaryrefslogtreecommitdiffstats
path: root/erts/lib_src/common/ethr_aux.c
diff options
context:
space:
mode:
Diffstat (limited to 'erts/lib_src/common/ethr_aux.c')
-rw-r--r--erts/lib_src/common/ethr_aux.c115
1 files changed, 95 insertions, 20 deletions
diff --git a/erts/lib_src/common/ethr_aux.c b/erts/lib_src/common/ethr_aux.c
index 0cbb1b2fb8..7b156fe01a 100644
--- a/erts/lib_src/common/ethr_aux.c
+++ b/erts/lib_src/common/ethr_aux.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2010-2014. All Rights Reserved.
+ * Copyright Ericsson AB 2010-2017. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -68,6 +68,8 @@ size_t ethr_max_stack_size__; /* kilo words */
ethr_rwmutex xhndl_rwmtx;
ethr_xhndl_list *xhndl_list;
+static ethr_tsd_key ethr_stacklimit_key__;
+
static int main_threads;
static int init_ts_event_alloc(void);
@@ -139,6 +141,38 @@ x86_init(void)
#endif
/* bit 26 of edx is set if we have sse2 */
ethr_runtime__.conf.have_sse2 = (edx & (1 << 26));
+
+ /* check if we have extended feature set */
+ eax = 0x80000000;
+ ethr_x86_cpuid__(&eax, &ebx, &ecx, &edx);
+
+ if (eax < 0x80000001)
+ return;
+
+ if (eax >= 0x80000007) {
+ /* Advanced Power Management Information */
+ eax = 0x80000007;
+ ethr_x86_cpuid__(&eax, &ebx, &ecx, &edx);
+
+ /* I got the values below from:
+ http://lxr.free-electrons.com/source/arch/x86/include/asm/cpufeature.h
+ They can be gotten from the intel/amd manual as well.
+ */
+
+ ethr_runtime__.conf.have_constant_tsc = (edx & (1 << 8));
+ ethr_runtime__.conf.have_tsc_reliable = (edx & (1 << 23));
+ ethr_runtime__.conf.have_nonstop_tsc = (edx & (1 << 24));
+ ethr_runtime__.conf.have_nonstop_tsc_s3 = (edx & (1 << 30));
+
+ }
+
+ /* Extended Processor Info and Feature Bits */
+ eax = 0x80000001;
+ ethr_x86_cpuid__(&eax, &ebx, &ecx, &edx);
+
+ /* bit 27 of edx is set if we have rdtscp */
+ ethr_runtime__.conf.have_rdtscp = (edx & (1 << 27));
+
}
#endif /* ETHR_X86_RUNTIME_CONF__ */
@@ -188,7 +222,7 @@ ethr_init_common__(ethr_init_data *id)
ethr_min_stack_size__ += ethr_pagesize__;
#endif
/* The system may think that we need more stack */
-#if defined(PTHREAD_STACK_MIN)
+#if defined(ETHR_HAVE_USABLE_PTHREAD_STACK_MIN)
if (ethr_min_stack_size__ < PTHREAD_STACK_MIN)
ethr_min_stack_size__ = PTHREAD_STACK_MIN;
#elif defined(_SC_THREAD_STACK_MIN)
@@ -205,24 +239,11 @@ ethr_init_common__(ethr_init_data *id)
#endif
ethr_min_stack_size__ = ETHR_PAGE_ALIGN(ethr_min_stack_size__);
- ethr_min_stack_size__ = ETHR_B2KW(ethr_min_stack_size__);
-
-#ifdef __OSE__
- /* For supervisor processes, OSE adds a number of bytes to the requested stack. With this
- * addition, the resulting size must not exceed the largest available stack size. The number
- * of bytes that will be added is configured in the monolith and can therefore not be
- * specified here. We simply assume that it is less than 0x1000. The available stack sizes
- * are configured in the .lmconf file and the largest one is usually 65536 bytes.
- * Consequently, the requested stack size is limited to 0xF000.
- */
- ethr_max_stack_size__ = 0xF000;
-#else
ethr_max_stack_size__ = 32*1024*1024;
-#endif
#if SIZEOF_VOID_P == 8
ethr_max_stack_size__ *= 2;
#endif
- ethr_max_stack_size__ = ETHR_B2KW(ethr_max_stack_size__);
+ ethr_max_stack_size__ = ETHR_PAGE_ALIGN(ethr_max_stack_size__);
res = ethr_init_atomics();
if (res != 0)
@@ -232,6 +253,10 @@ ethr_init_common__(ethr_init_data *id)
if (res != 0)
return res;
+ res = ethr_tsd_key_create(&ethr_stacklimit_key__, "stacklimit");
+ if (res != 0)
+ return res;
+
xhndl_list = NULL;
return 0;
@@ -292,6 +317,60 @@ ethr_late_init_common__(ethr_late_init_data *lid)
return 0;
}
+/*
+ * Stack limit
+ */
+
+void *ethr_get_stacklimit(void)
+{
+ return ethr_tsd_get(ethr_stacklimit_key__);
+}
+
+int ethr_set_stacklimit(void *limit)
+{
+ void *prev = ethr_tsd_get(ethr_stacklimit_key__);
+ if (prev)
+ return EACCES;
+ if (!limit)
+ return EINVAL;
+ return ethr_tsd_set(ethr_stacklimit_key__, limit);
+}
+
+/* internal stacklimit (thread creation) */
+
+void
+ethr_set_stacklimit__(char *prev_c, size_t stacksize)
+{
+ /*
+ * We *don't* want this function inlined, i.e., it is
+ * risky to call this function from another function
+ * in ethr_aux.c
+ */
+ void *limit = NULL;
+ char c;
+ int res;
+
+ if (stacksize) {
+ char *start;
+ if (&c > prev_c) {
+ start = (char *) ((((ethr_uint_t) prev_c)
+ / ethr_pagesize__)
+ * ethr_pagesize__);
+ limit = start + stacksize;
+ }
+ else {
+ start = (char *) (((((ethr_uint_t) prev_c) - 1)
+ / ethr_pagesize__ + 1)
+ * ethr_pagesize__);
+ limit = start - stacksize;
+ }
+ }
+
+ res = ethr_tsd_set(ethr_stacklimit_key__, limit);
+ if (res != 0)
+ ethr_abort__();
+}
+
int
ethr_install_exit_handler(void (*funcp)(void))
{
@@ -664,10 +743,6 @@ ETHR_IMPL_NORETURN__ ethr_fatal_error__(const char *file,
int ethr_assert_failed(const char *file, int line, const char *func, char *a)
{
fprintf(stderr, "%s:%d: %s(): Assertion failed: %s\n", file, line, func, a);
-#ifdef __OSE__
- ramlog_printf("%d: %s:%d: %s(): Assertion failed: %s\n",
- current_process(),file, line, func, a);
-#endif
ethr_abort__();
return 0;
}