The switch to kernel terminal context needs to update more than the cursor

position.  Especially the screen size, and potentially everything except
the input state and attributes.  Do this by changing the cursor position
setting method to a general syncing method.

Use proper constructors instead of copying to create kernel terminal
contexts.  We really want clones and not new instances, but there is
no method for cloning and there is nothing in the active instance that
needs to be cloned exactly.

Add proper destructors for kernel terminal contexts.  I doubt that the
destructor code has every been reached, but if it was then it leaked the
memory of the clones.

Remove freeing of statically allocated memory for the non-kernel terminal
context for the same terminal as the kernel.  This is in the nearly
unreachable code.  This used to not happen because delicate context
swapping made the user context use the dynamic memory and kernel
context the static memory.  I didn't restore this swapping since it
would have been unnatural to have all kernel contexts except 1 dynamic.

The constructor for terminal context has bad layering for reasons
related to the bug.  It has to return static memory early before
malloc() works.  Callers also can't allocate memory until after the
first constructor selects an emulator and tells upper layers the size
of its context.  After that, the cloning hack required the cloning
code to allocate the memory, but for all other constructors it would
be better for the terminal layer to allocate and deallocate the
memory in all cases.

Zero the memory when allocating terminal contexts dynamically.
This commit is contained in:
Bruce Evans 2017-03-29 14:46:26 +00:00
parent 8291fb89cf
commit 912da69951
3 changed files with 27 additions and 15 deletions

View File

@ -62,7 +62,7 @@ static sc_term_default_attr_t scteken_default_attr;
static sc_term_clear_t scteken_clear;
static sc_term_input_t scteken_input;
static sc_term_fkeystr_t scteken_fkeystr;
static sc_term_set_cursor_t scteken_set_cursor;
static sc_term_sync_t scteken_sync;
static void scteken_nop(void);
typedef struct {
@ -89,7 +89,7 @@ static sc_term_sw_t sc_term_scteken = {
(sc_term_notify_t *)scteken_nop,
scteken_input,
scteken_fkeystr,
scteken_set_cursor,
scteken_sync,
};
SCTERM_MODULE(scteken, sc_term_scteken);
@ -219,7 +219,7 @@ scteken_clear(scr_stat *scp)
teken_stat *ts = scp->ts;
sc_move_cursor(scp, 0, 0);
scteken_set_cursor(scp, 0, 0);
scteken_sync(scp);
sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20],
scteken_te_to_sc_attr(teken_get_curattr(&ts->ts_teken))
<< 8);
@ -284,13 +284,16 @@ scteken_fkeystr(scr_stat *scp, int c)
}
static void
scteken_set_cursor(scr_stat *scp, int col, int row)
scteken_sync(scr_stat *scp)
{
teken_stat *ts = scp->ts;
teken_pos_t tp;
tp.tp_col = col;
tp.tp_row = row;
tp.tp_col = scp->xsize;
tp.tp_row = scp->ysize;
teken_set_winsize_noreset(&ts->ts_teken, &tp);
tp.tp_col = scp->xpos;
tp.tp_row = scp->ypos;
teken_set_cursor(&ts->ts_teken, &tp);
}

View File

@ -567,8 +567,9 @@ sc_attach_unit(int unit, int flags)
/* assert(sc_console->ts != NULL); */
oldts = sc_console->ts;
for (i = 0; i <= mp_maxid; i++) {
ts = malloc(sc_console->tsw->te_size, M_DEVBUF, M_WAITOK);
bcopy(oldts, ts, sc_console->tsw->te_size);
ts = malloc(sc_console->tsw->te_size, M_DEVBUF,
M_WAITOK | M_ZERO);
(*sc_console->tsw->te_init)(sc_console, &ts, SC_TE_COLD_INIT);
sc_console->ts = ts;
(*sc_console->tsw->te_default_attr)(sc_console, sc_kattrtab[i],
SC_KERNEL_CONS_REV_ATTR);
@ -1705,6 +1706,9 @@ sc_cninit(struct consdev *cp)
static void
sc_cnterm(struct consdev *cp)
{
void *ts;
int i;
/* we are not the kernel console any more, release everything */
if (sc_console_unit < 0)
@ -1715,6 +1719,12 @@ sc_cnterm(struct consdev *cp)
sccnupdate(sc_console);
#endif
for (i = 0; i <= mp_maxid; i++) {
ts = kernel_console_ts[i];
kernel_console_ts[i] = NULL;
(*sc_console->tsw->te_term)(sc_console, &ts);
free(ts, M_DEVBUF);
}
scterm(sc_console_unit, SC_KERNEL_CONSOLE);
sc_console_unit = -1;
sc_console = NULL;
@ -1977,11 +1987,11 @@ sc_cnputc(struct consdev *cd, int c)
ts = kernel_console_ts[PCPU_GET(cpuid)];
if (ts != NULL) {
scp->ts = ts;
(*scp->tsw->te_set_cursor)(scp, scp->xpos, scp->ypos);
(*scp->tsw->te_sync)(scp);
}
sc_puts(scp, buf, 1);
scp->ts = oldts;
(*scp->tsw->te_set_cursor)(scp, scp->xpos, scp->ypos);
(*scp->tsw->te_sync)(scp);
}
s = spltty(); /* block sckbdevent and scrn_timer */
@ -3196,7 +3206,7 @@ scinit(int unit, int flags)
scp->xpos = col;
scp->ypos = row;
scp->cursor_pos = scp->cursor_oldpos = row*scp->xsize + col;
(*scp->tsw->te_set_cursor)(scp, col, row);
(*scp->tsw->te_sync)(scp);
/* Sync BIOS cursor shape to s/w (sc only). */
if (bios_value.cursor_end < scp->font_size)
@ -3312,12 +3322,11 @@ scterm(int unit, int flags)
scp = sc_get_stat(sc->dev[0]);
if (scp->tsw)
(*scp->tsw->te_term)(scp, &scp->ts);
if (scp->ts != NULL)
free(scp->ts, M_DEVBUF);
mtx_destroy(&sc->video_mtx);
/* clear the structure */
if (!(flags & SC_KERNEL_CONSOLE)) {
free(scp->ts, M_DEVBUF);
/* XXX: We need delete_dev() for this */
free(sc->dev, M_DEVBUF);
#if 0

View File

@ -394,7 +394,7 @@ typedef void sc_term_notify_t(scr_stat *scp, int event);
#define SC_TE_NOTIFY_VTSWITCH_OUT 1
typedef int sc_term_input_t(scr_stat *scp, int c, struct tty *tp);
typedef const char *sc_term_fkeystr_t(scr_stat *scp, int c);
typedef void sc_term_set_cursor_t(scr_stat *scp, int col, int row);
typedef void sc_term_sync_t(scr_stat *scp);
typedef struct sc_term_sw {
LIST_ENTRY(sc_term_sw) link;
@ -413,7 +413,7 @@ typedef struct sc_term_sw {
sc_term_notify_t *te_notify;
sc_term_input_t *te_input;
sc_term_fkeystr_t *te_fkeystr;
sc_term_set_cursor_t *te_set_cursor;
sc_term_sync_t *te_sync;
} sc_term_sw_t;
#define SCTERM_MODULE(name, sw) \