diff options
Diffstat (limited to 'erts/emulator/beam/erl_lock_count.h')
-rw-r--r-- | erts/emulator/beam/erl_lock_count.h | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/erts/emulator/beam/erl_lock_count.h b/erts/emulator/beam/erl_lock_count.h new file mode 100644 index 0000000000..8564c36203 --- /dev/null +++ b/erts/emulator/beam/erl_lock_count.h @@ -0,0 +1,195 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2008-2009. 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% + */ + +/* + * Description: Statistics for locks. + * + * Author: Bj�rn-Egil Dahlberg + * Date: 2008-07-03 + * Abstract: + * Locks statistics internal representation. + * + * Conceptual representation, + * - set name + * | - id (the unique lock) + * | | - lock type + * | | - statistics + * | | | - location (file and line number) + * | | | - tries + * | | | - collisions (including trylock busy) + * | | | - timer (time spent in waiting for lock) + * | | | - n_timer (collisions excluding trylock busy) + * + * Each instance of a lock is the unique lock, i.e. set and id in that set. + * For each lock there is a set of statistics with where and what impact + * the lock aqusition had. + */ + +#include "sys.h" + +#ifndef ERTS_LOCK_COUNT_H__ +#define ERTS_LOCK_COUNT_H__ + +#ifdef ERTS_ENABLE_LOCK_COUNT +#include "ethread.h" + +#define ERTS_LCNT_MAX_LOCK_LOCATIONS (10) + +#define ERTS_LCNT_LT_SPINLOCK (((Uint16) 1) << 0) +#define ERTS_LCNT_LT_RWSPINLOCK (((Uint16) 1) << 1) +#define ERTS_LCNT_LT_MUTEX (((Uint16) 1) << 2) +#define ERTS_LCNT_LT_RWMUTEX (((Uint16) 1) << 3) +#define ERTS_LCNT_LT_PROCLOCK (((Uint16) 1) << 4) +#define ERTS_LCNT_LT_ALLOC (((Uint16) 1) << 5) + +#define ERTS_LCNT_LO_READ (((Uint16) 1) << 6) +#define ERTS_LCNT_LO_WRITE (((Uint16) 1) << 7) + +#define ERTS_LCNT_LO_READ_WRITE ( ERTS_LCNT_LO_READ \ + | ERTS_LCNT_LO_WRITE ) + +#define ERTS_LCNT_LT_ALL ( ERTS_LCNT_LT_SPINLOCK \ + | ERTS_LCNT_LT_RWSPINLOCK \ + | ERTS_LCNT_LT_MUTEX \ + | ERTS_LCNT_LT_RWMUTEX \ + | ERTS_LCNT_LT_PROCLOCK ) +/* runtime options */ + +#define ERTS_LCNT_OPT_SUSPEND (((Uint16) 1) << 0) +#define ERTS_LCNT_OPT_LOCATION (((Uint16) 1) << 1) +#define ERTS_LCNT_OPT_PROCLOCK (((Uint16) 1) << 2) + +typedef struct { + unsigned long s; + unsigned long ns; +} erts_lcnt_time_t; + +extern erts_lcnt_time_t timer_start; + +typedef struct erts_lcnt_lock_stats_s { + /* "tries" and "colls" needs to be atomic since + * trylock busy does not aquire a lock and there + * is no post action to rectify the situation + */ + + char *file; /* which file the lock was taken */ + unsigned int line; /* line number in file */ + + ethr_atomic_t tries; /* n tries to get lock */ + ethr_atomic_t colls; /* n collisions of tries to get lock */ + + unsigned long timer_n; /* #times waited for lock */ + erts_lcnt_time_t timer; /* total wait time for lock */ +} erts_lcnt_lock_stats_t; + +/* rw locks uses both states, other locks only uses w_state */ +typedef struct erts_lcnt_lock_s { + char *name; /* lock name */ + Uint16 flag; /* lock type */ + Eterm id; /* id if possible */ + +#ifdef DEBUG + ethr_atomic_t flowstate; +#endif + + /* lock states */ + ethr_atomic_t w_state; /* 0 not taken, otherwise n threads waiting */ + ethr_atomic_t r_state; /* 0 not taken, > 0 -> writes will wait */ + + /* statistics */ + unsigned int n_stats; + erts_lcnt_lock_stats_t stats[ERTS_LCNT_MAX_LOCK_LOCATIONS]; /* first entry is "undefined"*/ + + /* chains for list handling */ + /* data is hold by lcnt_lock */ + struct erts_lcnt_lock_s *prev; + struct erts_lcnt_lock_s *next; +} erts_lcnt_lock_t; + +typedef struct { + erts_lcnt_lock_t *head; + erts_lcnt_lock_t *tail; + unsigned long n; +} erts_lcnt_lock_list_t; + +typedef struct { + erts_lcnt_time_t duration; /* time since last clear */ + erts_lcnt_lock_list_t *current_locks; + erts_lcnt_lock_list_t *deleted_locks; +} erts_lcnt_data_t; + +typedef struct { + int id; + + erts_lcnt_time_t timer; /* timer */ + int timer_set; /* bool */ + int lock_in_conflict; /* bool */ + + /* function pointer */ + void *(*function)(void *); + void *argument; + +} erts_lcnt_thread_data_t; + +/* globals */ + +extern Uint16 erts_lcnt_rt_options; + +/* function declerations */ + +void erts_lcnt_init(void); + +/* list operations (local) */ +erts_lcnt_lock_list_t *erts_lcnt_list_init(void); + +void erts_lcnt_list_clear( erts_lcnt_lock_list_t *list); +void erts_lcnt_list_insert(erts_lcnt_lock_list_t *list, erts_lcnt_lock_t *lock); +void erts_lcnt_list_delete(erts_lcnt_lock_list_t *list, erts_lcnt_lock_t *lock); + +/* lock operations (global) */ +void erts_lcnt_init_lock(erts_lcnt_lock_t *lock, char *name, Uint16 flag); +void erts_lcnt_init_lock_x(erts_lcnt_lock_t *lock, char *name, Uint16 flag, Eterm id); +void erts_lcnt_destroy_lock(erts_lcnt_lock_t *lock); + +void erts_lcnt_lock(erts_lcnt_lock_t *lock); +void erts_lcnt_lock_opt(erts_lcnt_lock_t *lock, Uint16 option); +void erts_lcnt_lock_post(erts_lcnt_lock_t *lock); +void erts_lcnt_lock_post_x(erts_lcnt_lock_t *lock, char *file, unsigned int line); +void erts_lcnt_lock_unaquire(erts_lcnt_lock_t *lock); + +void erts_lcnt_unlock(erts_lcnt_lock_t *lock); +void erts_lcnt_unlock_opt(erts_lcnt_lock_t *lock, Uint16 option); + +void erts_lcnt_trylock_opt(erts_lcnt_lock_t *lock, int res, Uint16 option); +void erts_lcnt_trylock(erts_lcnt_lock_t *lock, int res); + +/* thread operations */ + +int erts_lcnt_thr_create(ethr_tid *tid, void * (*function)(void *), void *arg, ethr_thr_opts *opts); + +/* bif interface */ + +Uint16 erts_lcnt_set_rt_opt(Uint16 opt); +Uint16 erts_lcnt_clear_rt_opt(Uint16 opt); +void erts_lcnt_clear_counters(void); +char *erts_lcnt_lock_type(Uint16 type); +erts_lcnt_data_t *erts_lcnt_get_data(void); + +#endif /* ifdef ERTS_ENABLE_LOCK_COUNT */ +#endif /* ifndef ERTS_LOCK_COUNT_H__ */ |