📄 global.h
字号:
/* ``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 via the world wide web 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. * * The Initial Developer of the Original Code is Ericsson Utvecklings AB. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings * AB. All Rights Reserved.'' * * $Id$ */#ifndef __GLOBAL_H__#define __GLOBAL_H__#include "sys.h"#include "erl_alloc.h"#include "erl_vm.h"#include "erl_node_container_utils.h"#include "hash.h"#include "index.h"#include "atom.h"#include "export.h"#include "module.h"#include "register.h"#include "erl_fun.h"#include "erl_node_tables.h"#include "benchmark.h"#include "erl_process.h"#include "erl_sys_driver.h"#include "erl_debug.h"typedef struct port Port;#include "erl_port_task.h"#define ERTS_MAX_NO_OF_ASYNC_THREADS 1024extern int erts_async_max_threads;#define ERTS_ASYNC_THREAD_MIN_STACK_SIZE 16 /* Kilo words */#define ERTS_ASYNC_THREAD_MAX_STACK_SIZE 8192 /* Kilo words */extern int erts_async_thread_suggested_stack_size;#define MAXINDX 255typedef struct cache { Eterm in_arr[MAXINDX]; Eterm out_arr[MAXINDX];} ErlCache;#define SMALL_IO_QUEUE 5 /* Number of fixed elements */typedef struct { int size; /* total size in bytes */ SysIOVec* v_start; SysIOVec* v_end; SysIOVec* v_head; SysIOVec* v_tail; SysIOVec v_small[SMALL_IO_QUEUE]; ErlDrvBinary** b_start; ErlDrvBinary** b_end; ErlDrvBinary** b_head; ErlDrvBinary** b_tail; ErlDrvBinary* b_small[SMALL_IO_QUEUE];} ErlIOQueue;typedef struct line_buf { /* Buffer used in line oriented I/O */ int bufsiz; /* Size of character buffer */ int ovlen; /* Length of overflow data */ int ovsiz; /* Actual size of overflow buffer */ char data[1]; /* Starting point of buffer data, data[0] is a flag indicating an unprocess CR, The rest is the overflow buffer. */} LineBuf;#ifdef ERTS_SMPtypedef struct ErtsXPortsList_ ErtsXPortsList;#endif/* * Port locking: * * Locking is done either driver specific or port specific. When * driver specific locking is used, all instances of the driver, * i.e. ports running the driver, share the same lock. When port * specific locking is used each instance have its own lock. * * Most fields in the Port structure are protected by the lock * referred to by the lock filed. I'v called it the port lock. * This lock is shared between all ports running the same driver * when driver specific locking is used. * * The 'sched' field is protected by the port tasks lock * (see erl_port_tasks.c) * * The 'status' field is protected by a combination of the port lock, * the port tasks lock, and the port table lock. It may be read if * the port table lock, or the port lock is held. It may only be * modified if both the port lock and the port table lock is held * (with one exception; see below). When changeing status from alive * to dead or vice versa, also the port task lock has to be held. * This in order to guarantee that tasks are scheduled only for * ports that are alive. * * The status field may be modified with only the port table lock * held when status is changed from dead to alive. This since no * threads can have any references to the port other than via the * port table. * * /rickard */struct port {#ifdef ERTS_USE_PORT_TASKS ErtsPortTaskSched sched; ErtsPortTaskHandle timeout_task;#endif#ifdef ERTS_SMP erts_smp_atomic_t refc; erts_smp_mtx_t *lock; ErtsXPortsList *xports;#endif Eterm id; /* The Port id of this port */ Eterm connected; /* A connected process */ Eterm caller; /* Current caller. */ Eterm data; /* Data associated with port. */ ErlHeapFragment* bp; /* Heap fragment holding data (NULL if imm data). */ ErtsLink *nlinks; ErtsMonitor *monitors; /* Only MON_ORIGIN monitors of pid's */ Uint bytes_in; /* Number of bytes read */ Uint bytes_out; /* Number of bytes written */#ifdef ERTS_SMP ErtsSmpPTimer *ptimer;#else ErlTimer tm; /* Timer entry */#endif ErlIOQueue ioq; /* driver accessible i/o queue */ DistEntry *dist_entry; /* Dist entry used in DISTRIBUTION */ char *name; /* String used in the open */ ErlDrvEntry* drv_ptr; long drv_data; ProcessList *suspended; /* List of suspended processes. */ LineBuf *linebuf; /* Buffer to hold data not ready for process to get (line oriented I/O)*/ Uint32 status; /* Status and type flags */ int control_flags; /* Flags for port_control() */ struct reg_proc *reg; ErlDrvPDL port_data_lock;};/* Driver handle (wrapper for old plain handle) */#define ERL_DE_OK 0#define ERL_DE_UNLOAD 1#define ERL_DE_FORCE_UNLOAD 2 #define ERL_DE_RELOAD 3#define ERL_DE_FORCE_RELOAD 4#define ERL_DE_PERMANENT 5#define ERL_DE_PROC_LOADED 0#define ERL_DE_PROC_AWAIT_UNLOAD 1#define ERL_DE_PROC_AWAIT_UNLOAD_ONLY 2#define ERL_DE_PROC_AWAIT_LOAD 3/* Flags for process entries */#define ERL_DE_FL_DEREFERENCED 1/* Flags for drivers, put locking policy here /PaN */#define ERL_DE_FL_KILL_PORTS 1#define ERL_FL_CONSISTENT_MASK ( ERL_DE_FL_KILL_PORTS )/* System specific load errors are returned as positive values */#define ERL_DE_NO_ERROR 0#define ERL_DE_LOAD_ERROR_NO_INIT -1#define ERL_DE_LOAD_ERROR_FAILED_INIT -2#define ERL_DE_LOAD_ERROR_BAD_NAME -3#define ERL_DE_LOAD_ERROR_NAME_TO_LONG -4#define ERL_DE_LOAD_ERROR_INCORRECT_VERSION -5#define ERL_DE_ERROR_NO_DDLL_FUNCTIONALITY -6#define ERL_DE_ERROR_UNSPECIFIED -7#define ERL_DE_LOOKUP_ERROR_NOT_FOUND -8#define ERL_DE_DYNAMIC_ERROR_OFFSET -10typedef struct de_proc_entry { Process *proc; /* The process... */ Uint awaiting_status; /* PROC_LOADED == Have loaded the driver PROC_AWAIT_UNLOAD == Wants to be notified when we have unloaded the driver (was locked) PROC_AWAIT_LOAD == Wants to be notified when we reloaded the driver (old was locked) */ Uint flags; /* ERL_FL_DE_DEREFERENCED when reload in progress */ Eterm heap[REF_THING_SIZE]; /* "ref heap" */ struct de_proc_entry *next;} DE_ProcEntry;typedef struct { void *handle; /* Handle for DLL or SO (for dyn. drivers). */ DE_ProcEntry *procs; /* List of pids that have loaded this driver, or that wait for it to change state */ erts_refc_t refc; /* Number of ports/processes having references to the driver */ Uint port_count; /* Number of ports using the driver */ Uint flags; /* ERL_DE_FL_KILL_PORTS */ int status; /* ERL_DE_xxx */ char *full_path; /* Full path of the driver */ char *reload_full_path; /* If status == ERL_DE_RELOAD, this contains full name of driver (path) */ char *reload_driver_name; /* ... and this contains the driver name */ Uint reload_flags; /* flags for reloaded driver */} DE_Handle;/* * This structure represents a link to the next driver. */typedef struct de_list { ErlDrvEntry *drv; /* Pointer to entry for driver. */ DE_Handle *de_hndl; /* Handle for DLL or SO (for dynamic drivers). */ struct de_list *next; /* Pointer to next. */ struct de_list *prev; /* Pointer to previous */#ifdef ERTS_SMP erts_smp_mtx_t *driver_lock;#endif} DE_List;extern DE_List *driver_list;extern erts_smp_mtx_t erts_driver_list_lock;extern void erts_ddll_init(void);extern void erts_ddll_lock_driver(DE_Handle *dh, char *name);/* These are for bookkeeping */extern void erts_ddll_increment_port_count(DE_Handle *dh);extern void erts_ddll_decrement_port_count(DE_Handle *dh);/* These makes things happen, drivers may be scheduled for unload etc */extern void erts_ddll_reference_driver(DE_Handle *dh);extern void erts_ddll_reference_referenced_driver(DE_Handle *dh);extern void erts_ddll_dereference_driver(DE_Handle *dh);extern char *erts_ddll_error(int code);extern void erts_ddll_proc_dead(Process *p, Uint32 plocks);extern int erts_ddll_driver_ok(DE_Handle *dh);extern void erts_ddll_remove_monitor(Process *p, Eterm ref, Uint32 plocks);extern Eterm erts_ddll_monitor_driver(Process *p, Eterm description, Uint32 plocks);/* * Max no. of drivers (linked in and dynamically loaded). Each table * entry uses 4 bytes. */#define DRIVER_TAB_SIZE 32/*** Just like the driver binary but with initial flags** Note that the two structures Binary and ErlDrvBinary HAVE to** be equal except for extra fields in the beginning of the struct.** ErlDrvBinary is defined in erl_driver.h.** When driver_alloc_binary is called, a Binary is allocated, but ** the pointer returned is to the address of the first element that** also occurs in the ErlDrvBinary struct (driver.*binary takes care if this).** The driver need never know about additions to the internal Binary of the** emulator. One should however NEVER be sloppy when mixing ErlDrvBinary** and Binary, the macros below can convert one type to the other, as they both** in reality are equal.*/typedef struct binary { Uint flags; erts_refc_t refc;#ifdef ARCH_32 Uint32 align__; /* *DO NOT USE* only for alignment. */#endif /* Add fields BEFORE this, otherwise the drivers crash */ long orig_size; char orig_bytes[1]; /* to be continued */} Binary;/* * 'Binary' alignment: * Address of orig_bytes[0] of a Binary should always be 8-byte aligned. * It is assumed that the flags, refc, and orig_size fields are 4 bytes on * 32-bits architectures and 8 bytes on 64-bits architectures. */#define Binary2ErlDrvBinary(B) ((ErlDrvBinary *) (&((B)->orig_size)))#define ErlDrvBinary2Binary(D) ((Binary *) \ (((char *) (D)) - \ ((char *) &(((Binary *) 0)->orig_size))))/* A "magic" binary flag */#define BIN_FLAG_MATCH_PROG 1#define BIN_FLAG_USR1 2 /* Reserved for use by different modules too mark */#define BIN_FLAG_USR2 4 /* certain binaries as special (used by ets) */#define BIN_FLAG_DRV 8/* * This structure represents one type of a binary in a process. */typedef struct proc_bin { Eterm thing_word; /* Subtag REFC_BINARY_SUBTAG. */ Uint size; /* Binary size in bytes. */ struct proc_bin *next; /* Pointer to next ProcBin. */ Binary *val; /* Pointer to Binary structure. */ byte *bytes; /* Pointer to the actual data bytes. */} ProcBin;/* * ProcBin size in Eterm words. */#define PROC_BIN_SIZE (sizeof(ProcBin)/sizeof(Eterm))/* arrays that get malloced at startup */extern Port* erts_port;extern long erts_ports_alive;extern Uint erts_max_ports;extern Uint erts_port_tab_index_mask;/* controls warning mapping in error_logger */extern Eterm node_cookie;extern erts_smp_atomic_t erts_bytes_out; /* no bytes written out */extern erts_smp_atomic_t erts_bytes_in; /* no bytes sent into the system */extern Uint display_items; /* no of items to display in traces etc */extern Uint display_loads; /* print info about loaded modules */extern int erts_backtrace_depth;extern erts_smp_atomic_t erts_max_gen_gcs;extern int erts_disable_tolerant_timeofday;/* Defines to ease the change of memory architecture */# define HEAP_START(p) (p)->heap# define HEAP_TOP(p) (p)->htop# define HEAP_LIMIT(p) (p)->stop# define HEAP_END(p) (p)->hend# define HEAP_SIZE(p) (p)->heap_sz# define STACK_START(p) (p)->hend# define STACK_TOP(p) (p)->stop# define STACK_END(p) (p)->htop# define HIGH_WATER(p) (p)->high_water# define OLD_HEND(p) (p)->old_hend# define OLD_HTOP(p) (p)->old_htop# define OLD_HEAP(p) (p)->old_heap# define GEN_GCS(p) (p)->gen_gcs# define MAX_GEN_GCS(p) (p)->max_gen_gcs# define FLAGS(p) (p)->flags# define MBUF(p) (p)->mbuf# define HALLOC_MBUF(p) (p)->halloc_mbuf# define MBUF_SIZE(p) (p)->mbuf_sz# define MSO(p) (p)->off_heap# define MIN_HEAP_SIZE(p) (p)->min_heap_size#ifdef HYBRID/* Message Area heap pointers */extern Eterm *global_heap; /* Heap start */extern Eterm *global_hend; /* Heap end */extern Eterm *global_htop; /* Heap top (heap pointer) */extern Eterm *global_saved_htop; /* Saved heap top (heap pointer) */extern Uint global_heap_sz; /* Heap size, in words */extern Eterm *global_old_heap; /* Old generation */extern Eterm *global_old_hend;extern ErlOffHeap erts_global_offheap; /* Global MSO (OffHeap) list */extern Uint16 global_gen_gcs;extern Uint16 global_max_gen_gcs;extern Uint global_gc_flags;#ifdef INCREMENTAL#define ACTIVATE(p)#define DEACTIVATE(p)#define IS_ACTIVE(p) 1#define INC_ACTIVATE(p) do { \ if ((p)->active) { \ if ((p)->active_next != NULL) { \ (p)->active_next->active_prev = (p)->active_prev; \ if ((p)->active_prev) { \ (p)->active_prev->active_next = (p)->active_next; \ } else { \ inc_active_proc = (p)->active_next; \ } \ inc_active_last->active_next = (p); \ (p)->active_next = NULL; \ (p)->active_prev = inc_active_last; \ inc_active_last = (p); \ } \ } else { \ (p)->active_next = NULL; \ (p)->active_prev = inc_active_last; \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -