Skip to content

Commit

Permalink
Merge branch 'vinoski/enif-schedule-nif' into maint
Browse files Browse the repository at this point in the history
OTP-12128

* vinoski/enif-schedule-nif:
  Fix leak of NIF exports
  Use separate allocation type for NIF export
  • Loading branch information
rickard-green committed Sep 5, 2014
2 parents fbd740b + 18a38b9 commit b3a7e7f
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 6 deletions.
2 changes: 2 additions & 0 deletions erts/emulator/beam/erl_alloc.types
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ type DB_MS_PSDO_PROC LONG_LIVED_LOW ETS db_match_pseudo_proc
type SCHDLR_DATA LONG_LIVED_LOW SYSTEM scheduler_data
type LL_TEMP_TERM LONG_LIVED_LOW SYSTEM ll_temp_term

type NIF_TRAP_EXPORT STANDARD_LOW CODE nif_trap_export_entry
type EXPORT LONG_LIVED_LOW CODE export_entry
type MONITOR_SH STANDARD_LOW PROCESSES monitor_sh
type NLINK_SH STANDARD_LOW PROCESSES nlink_sh
Expand All @@ -375,6 +376,7 @@ type DB_MS_PSDO_PROC LONG_LIVED ETS db_match_pseudo_proc
type SCHDLR_DATA LONG_LIVED SYSTEM scheduler_data
type LL_TEMP_TERM LONG_LIVED SYSTEM ll_temp_term

type NIF_TRAP_EXPORT STANDARD CODE nif_trap_export_entry
type EXPORT LONG_LIVED CODE export_entry
type MONITOR_SH FIXED_SIZE PROCESSES monitor_sh
type NLINK_SH FIXED_SIZE PROCESSES nlink_sh
Expand Down
18 changes: 15 additions & 3 deletions erts/emulator/beam/erl_nif.c
Original file line number Diff line number Diff line change
Expand Up @@ -1578,17 +1578,29 @@ allocate_nif_sched_data(Process* proc, int argc)

argv_extra = argc > 1 ? sizeof(Eterm)*(argc-1) : 0;
total = sizeof(NifExport) + argv_extra;
ep = erts_alloc(ERTS_ALC_T_PSD, total);
ep = erts_alloc(ERTS_ALC_T_NIF_TRAP_EXPORT, total);
sys_memset((void*) ep, 0, total);
ep->alloced_argv_sz = argc;
for (i=0; i<ERTS_NUM_CODE_IX; i++) {
ep->exp.addressv[i] = &ep->exp.code[3];
}
ep->exp.code[3] = (BeamInstr) em_call_nif;
(void) ERTS_PROC_SET_NIF_TRAP_EXPORT(proc, ERTS_PROC_LOCK_MAIN, &ep->exp);
(void) ERTS_PROC_SET_NIF_TRAP_EXPORT(proc, ERTS_PROC_LOCK_MAIN, ep);
return ep;
}

static ERTS_INLINE void
destroy_nif_export(NifExport *nif_export)
{
erts_free(ERTS_ALC_T_NIF_TRAP_EXPORT, (void *) nif_export);
}

void
erts_destroy_nif_export(void *nif_export)
{
destroy_nif_export((NifExport *) nif_export);
}

/*
* Initialize a NifExport struct. Create it if needed and store it in the
* proc. The direct_fp function is what will be invoked by op_call_nif, and
Expand All @@ -1611,7 +1623,7 @@ init_nif_sched_data(ErlNifEnv* env, NativeFunPtr direct_fp, NativeFunPtr indirec
ep = allocate_nif_sched_data(proc, argc);
else if (need_save && ep->alloced_argv_sz < argc) {
NifExport* new_ep = allocate_nif_sched_data(proc, argc);
erts_free(ERTS_ALC_T_PSD, (void*) ep);
destroy_nif_export(ep);
ep = new_ep;
}
ERTS_VBUMP_ALL_REDS(proc);
Expand Down
5 changes: 5 additions & 0 deletions erts/emulator/beam/erl_process.c
Original file line number Diff line number Diff line change
Expand Up @@ -11872,6 +11872,7 @@ erts_continue_exit_process(Process *p)
struct saved_calls *scb;
process_breakpoint_time_t *pbt;
erts_aint32_t state;
void *nif_export;

#ifdef DEBUG
int yield_allowed = 1;
Expand Down Expand Up @@ -12022,6 +12023,7 @@ erts_continue_exit_process(Process *p)
: NULL);
scb = ERTS_PROC_SET_SAVED_CALLS_BUF(p, ERTS_PROC_LOCKS_ALL, NULL);
pbt = ERTS_PROC_SET_CALL_TIME(p, ERTS_PROC_LOCKS_ALL, NULL);
nif_export = ERTS_PROC_SET_NIF_TRAP_EXPORT(p, ERTS_PROC_LOCKS_ALL, NULL);

erts_smp_proc_unlock(p, ERTS_PROC_LOCKS_ALL);
#ifdef BM_COUNTERS
Expand Down Expand Up @@ -12069,6 +12071,9 @@ erts_continue_exit_process(Process *p)
if (pbt)
erts_free(ERTS_ALC_T_BPD, (void *) pbt);

if (nif_export)
erts_destroy_nif_export(nif_export);

delete_process(p);

#ifdef ERTS_SMP
Expand Down
7 changes: 4 additions & 3 deletions erts/emulator/beam/erl_process.h
Original file line number Diff line number Diff line change
Expand Up @@ -1362,6 +1362,7 @@ Uint64 erts_ensure_later_proc_interval(Uint64);
Uint64 erts_step_proc_interval(void);

int erts_setup_nif_gc(Process* proc, Eterm** objv, int* nobj); /* see erl_nif.c */
void erts_destroy_nif_export(void *); /* see erl_nif.c */

ErtsProcList *erts_proclist_create(Process *);
void erts_proclist_destroy(ErtsProcList *);
Expand Down Expand Up @@ -1814,9 +1815,9 @@ erts_psd_set(Process *p, ErtsProcLocks plocks, int ix, void *data)
((ErtsProcSysTaskQs *) erts_psd_set((P), (L), ERTS_PSD_DELAYED_GC_TASK_QS, (void *) (PBT)))

#define ERTS_PROC_GET_NIF_TRAP_EXPORT(P) \
((Export *) erts_psd_get((P), ERTS_PSD_NIF_TRAP_EXPORT))
#define ERTS_PROC_SET_NIF_TRAP_EXPORT(P, L, DSTE) \
((Export *) erts_psd_set((P), (L), ERTS_PSD_NIF_TRAP_EXPORT, (void *) (DSTE)))
erts_psd_get((P), ERTS_PSD_NIF_TRAP_EXPORT)
#define ERTS_PROC_SET_NIF_TRAP_EXPORT(P, L, NTE) \
erts_psd_set((P), (L), ERTS_PSD_NIF_TRAP_EXPORT, (void *) (NTE))


ERTS_GLB_INLINE Eterm erts_proc_get_error_handler(Process *p);
Expand Down

0 comments on commit b3a7e7f

Please sign in to comment.