aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r--erts/emulator/beam/atom.c12
-rw-r--r--erts/emulator/beam/atom.h21
-rw-r--r--erts/emulator/beam/erl_init.c22
-rw-r--r--erts/emulator/beam/erl_port_task.c12
-rw-r--r--erts/emulator/beam/erl_process.c38
-rw-r--r--erts/emulator/beam/erl_vm.h2
-rw-r--r--erts/emulator/beam/external.c7
7 files changed, 88 insertions, 26 deletions
diff --git a/erts/emulator/beam/atom.c b/erts/emulator/beam/atom.c
index dfc3cde6a7..e2a79d6e4f 100644
--- a/erts/emulator/beam/atom.c
+++ b/erts/emulator/beam/atom.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -322,7 +322,7 @@ init_atom_table(void)
text_list = NULL;
erts_index_init(ERTS_ALC_T_ATOM_TABLE, &erts_atom_table,
- "atom_tab", ATOM_SIZE, ATOM_LIMIT, f);
+ "atom_tab", ATOM_SIZE, erts_atom_table_size, f);
more_atom_space();
/* Ordinary atoms */
diff --git a/erts/emulator/beam/atom.h b/erts/emulator/beam/atom.h
index e7e0dc440d..cb245a87b1 100644
--- a/erts/emulator/beam/atom.h
+++ b/erts/emulator/beam/atom.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1996-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1996-2010. All Rights Reserved.
+ *
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
- *
+ *
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
- *
+ *
* %CopyrightEnd%
*/
@@ -28,6 +28,17 @@
#define MAX_ATOM_LENGTH 255
#define ATOM_LIMIT (1024*1024)
+#define MIN_ATOM_TABLE_SIZE 8192
+
+#ifndef ARCH_32
+/* Internal atom cache needs MAX_ATOM_TABLE_SIZE to be less than an
+ unsigned 32 bit integer. See external.c(erts_encode_ext_dist_header_setup)
+ for more details. */
+#define MAX_ATOM_TABLE_SIZE ((MAX_ATOM_INDEX + 1 < (1UL << 32)) ? MAX_ATOM_INDEX + 1 : (1UL << 32))
+#else
+#define MAX_ATOM_TABLE_SIZE (MAX_ATOM_INDEX + 1)
+#endif
+
/*
* Atom entry.
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index bdf888eaff..17cf3b9597 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -119,6 +119,8 @@ int erts_disable_tolerant_timeofday; /* Time correction can be disabled it is
* not and/or it is too slow.
*/
+int erts_atom_table_size = ATOM_LIMIT; /* Maximum number of atoms */
+
int erts_modified_timing_level;
int erts_no_crash_dump = 0; /* Use -d to suppress crash dump. */
@@ -569,6 +571,10 @@ void erts_usage(void)
erts_fprintf(stderr, " schedulers online (n2), valid range for both\n");
erts_fprintf(stderr, " numbers are [1-%d]\n",
ERTS_MAX_NO_OF_SCHEDULERS);
+ erts_fprintf(stderr, "-t size set the maximum number of atoms the "
+ "emulator can handle\n");
+ erts_fprintf(stderr, " valid range is [%d-%d]\n",
+ MIN_ATOM_TABLE_SIZE, MAX_ATOM_TABLE_SIZE);
erts_fprintf(stderr, "-T number set modified timing level,\n");
erts_fprintf(stderr, " valid range is [0-%d]\n",
ERTS_MODIFIED_TIMING_LEVELS-1);
@@ -1140,6 +1146,22 @@ erl_start(int argc, char **argv)
}
break;
}
+ case 't':
+ /* set atom table size */
+ arg = get_arg(argv[i]+2, argv[i+1], &i);
+ errno = 0;
+ erts_atom_table_size = strtol(arg, NULL, 10);
+ if (errno != 0 ||
+ erts_atom_table_size < MIN_ATOM_TABLE_SIZE ||
+ erts_atom_table_size > MAX_ATOM_TABLE_SIZE) {
+ erts_fprintf(stderr, "bad atom table size %s\n", arg);
+ erts_usage();
+ }
+ VERBOSE(DEBUG_SYSTEM,
+ ("setting maximum number of atoms to %d\n",
+ erts_atom_table_size));
+ break;
+
case 'T' :
arg = get_arg(argv[i]+2, argv[i+1], &i);
errno = 0;
diff --git a/erts/emulator/beam/erl_port_task.c b/erts/emulator/beam/erl_port_task.c
index 3cb5a966ac..0b6bb0d8e9 100644
--- a/erts/emulator/beam/erl_port_task.c
+++ b/erts/emulator/beam/erl_port_task.c
@@ -575,7 +575,7 @@ erts_port_task_schedule(Eterm id,
}
#endif
- ASSERT(!(runq->flags & ERTS_RUNQ_FLG_SUSPENDED));
+ ASSERT(!enq_port || !(runq->flags & ERTS_RUNQ_FLG_SUSPENDED));
ASSERT(pp->sched.taskq);
ASSERT(ptp);
@@ -601,6 +601,15 @@ erts_port_task_schedule(Eterm id,
break;
}
+#ifndef ERTS_SMP
+ /*
+ * When (!enq_port && !pp->sched.exe_taskq) is true in the smp case,
+ * the port might not be in the run queue. If this is the case, another
+ * thread is in the process of enqueueing the port. This very seldom
+ * occur, but do occur and is a valid scenario. Debug info showing this
+ * enqueue in progress must be introduced before we can enable (modified
+ * versions of these) assertions in the smp case again.
+ */
#if defined(HARD_DEBUG)
if (pp->sched.exe_taskq || enq_port)
ERTS_PT_CHK_NOT_IN_PORTQ(runq, pp);
@@ -612,6 +621,7 @@ erts_port_task_schedule(Eterm id,
ASSERT(pp->sched.prev || runq->ports.start == pp);
}
#endif
+#endif
if (!enq_port) {
ERTS_PT_CHK_PRES_PORTQ(runq, pp);
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index b519b39d63..2789691c55 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -2765,7 +2765,7 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all)
p->flags |= F_HAVE_BLCKD_MSCHED;
ASSERT(erts_smp_atomic_read(&schdlr_sspnd.active) == 1);
ASSERT(p->scheduler_data->no == 1);
- res = 1;
+ res = ERTS_SCHDLR_SSPND_DONE_MSCHED_BLOCKED;
}
else {
p->flags |= F_HAVE_BLCKD_MSCHED;
@@ -2896,12 +2896,16 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all)
#endif
p->flags &= ~F_HAVE_BLCKD_MSCHED;
erts_smp_atomic_set(&schdlr_sspnd.msb.ongoing, 0);
- if (schdlr_sspnd.online == 1)
- /* No schedulers to resume */;
+ if (schdlr_sspnd.online == 1) {
+ /* No schedulers to resume */
+ ASSERT(erts_smp_atomic_read(&schdlr_sspnd.active) == 1);
+ schdlr_sspnd.changing = 0;
+ }
else if (erts_common_run_queue) {
for (ix = 1; ix < schdlr_sspnd.online; ix++)
erts_smp_atomic_set(&ERTS_SCHEDULER_IX(ix)->suspended, 0);
wake_all_schedulers();
+ erts_smp_cnd_broadcast(&schdlr_sspnd.cnd);
}
else {
int online = schdlr_sspnd.online;
@@ -2933,8 +2937,8 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all)
erts_smp_runq_unlock(ERTS_RUNQ_IX(0));
erts_smp_mtx_unlock(&balance_info.update_mtx);
erts_smp_mtx_lock(&schdlr_sspnd.mtx);
+ erts_smp_cnd_broadcast(&schdlr_sspnd.cnd);
}
- erts_smp_cnd_broadcast(&schdlr_sspnd.cnd);
res = ERTS_SCHDLR_SSPND_DONE;
}
}
@@ -8033,11 +8037,6 @@ erts_do_exit_process(Process* p, Eterm reason)
if (p->bif_timers)
erts_cancel_bif_timers(p, ERTS_PROC_LOCKS_ALL);
-#ifdef ERTS_SMP
- if (p->flags & F_HAVE_BLCKD_MSCHED)
- erts_block_multi_scheduling(p, ERTS_PROC_LOCKS_ALL, 0, 1);
-#endif
-
erts_smp_proc_unlock(p, ERTS_PROC_LOCKS_ALL_MINOR);
#ifdef ERTS_SMP
@@ -8082,6 +8081,27 @@ continue_exit_process(Process *p
erts_smp_proc_unlock(p, ERTS_PROC_LOCK_STATUS);
#endif
+#ifdef ERTS_SMP
+ if (p->flags & F_HAVE_BLCKD_MSCHED) {
+ ErtsSchedSuspendResult ssr;
+ ssr = erts_block_multi_scheduling(p, ERTS_PROC_LOCK_MAIN, 0, 1);
+ switch (ssr) {
+ case ERTS_SCHDLR_SSPND_YIELD_RESTART:
+ goto yield;
+ case ERTS_SCHDLR_SSPND_DONE_MSCHED_BLOCKED:
+ case ERTS_SCHDLR_SSPND_YIELD_DONE_MSCHED_BLOCKED:
+ case ERTS_SCHDLR_SSPND_DONE:
+ case ERTS_SCHDLR_SSPND_YIELD_DONE:
+ p->flags &= ~F_HAVE_BLCKD_MSCHED;
+ break;
+ case ERTS_SCHDLR_SSPND_EINVAL:
+ default:
+ erl_exit(ERTS_ABORT_EXIT, "%s:%d: Internal error: %d\n",
+ __FILE__, __LINE__, (int) ssr);
+ }
+ }
+#endif
+
if (p->flags & F_USING_DB) {
if (erts_db_process_exiting(p, ERTS_PROC_LOCK_MAIN))
goto yield;
diff --git a/erts/emulator/beam/erl_vm.h b/erts/emulator/beam/erl_vm.h
index 5b0d3c2bfa..50b3e5b61c 100644
--- a/erts/emulator/beam/erl_vm.h
+++ b/erts/emulator/beam/erl_vm.h
@@ -181,6 +181,8 @@ extern int num_instructions; /* Number of instruction in opc[]. */
extern int H_MIN_SIZE; /* minimum (heap + stack) */
extern int BIN_VH_MIN_SIZE; /* minimum virtual (bin) heap */
+extern int erts_atom_table_size;/* Atom table size */
+
#define ORIG_CREATION 0
/* macros for extracting bytes from uint16's */
diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c
index 24887b3dea..b011d4c0de 100644
--- a/erts/emulator/beam/external.c
+++ b/erts/emulator/beam/external.c
@@ -271,11 +271,8 @@ erts_encode_ext_dist_header_size(ErtsAtomCacheMap *acmp)
byte *erts_encode_ext_dist_header_setup(byte *ctl_ext, ErtsAtomCacheMap *acmp)
{
-#ifndef ARCH_32
-#if ATOM_LIMIT >= (1UL << 32)
-#error "ATOM_LIMIT too large for interal atom cache update instructions. New instructions needed."
-#endif
-#endif
+ /* Maximum number of atom must be less than the maximum of a 32 bits
+ unsigned integer. Check is done in erl_init.c, erl_start function. */
if (!acmp)
return ctl_ext;
else {