diff options
Diffstat (limited to 'erts/emulator/beam/erl_process.h')
| -rw-r--r-- | erts/emulator/beam/erl_process.h | 162 | 
1 files changed, 110 insertions, 52 deletions
| diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index cbcdec4ba7..d927415f37 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -174,8 +174,8 @@ extern int erts_sched_thread_suggested_stack_size;  #define ERTS_UNSET_RUNQ_FLG_EVACUATE(FLGS, PRIO) \    ((FLGS) &= ~ERTS_RUNQ_FLG_EVACUATE((PRIO))) -#define ERTS_RUNQ_IFLG_SUSPENDED		(((long) 1) << 0) -#define ERTS_RUNQ_IFLG_NONEMPTY			(((long) 1) << 1) +#define ERTS_RUNQ_IFLG_SUSPENDED		(((erts_aint32_t) 1) << 0) +#define ERTS_RUNQ_IFLG_NONEMPTY			(((erts_aint32_t) 1) << 1)  #ifdef DEBUG @@ -219,6 +219,49 @@ typedef enum {      ERTS_MIGRATE_FAILED_RUNQ_SUSPENDED  } ErtsMigrateResult; +#define ERTS_SSI_FLG_SLEEPING		(((erts_aint32_t) 1) << 0) +#define ERTS_SSI_FLG_POLL_SLEEPING 	(((erts_aint32_t) 1) << 1) +#define ERTS_SSI_FLG_TSE_SLEEPING 	(((erts_aint32_t) 1) << 2) +#define ERTS_SSI_FLG_WAITING		(((erts_aint32_t) 1) << 3) +#define ERTS_SSI_FLG_SUSPENDED	 	(((erts_aint32_t) 1) << 4) + +#define ERTS_SSI_FLGS_SLEEP_TYPE			\ + (ERTS_SSI_FLG_TSE_SLEEPING|ERTS_SSI_FLG_POLL_SLEEPING) + +#define ERTS_SSI_FLGS_SLEEP				\ + (ERTS_SSI_FLG_SLEEPING|ERTS_SSI_FLGS_SLEEP_TYPE) + +#define ERTS_SSI_FLGS_ALL				\ + (ERTS_SSI_FLGS_SLEEP					\ +  | ERTS_SSI_FLG_WAITING				\ +  | ERTS_SSI_FLG_SUSPENDED) + +#define ERTS_SCHED_NEED_BLOCKABLE_AUX_WORK + +#define ERTS_SSI_AUX_WORK_CHECK_CHILDREN	(((erts_aint32_t) 1) << 0) +#define ERTS_SSI_AUX_WORK_MISC			(((erts_aint32_t) 1) << 1) + +#define ERTS_SSI_BLOCKABLE_AUX_WORK_MASK \ +  (ERTS_SSI_AUX_WORK_CHECK_CHILDREN \ +   | ERTS_SSI_AUX_WORK_MISC) +#define ERTS_SSI_NONBLOCKABLE_AUX_WORK_MASK \ +  (0) + +typedef struct ErtsSchedulerSleepInfo_ ErtsSchedulerSleepInfo; + +typedef struct { +    erts_smp_spinlock_t lock; +    ErtsSchedulerSleepInfo *list; +} ErtsSchedulerSleepList; + +struct ErtsSchedulerSleepInfo_ { +    ErtsSchedulerSleepInfo *next; +    ErtsSchedulerSleepInfo *prev; +    erts_smp_atomic32_t flags; +    erts_tse_t *event; +    erts_smp_atomic32_t aux_work; +}; +  /* times to reschedule low prio process before running */  #define RESCHEDULE_LOW        8 @@ -266,13 +309,14 @@ typedef struct {  struct ErtsRunQueue_ {      int ix; -    erts_smp_atomic_t info_flags; +    erts_smp_atomic32_t info_flags;      erts_smp_mtx_t mtx;      erts_smp_cnd_t cnd; -    erts_smp_atomic_t spin_waiter; -    erts_smp_atomic_t spin_wake; +#ifdef ERTS_SMP +    ErtsSchedulerSleepList sleepers; +#endif      ErtsSchedulerData *scheduler;      int waiting; /* < 0 in sys schedule; > 0 on cnd variable */ @@ -353,6 +397,7 @@ struct ErtsSchedulerData_ {      ethr_tid tid;		/* Thread id */      struct erl_bits_state erl_bits_state; /* erl_bits.c state */      void *match_pseudo_process; /* erl_db_util.c:db_prog_match() */ +    ErtsSchedulerSleepInfo *ssi;      Process *free_process;  #endif  #if !HEAP_ON_C_STACK @@ -374,15 +419,17 @@ struct ErtsSchedulerData_ {  #ifdef ERTS_SMP      /* NOTE: These fields are modified under held mutexes by other threads */ -#ifdef ERTS_SMP_SCHEDULERS_NEED_TO_CHECK_CHILDREN -    int check_children; /* run queue mutex */ -    int blocked_check_children; /* schdlr_sspnd mutex */ -#endif -    erts_smp_atomic_t suspended; /* Only used when common run queue */ -    erts_smp_atomic_t chk_cpu_bind; /* Only used when common run queue */ +    erts_smp_atomic32_t chk_cpu_bind; /* Only used when common run queue */  #endif  }; +typedef union { +    ErtsSchedulerData esd; +    char align[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(ErtsSchedulerData))]; +} ErtsAlignedSchedulerData; + +extern ErtsAlignedSchedulerData *erts_aligned_scheduler_data; +  #ifndef ERTS_SMP  extern ErtsSchedulerData *erts_scheduler_data;  #endif @@ -397,8 +444,9 @@ extern ErtsSchedulerData *erts_scheduler_data;  #define ERTS_PSD_SAVED_CALLS_BUF		1  #define ERTS_PSD_SCHED_ID			2  #define ERTS_PSD_DIST_ENTRY			3 +#define ERTS_PSD_CALL_TIME_BP			4 -#define ERTS_PSD_SIZE				4 +#define ERTS_PSD_SIZE				5  typedef struct {      void *data[ERTS_PSD_SIZE]; @@ -419,6 +467,9 @@ typedef struct {  #define ERTS_PSD_DIST_ENTRY_GET_LOCKS ERTS_PROC_LOCK_MAIN  #define ERTS_PSD_DIST_ENTRY_SET_LOCKS ERTS_PROC_LOCK_MAIN +#define ERTS_PSD_CALL_TIME_BP_GET_LOCKS ERTS_PROC_LOCK_MAIN +#define ERTS_PSD_CALL_TIME_BP_SET_LOCKS ERTS_PROC_LOCK_MAIN +  typedef struct {      ErtsProcLocks get_locks;      ErtsProcLocks set_locks; @@ -490,6 +541,7 @@ struct ErtsPendingSuspend_ {  #  define MIN_VHEAP_SIZE(p)   (p)->min_vheap_size  #  define BIN_VHEAP_SZ(p)     (p)->bin_vheap_sz +#  define BIN_VHEAP_MATURE(p) (p)->bin_vheap_mature  #  define BIN_OLD_VHEAP_SZ(p) (p)->bin_old_vheap_sz  #  define BIN_OLD_VHEAP(p)    (p)->bin_old_vheap @@ -607,9 +659,10 @@ struct process {      Uint mbuf_sz;		/* Size of all message buffers */      ErtsPSD *psd;		/* Rarely used process specific data */ -    Uint bin_vheap_sz;		/* Virtual heap block size for binaries */ -    Uint bin_old_vheap_sz;	/* Virtual old heap block size for binaries */ -    Uint bin_old_vheap;		/* Virtual old heap size for binaries */ +    Uint64 bin_vheap_sz;	/* Virtual heap block size for binaries */ +    Uint64 bin_vheap_mature;	/* Virtual heap block size for binaries */ +    Uint64 bin_old_vheap_sz;	/* Virtual old heap block size for binaries */ +    Uint64 bin_old_vheap;	/* Virtual old heap size for binaries */      union {  #ifdef ERTS_SMP @@ -765,7 +818,7 @@ ERTS_GLB_INLINE void erts_heap_frag_shrink(Process* p, Eterm* hp)  {      ErlHeapFragment* hf = MBUF(p); -    ASSERT(hf!=NULL && (hp - hf->mem < (unsigned long)hf->size)); +    ASSERT(hf!=NULL && (hp - hf->mem < (unsigned long)hf->alloc_size));      hf->used_size = hp - hf->mem;  }	 @@ -824,7 +877,7 @@ extern struct erts_system_profile_flags_t erts_system_profile_flags;  #define F_INSLPQUEUE         (1 <<  1) /* Set if in timer queue */  #define F_TIMO               (1 <<  2) /* Set if timeout */  #define F_HEAP_GROW          (1 <<  3) -#define F_NEED_FULLSWEEP     (1 <<  4) /* If process has old binaries & funs. */ +#define F_NEED_FULLSWEEP     (1 <<  4)  #define F_USING_DB           (1 <<  5) /* If have created tables */  #define F_DISTRIBUTION       (1 <<  6) /* Process used in distribution */  #define F_USING_DDLL         (1 <<  7) /* Process has used the DDLL interface */ @@ -958,26 +1011,12 @@ extern struct erts_system_profile_flags_t erts_system_profile_flags;  	    (p)->flags &= ~F_TIMO; \      } while (0) - -#define ERTS_INIT_SCHED_BIND_TYPE_SUCCESS		0 -#define ERTS_INIT_SCHED_BIND_TYPE_NOT_SUPPORTED		1 -#define ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_CPU_TOPOLOGY	2 -#define ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_BAD_TYPE	3 - -int erts_init_scheduler_bind_type(char *how); - -#define ERTS_INIT_CPU_TOPOLOGY_OK			0 -#define ERTS_INIT_CPU_TOPOLOGY_INVALID_ID		1 -#define ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_RANGE		2 -#define ERTS_INIT_CPU_TOPOLOGY_INVALID_HIERARCHY	3 -#define ERTS_INIT_CPU_TOPOLOGY_INVALID_ID_TYPE		4 -#define ERTS_INIT_CPU_TOPOLOGY_INVALID_NODES		5 -#define ERTS_INIT_CPU_TOPOLOGY_MISSING_LID		6 -#define ERTS_INIT_CPU_TOPOLOGY_NOT_UNIQUE_LIDS		7 -#define ERTS_INIT_CPU_TOPOLOGY_NOT_UNIQUE_ENTITIES	8 -#define ERTS_INIT_CPU_TOPOLOGY_MISSING			9 - -int erts_init_cpu_topology(char *topology_str); +#define ERTS_RUNQ_IX(IX)						\ +  (ASSERT_EXPR(0 <= (IX) && (IX) < erts_no_run_queues),			\ +   &erts_aligned_run_queues[(IX)].runq) +#define ERTS_SCHEDULER_IX(IX)						\ +  (ASSERT_EXPR(0 <= (IX) && (IX) < erts_no_schedulers),			\ +   &erts_aligned_scheduler_data[(IX)].esd)  void erts_pre_init_process(void);  void erts_late_init_process(void); @@ -988,9 +1027,12 @@ ErtsProcList *erts_proclist_create(Process *);  void erts_proclist_destroy(ErtsProcList *);  int erts_proclist_same(ErtsProcList *, Process *); +int erts_sched_set_wakeup_limit(char *str); +  #ifdef DEBUG  void erts_dbg_multi_scheduling_return_trap(Process *, Eterm);  #endif +int erts_get_max_no_executing_schedulers(void);  #ifdef ERTS_SMP  ErtsSchedSuspendResult  erts_schedulers_state(Uint *, Uint *, Uint *, int); @@ -1005,9 +1047,15 @@ int erts_is_multi_scheduling_blocked(void);  Eterm erts_multi_scheduling_blockers(Process *);  void erts_start_schedulers(void);  void erts_smp_notify_check_children_needed(void); +void +erts_smp_schedule_misc_aux_work(int ignore_self, +				int max_sched, +				void (*func)(void *), +				void *arg);  #endif +void erts_sched_notify_check_cpu_bind(void);  Uint erts_active_schedulers(void); -void erts_init_process(void); +void erts_init_process(int);  Eterm erts_process_status(Process *, ErtsProcLocks, Process *, Eterm);  Uint erts_run_queues_len(Uint *);  void erts_add_to_runq(Process *); @@ -1081,6 +1129,9 @@ void erts_handle_pending_exit(Process *, ErtsProcLocks);  void erts_deep_process_dump(int, void *); +Eterm erts_get_reader_groups_map(Process *c_p); +Eterm erts_debug_reader_groups_map(Process *c_p, int groups); +  Sint erts_test_next_pid(int, Uint);  Eterm erts_debug_processes(Process *c_p);  Eterm erts_debug_processes_bif_info(Process *c_p); @@ -1208,6 +1259,12 @@ erts_psd_set(Process *p, ErtsProcLocks plocks, int ix, void *data)  #define ERTS_PROC_SET_SAVED_CALLS_BUF(P, L, SCB) \    ((struct saved_calls *) erts_psd_set((P), (L), ERTS_PSD_SAVED_CALLS_BUF, (void *) (SCB))) +#define ERTS_PROC_GET_CALL_TIME(P) \ +  ((process_breakpoint_time_t *) erts_psd_get((P), ERTS_PSD_CALL_TIME_BP)) +#define ERTS_PROC_SET_CALL_TIME(P, L, PBT) \ +  ((process_breakpoint_time_t *) erts_psd_set((P), (L), ERTS_PSD_CALL_TIME_BP, (void *) (PBT))) + +  ERTS_GLB_INLINE Eterm erts_proc_get_error_handler(Process *p);  ERTS_GLB_INLINE Eterm erts_proc_set_error_handler(Process *p,  						  ErtsProcLocks plocks, @@ -1499,29 +1556,30 @@ extern int erts_disable_proc_not_running_opt;  #define ERTS_MIN_PROCESSES		16  #endif -#ifdef ERTS_INCLUDE_SCHEDULER_INTERNALS -ERTS_GLB_INLINE void erts_smp_notify_inc_runq(ErtsRunQueue *runq); -void erts_smp_notify_inc_runq__(ErtsRunQueue *runq); -#endif /* ERTS_INCLUDE_SCHEDULER_INTERNALS */ +void erts_smp_notify_inc_runq(ErtsRunQueue *runq); -#if ERTS_GLB_INLINE_INCL_FUNC_DEF +#ifdef ERTS_SMP +void erts_sched_finish_poke(ErtsSchedulerSleepInfo *, erts_aint32_t); +ERTS_GLB_INLINE void erts_sched_poke(ErtsSchedulerSleepInfo *ssi); -#ifdef ERTS_INCLUDE_SCHEDULER_INTERNALS +#if ERTS_GLB_INLINE_INCL_FUNC_DEF  ERTS_GLB_INLINE void -erts_smp_notify_inc_runq(ErtsRunQueue *runq) +erts_sched_poke(ErtsSchedulerSleepInfo *ssi)  { -#ifdef ERTS_SMP -    ERTS_SMP_LC_ASSERT(erts_smp_lc_runq_is_locked(runq)); -    if (runq->waiting) -	erts_smp_notify_inc_runq__(runq); -#endif +    erts_aint32_t flags = erts_smp_atomic32_read(&ssi->flags); +    ASSERT(!(flags & ERTS_SSI_FLG_SLEEPING) +	   || (flags & ERTS_SSI_FLG_WAITING)); +    if (flags & ERTS_SSI_FLG_SLEEPING) { +	flags = erts_smp_atomic32_band(&ssi->flags, ~ERTS_SSI_FLGS_SLEEP); +	erts_sched_finish_poke(ssi, flags); +    }  } -#endif /* ERTS_INCLUDE_SCHEDULER_INTERNALS */ -  #endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */ +#endif /* #ifdef ERTS_SMP */ +  #include "erl_process_lock.h"  #undef ERTS_INCLUDE_SCHEDULER_INTERNALS | 
