⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thd_dbg.c

📁 wm PNE 3.3 source code, running at more than vxworks6.x version.
💻 C
字号:
/* $Header: /usr/cvsroot/target/src/wrn/wm/common/lib/thd_dbg.c,v 1.3 2003/01/16 18:18:58 josh Exp $ *//* * Copyright (C) 1999-2005 Wind River Systems, Inc. * All rights reserved.  Provided under license only. * Distribution or other use of this software is only * permitted pursuant to the terms of a license agreement * from Wind River Systems (and is otherwise prohibited). * Refer to that license agreement for terms of use. *//**************************************************************************** *  Copyright 1998-1999 Integrated Systems, Inc. *  All rights reserved. ****************************************************************************//* * $Log: thd_dbg.c,v $ * Revision 1.3  2003/01/16 18:18:58  josh * directory structure shifting * * Revision 1.2  2001/11/06 22:15:56  tneale * Fixed for newest file layout * * Revision 1.1.1.1  2001/11/05 17:48:40  tneale * Tornado shuffle * * Revision 1.12  2001/06/12 08:06:07  paul * Mutex priorities are unsigned. * Added debugging to condition variable routines. * * Revision 1.11  2001/03/22 16:54:08  paul * Mutex and condition variable functions now return errors. * * Revision 1.10  2001/03/20 17:11:38  paul * Removed unused local variable. * * Revision 1.9  2001/01/19 22:21:32  paul * Update copyright. * * Revision 1.8  2000/10/16 19:22:06  paul * Restore sockets and mempool code. * * Revision 1.6  2000/03/17 00:16:59  meister * Update copyright message * * Revision 1.5  1999/09/02 20:58:18  wes * Create a new memory pool for thread debug state, and use it instead of * using malloc/free. * * Revision 1.4  1999/05/20 19:44:32  wes * Print out more info for thread assertion failures * * Revision 1.3  1999/05/19 21:27:33  wes * Fix signed vs unsigned comparison glitch * * Revision 1.2  1999/04/21 20:05:18  wes * Silence DIAB compiler warnings * * Revision 1.1  1999/02/18 17:45:57  wes * 8.3ize thread_debug.c to thd_dbg.c * * Revision 1.2  1999/02/18 04:41:23  wes * Sockets merge: Everything Else *  - memory pools *  - thread support *  - port-specific headers * * Revision 1.1.6.10  1999/02/05 18:33:57  paul * Changed the way we identify the thread for trace statements, due to * differences between various pthreads implementations. * * Revision 1.1.6.9  1999/01/22 19:49:15  paul * Added this_thread() to allow other parts of the code to print the * current thread. * Added copyright notice. * *//* [clearcase]modification history-------------------01b,20apr05,job  update copyright notices01a,11dec03,job  fix copyright statements*/#include <wrn/wm/common/install.h>#include <wrn/wm/common/config.h>#include <wrn/wm/common/thread.h>#include <wrn/attache/config.h>	/* !!!??? */#include <wrn/attache/glue.h>	/* !!!??? */#include <wrn/wm/common/bug.h>#define ASSERT1(cond, lock, file, line) \	do {if (!(cond)) { thread_preabort(file, line, lock); \            BUG(BUG_ASSERTION_FAILED, BUG_FATAL, 0, \		(BUG_OUT, "Lock assertion \"%s\" failed, file %s, line %d", \                          #cond, file, line));  } } while (0)glue_mutex_t etc_meta_mutex;enum thread_debug_state {    THREAD_DEBUG_RUNNABLE,    THREAD_DEBUG_MUTEX_WAIT,    THREAD_DEBUG_COND_WAIT};typedef struct _tdit thread_debug_info_t;struct _tdit {  thread_debug_info_t *next_thread;  char *thread_name;  enum thread_debug_state thread_state;  etc_mutex_t *thread_held_locks;  etc_mutex_t *thread_wanted_lock;  etc_cond_t *thread_wanted_cond;  glue_thread_t tid;};size_t thd_debug_size = sizeof(thread_debug_info_t);void debug_state_free(void *debug){  BUG(BUG_THREAD_TRACE, BUG_CONTINUABLE, 0,      (BUG_OUT, "Freeing thread state %p", debug));  GLUE_FREE_TO_POOL(debug, MEMPOOL_THD_DBG);}void common_thread_init(void){  GLUE_THREAD_INIT();  GLUE_MUTEX_INIT_MAGIC(&etc_meta_mutex);   GLUE_THD_COOKIE_INIT(debug_state_free);  BUG(BUG_THREAD_TRACE, BUG_CONTINUABLE, 0,      (BUG_OUT, "Threading!"));}thread_debug_info_t *thread_debug_state(void){  thread_debug_info_t *dip;  GLUE_THD_COOKIE_GET(&dip);    if (dip == NULL) {    dip = GLUE_ALLOC_FROM_POOL(sizeof(*dip), MEMPOOL_THD_DBG);    BUG_ASSERT(dip != NULL);    dip->tid = GLUE_THD_SELF();    dip->next_thread = NULL;    dip->thread_name = NULL;    dip->thread_state = THREAD_DEBUG_RUNNABLE;    dip->thread_held_locks = NULL;    dip->thread_wanted_lock = NULL;    dip->thread_wanted_cond = NULL;    GLUE_THD_COOKIE_SET(dip);  }  return dip;}static unsigned compute_lock_prio(thread_debug_info_t *tdi){  unsigned prio = 0;  etc_mutex_t *lock;  for (lock = tdi->thread_held_locks; lock != NULL; lock = lock->next_lock)    {      if (lock->lock_prio > prio)	prio = lock->lock_prio;    }  return prio;}#if INSTALL_BUGstatic char *indent_string(int level){  static char indentfu[10]="\t\t\t\t\t\t\t\t\t\t";  if (level < 0) level=0;  if (level > (int)sizeof(indentfu)) level = sizeof(indentfu);  return &indentfu[sizeof(indentfu) - level];}#endifvoid print_proc (int level, char *tag, thread_debug_info_t *tdi){  BUG(BUG_ASSERTION_FAILED, BUG_CONTINUABLE, 0,        (BUG_OUT, "%s%s: %p", indent_string(level), tag, tdi));}void print_lock(int level, char *tag, etc_mutex_t *lock) {  BUG(BUG_ASSERTION_FAILED, BUG_CONTINUABLE, 0,       (BUG_OUT, "%s%s: %s (%p) (pri %u)", indent_string(level),       tag, lock->lock_name, lock, lock->lock_prio));  BUG(BUG_ASSERTION_FAILED, BUG_CONTINUABLE, 0,       (BUG_OUT, "%slock last locked in %s, line %d",       indent_string(level+1), lock->last_lock_file, lock->last_lock_line));  BUG(BUG_ASSERTION_FAILED, BUG_CONTINUABLE, 0,       (BUG_OUT, "%slock last unlocked in %s, line %d",       indent_string(level+1), lock->last_unlock_file,       lock->last_unlock_line));  if (lock->lock_owner != NULL) {    print_proc(level+1, "Held by", lock->lock_owner);  }}void thread_preabort(char *file, int line, etc_mutex_t *errlock) {  thread_debug_info_t *tdi = thread_debug_state();  etc_mutex_t *lock;    BUG(BUG_ASSERTION_FAILED, BUG_CONTINUABLE, 0,      (BUG_OUT, "locking error detected on lock %p at %s, line %d",       errlock,       file, line));  print_lock(0, "bad lock", errlock);  if (tdi->thread_wanted_lock == NULL) {    BUG(BUG_ASSERTION_FAILED, BUG_CONTINUABLE, 0,	(BUG_OUT, "No locks wanted"));  } else {    print_lock(0, "waiting for", tdi->thread_wanted_lock);  }  if (tdi->thread_held_locks == NULL) {    BUG(BUG_ASSERTION_FAILED, BUG_CONTINUABLE, 0,	(BUG_OUT, "No locks held"));  } else {    BUG(BUG_ASSERTION_FAILED, BUG_CONTINUABLE, 0,	(BUG_OUT, "Held locks:"));    for (lock = tdi->thread_held_locks; lock != NULL; lock = lock->next_lock) {      BUG(BUG_ASSERTION_FAILED, BUG_CONTINUABLE, 0,	  (BUG_OUT, "\t%s (%p) (pri %u)", lock->lock_name, lock, lock->lock_prio));    }  }}static int etc_mutex_lock_debug (etc_mutex_t *lock, unsigned prio,				 char *file, int line) {  thread_debug_info_t *us = thread_debug_state();  unsigned curlockprio = compute_lock_prio(us);  int ret;    ASSERT1((lock->magic == ETC_LOCK_MAGIC), lock, file, line);  us->thread_state = THREAD_DEBUG_MUTEX_WAIT;  us->thread_wanted_lock = lock;  ASSERT1((lock->lock_owner != us), lock, file, line);  ASSERT1((lock->lock_prio > curlockprio), lock, file, line);  BUG(BUG_THREAD_TRACE, BUG_CONTINUABLE, 0,       (BUG_OUT, "waiting to lock %s (%p) at %s, line %d",       lock->lock_name, lock, file, line));  if (GLUE_MUTEX_TRYLOCK(&(lock)->m, prio)) {    ETC_META_UNLOCK();    ret = (int)GLUE_MUTEX_LOCK(&(lock)->m, prio);    ETC_META_LOCK();    if (ret) {      BUG(BUG_THREAD_TRACE, BUG_CONTINUABLE, 0, 	  (BUG_OUT, "!!failed to lock %s (%p) at %s, line %d", lock->lock_name,	   lock, file, line));      return ret;    }  }  BUG(BUG_THREAD_TRACE, BUG_CONTINUABLE, 0,       (BUG_OUT, "locked %s (%p) at %s, line %d", lock->lock_name,       lock, file, line));  us->thread_state = THREAD_DEBUG_RUNNABLE;  us->thread_wanted_lock = NULL;  ASSERT1((lock->lock_prio == prio), lock, file, line);  ASSERT1((lock->lock_owner == NULL), lock, file, line);  lock->last_lock_file = file;  lock->last_lock_line = line;  lock->lock_owner = us;  lock->next_lock = us->thread_held_locks;  us->thread_held_locks = lock;    return 0;}static int etc_mutex_unlock_debug (etc_mutex_t *lock, unsigned prio,				   char *file, int line){  thread_debug_info_t *us = thread_debug_state();  ASSERT1((lock->magic == ETC_LOCK_MAGIC), lock, file, line);    ASSERT1((lock->lock_owner == us), lock, file, line);  ASSERT1((lock->lock_prio == prio), lock, file, line);  lock->lock_owner = NULL;  BUG(BUG_THREAD_TRACE, BUG_CONTINUABLE, 0,       (BUG_OUT, "unlocking %s (%p) at %s, line %d",       lock->lock_name, lock, file, line));  if (lock == us->thread_held_locks) {    us->thread_held_locks = lock->next_lock;    lock->next_lock = NULL;  } else {    etc_mutex_t *l1;    for (l1 = us->thread_held_locks; l1 != NULL; l1 = l1->next_lock) {      if (l1->next_lock == lock) {	l1->next_lock = lock->next_lock;	lock->next_lock = NULL;	break;      }    }  }  ASSERT1((lock->next_lock == NULL), lock, file, line);  lock->last_unlock_file = file;  lock->last_unlock_line = line;  return (int)GLUE_MUTEX_UNLOCK(&(lock)->m, prio);}void etc_mutex_lock_assert (etc_mutex_t *lock, unsigned prio,			    char *file, int line){  thread_debug_info_t *us = thread_debug_state();  ETC_META_LOCK();  ASSERT1((lock->magic == ETC_LOCK_MAGIC), lock, file, line);  ASSERT1((lock->lock_owner == us), lock, file, line);  ASSERT1((lock->lock_prio == prio), lock, file, line);  ETC_META_UNLOCK();}int etc_mutex_destroy (etc_mutex_t *lock, char *file, int line){  int ret;  ETC_META_LOCK();  BUG(BUG_THREAD_TRACE, BUG_CONTINUABLE, 0,      (BUG_OUT, "destroying mutex %s (%p)",        lock->lock_name, lock));  ASSERT1((lock->magic == ETC_LOCK_MAGIC), lock, file, line);    ret = (int)GLUE_MUTEX_DESTROY(&(lock)->m);  (lock)->magic = ~ETC_LOCK_MAGIC;  lock->last_unlock_file = file;  lock->last_unlock_line = line;  ETC_META_UNLOCK();  return ret;}void *this_thread(void){  thread_debug_info_t *us = thread_debug_state();  return (void *)us;}int etc_mutex_init(etc_mutex_t *lock, unsigned prio, char *name){  int ret;  ETC_META_LOCK();  lock->magic = ETC_LOCK_MAGIC;  lock->lock_owner = NULL;  lock->lock_name = name;  lock->lock_prio = prio;  lock->next_lock = NULL;  ret = (int)GLUE_MUTEX_INIT(&lock->m, prio);  ETC_META_UNLOCK();  return ret;}int etc_mutex_lock(etc_mutex_t *lock, unsigned prio, char *file, int line){  int ret;  ETC_META_LOCK();  ret = etc_mutex_lock_debug(lock, prio, file, line);  ETC_META_UNLOCK();  return ret;}int etc_mutex_unlock(etc_mutex_t *lock, unsigned prio, char *file, int line){  int ret;  ETC_META_LOCK();  ret = etc_mutex_unlock_debug(lock, prio, file, line);  ETC_META_UNLOCK();  return ret;}int etc_cond_init(etc_cond_t *cond, etc_mutex_t *mutex, char *file, int line){  int ret;  ETC_META_LOCK();  cond->m = mutex;  ret = (int)GLUE_COND_INIT(&cond->c, &mutex->m);  ETC_META_UNLOCK();  /* pthread_cond_init() and cv_create() both return 0 on success */  BUG_IF((ret != 0), BUG_ASSERTION_FAILED, BUG_CONTINUABLE, 0,	 (BUG_OUT, "GLUE_COND_INIT returned %d, file %s, line %d", ret, file, line));  return ret;}int etc_cond_wait(etc_cond_t *cond, etc_mutex_t *mutex, char *file, int line){  int ret;  ETC_META_LOCK();  etc_mutex_unlock_debug(mutex, mutex->lock_prio, file, line);  ret = (int)GLUE_COND_WAIT(&cond->c, &etc_meta_mutex);  etc_mutex_lock_debug(mutex, mutex->lock_prio, file, line);  ETC_META_UNLOCK();  /* pthread_cond_wait() and cv_wait() both return 0 on success */  BUG_IF((ret != 0), BUG_ASSERTION_FAILED, BUG_FATAL, 0,	 (BUG_OUT, "GLUE_COND_WAIT returned %d, file %s, line %d", ret, file, line));  return ret;}int etc_cond_wakeup(etc_cond_t *cond, etc_mutex_t *mutex, char *file, int line){  int ret;  ETC_META_LOCK();  ret = (int)GLUE_COND_WAKEUP(&cond->c, mutex);  ETC_META_UNLOCK();  /* pthread_cond_signal() and cv_signal() both return 0 on success */  BUG_IF((ret != 0), BUG_ASSERTION_FAILED, BUG_FATAL, 0,	 (BUG_OUT, "GLUE_COND_WAKEUP returned %d, file %s, line %d", ret, file, line));  return ret;}int etc_cond_broadcast(etc_cond_t *cond, etc_mutex_t *mutex, char *file, int line){  int ret;  ETC_META_LOCK();  ret = (int)GLUE_COND_BROADCAST(&cond->c, mutex);  ETC_META_UNLOCK();  /* pthread_cond_broadcast() and cv_broadcast() both return 0 on success */  BUG_IF((ret != 0), BUG_ASSERTION_FAILED, BUG_FATAL, 0,	 (BUG_OUT, "GLUE_COND_BROADCAST returned %d, file %s, line %d", ret, file, line));  return ret;}int etc_cond_destroy(etc_cond_t *cond, char *file, int line){  int ret;  ETC_META_LOCK();  ret = (int)GLUE_COND_DESTROY(&cond->c);  ETC_META_UNLOCK();  /* pthread_cond_destroy() and cv_delete() both return 0 on success */  BUG_IF((ret != 0), BUG_ASSERTION_FAILED, BUG_FATAL, 0,	 (BUG_OUT, "GLUE_COND_DESTROY returned %d, file %s, line %d", ret, file, line)); return ret;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -