📄 print.c
字号:
static void prt_lock_init (void)
{
/**************************************
*
* l o c k _ i n i t
*
**************************************
*
* Functional description
* Initialize a lock table to looking -- i.e. don't do
* nuthin.
*
**************************************/
}
static void prt_history (
OUTFILE outfile,
LHB LOCK_header,
PTR history_header,
SCHAR *title)
{
/**************************************
*
* p r t _ h i s t o r y
*
**************************************
*
* Functional description
* Print history list of lock table.
*
**************************************/
HIS history;
FPRINTF (outfile, "%s:\n", title);
for (history = (HIS) ABS_PTR (history_header); TRUE;
history = (HIS) ABS_PTR (history->his_next))
{
if (history->his_operation)
FPRINTF (outfile, " %s:\towner = %6d, lock = %6d, request = %6d\n",
history_names [history->his_operation],
history->his_process, history->his_lock,
history->his_request);
if (history->his_next == history_header)
break;
}
}
static void prt_lock (
OUTFILE outfile,
LHB LOCK_header,
LBL lock,
USHORT sw_series)
{
/**************************************
*
* p r t _ l o c k
*
**************************************
*
* Functional description
* Print a formatted lock block
*
**************************************/
SRQ que;
LRQ request;
if (sw_series && lock->lbl_series != sw_series)
return;
FPRINTF (outfile, "LOCK BLOCK %6d\n", REL_PTR (lock));
FPRINTF (outfile, "\tSeries: %d, Parent: %6d, State: %d, size: %d length: %d data: %d\n",
lock->lbl_series, lock->lbl_parent, lock->lbl_state,
lock->lbl_size, lock->lbl_length, lock->lbl_data);
if (lock->lbl_length == 4)
{
SLONG key;
UCHAR *p, *q, *end;
p = (UCHAR*) &key;
q = lock->lbl_key;
for (end = q + 4; q < end; q++)
*p++ = *q;
FPRINTF (outfile, "\tKey: %06u,", key);
}
else
{
UCHAR c, *p, *q, *end, temp [512];
q = lock->lbl_key;
for (p = temp, end = q + lock->lbl_length; q < end; q++)
{
c = *q;
if ((c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') ||
c == '/')
*p++ = c;
else
{
sprintf (p, "<%d>", c);
while (*p)
p++;
}
}
*p = 0;
FPRINTF (outfile, "\tKey: %s,", temp);
}
FPRINTF (outfile, " Flags: 0x%02X, Pending request count: %6d\n",
lock->lbl_flags, lock->lbl_pending_lrq_count);
prt_que (outfile, LOCK_header, "\tHash que", &lock->lbl_lhb_hash,
OFFSET (LBL, lbl_lhb_hash));
prt_que (outfile, LOCK_header, "\tRequests", &lock->lbl_requests,
OFFSET (LRQ, lrq_lbl_requests));
QUE_LOOP (lock->lbl_requests, que)
{
request = (LRQ) ((UCHAR*) que - OFFSET (LRQ, lrq_lbl_requests));
FPRINTF (outfile, "\t\tRequest %6d, Owner: %6d, State: %d (%d), Flags: 0x%02X\n",
REL_PTR (request), request->lrq_owner, request->lrq_state,
request->lrq_requested, request->lrq_flags);
}
FPRINTF (outfile, "\n");
}
static void prt_owner (
OUTFILE outfile,
LHB LOCK_header,
OWN owner,
BOOLEAN sw_requests,
BOOLEAN sw_waitlist)
{
/**************************************
*
* p r t _ o w n e r
*
**************************************
*
* Functional description
* Print a formatted owner block.
*
**************************************/
SRQ que;
FPRINTF (outfile, "OWNER BLOCK %6d\n", REL_PTR (owner));
#ifndef mpexl
FPRINTF (outfile, "\tOwner id: %6d, type: %1d, flags: 0x%02X, pending: %6d, semid: %6d ",
owner->own_owner_id, owner->own_owner_type,
(owner->own_flags | (UCHAR) owner->own_ast_flags), owner->own_pending_request,
owner->own_semaphore & ~OWN_semavail);
if (owner->own_semaphore & OWN_semavail)
FPRINTF (outfile, "(available)\n");
else
FPRINTF (outfile, "\n");
FPRINTF (outfile, "\tProcess id: %6d, UID: 0x%X %s\n",
owner->own_process_id,
owner->own_process_uid,
ISC_check_process_existence (owner->own_process_id, owner->own_process_uid, FALSE) ? "Alive" : "Dead");
#ifdef SOLARIS_MT
FPRINTF (outfile, "\tLast Acquire: %6d (%6d ago)",
owner->own_acquire_time,
LOCK_header->lhb_acquires - owner->own_acquire_time);
#ifdef DEV_BUILD
FPRINTF (outfile, " sec %9ld (%3d sec ago)",
owner->own_acquire_realtime,
time (NULL) - owner->own_acquire_realtime);
#endif /* DEV_BUILD */
FPRINTF (outfile, "\n");
#endif /* SOLARIS_MT */
{
UCHAR tmp;
tmp = (owner->own_flags | (UCHAR) owner->own_ast_flags
| (UCHAR) owner->own_ast_hung_flags );
FPRINTF (outfile, "\tFlags: 0x%02X ", tmp);
FPRINTF (outfile, " %s", (tmp & OWN_hung) ? "hung" : " ");
FPRINTF (outfile, " %s", (tmp & OWN_blocking)? "blkg" : " ");
FPRINTF (outfile, " %s", (tmp & OWN_starved) ? "STRV" : " ");
FPRINTF (outfile, " %s", (tmp & OWN_signal) ? "sgnl" : " ");
FPRINTF (outfile, " %s", (tmp & OWN_wakeup) ? "wake" : " ");
FPRINTF (outfile, " %s", (tmp & OWN_scanned) ? "scan" : " ");
FPRINTF (outfile, "\n");
}
#else /* mpexl */
FPRINTF (outfile, "\tProcess id: %6d.%6d flags: 0x%02X, pending: %6d\n",
owner->own_process_id, owner->own_process_uid,
(owner->own_flags | (UCHAR) owner->own_ast_flags), owner->own_pending_request);
FPRINTF (outfile, "\tAsync port: %6d, Sync port: %6d\n",
owner->own_mpexl_async_port, owner->own_mpexl_sync_port);
#endif /* mpexl */
prt_que (outfile, LOCK_header, "\tRequests", &owner->own_requests,
OFFSET (LRQ, lrq_own_requests));
prt_que (outfile, LOCK_header, "\tBlocks", &owner->own_blocks,
OFFSET (LRQ, lrq_own_blocks));
if (sw_waitlist)
{
struct waitque owner_list;
owner_list.waitque_depth = 0;
prt_owner_wait_cycle (outfile, LOCK_header, owner, 8, &owner_list);
}
FPRINTF (outfile, "\n");
if (sw_requests)
QUE_LOOP (owner->own_requests, que)
prt_request (outfile, LOCK_header,
(LRQ)((UCHAR*) que - OFFSET (LRQ, lrq_own_requests)));
}
static void prt_owner_wait_cycle (
OUTFILE outfile,
LHB LOCK_header,
OWN owner,
USHORT indent,
struct waitque *waiters)
{
/**************************************
*
* p r t _ o w n e r _ w a i t _ c y c l e
*
**************************************
*
* Functional description
* For the given owner, print out the list of owners
* being waited on. The printout is recursive, up to
* a limit. It is recommended this be used with
* the -c consistency mode.
*
**************************************/
USHORT i;
for (i = indent; i; i--)
FPRINTF (outfile, " ");
/* Check to see if we're in a cycle of owners - this might be
a deadlock, or might not, if the owners haven't processed
their blocking queues */
for (i = 0; i < waiters->waitque_depth; i++)
if (REL_PTR (owner) == waiters->waitque_entry [i])
{
FPRINTF (outfile, "%6d (potential deadlock).\n", REL_PTR (owner));
return;
};
FPRINTF (outfile, "%6d waits on ", REL_PTR (owner));
if (!owner->own_pending_request)
FPRINTF (outfile, "nothing.\n");
else
{
SRQ que;
LRQ owner_request;
LBL lock;
USHORT counter;
BOOLEAN owner_conversion;
if (waiters->waitque_depth > COUNT (waiters->waitque_entry))
{
FPRINTF (outfile, "Dependency too deep\n");
return;
};
waiters->waitque_entry [waiters->waitque_depth++] = REL_PTR (owner);
FPRINTF (outfile, "\n");
owner_request = ABS_PTR (owner->own_pending_request);
assert (owner_request->lrq_type == type_lrq);
owner_conversion = (owner_request->lrq_state > LCK_null) ? TRUE : FALSE;
lock = ABS_PTR (owner_request->lrq_lock);
assert (lock->lbl_type == type_lbl);
counter = 0;
QUE_LOOP (lock->lbl_requests, que)
{
OWN lock_owner;
LRQ lock_request;
if (counter++ > 50)
{
for (i = indent+6; i; i--)
FPRINTF (outfile, " ");
FPRINTF (outfile, "printout stopped after %d owners\n", counter-1);
break;
}
lock_request = (LRQ)((UCHAR*) que - OFFSET (LRQ, lrq_lbl_requests));
assert (lock_request->lrq_type == type_lrq);
if (LOCK_header->lhb_flags & LHB_lock_ordering && !owner_conversion)
{
/* Requests AFTER our request can't block us */
if (owner_request == lock_request)
break;
if (COMPATIBLE (owner_request->lrq_requested,
MAX (lock_request->lrq_state, lock_request->lrq_requested)))
continue;
}
else
{
/* Requests AFTER our request CAN block us */
if (lock_request == owner_request)
continue;
if (COMPATIBLE (owner_request->lrq_requested, lock_request->lrq_state))
continue;
};
lock_owner = ABS_PTR (lock_request->lrq_owner);
prt_owner_wait_cycle (outfile, LOCK_header, lock_owner, indent+4, waiters);
}
waiters->waitque_depth--;
}
}
static void prt_request (
OUTFILE outfile,
LHB LOCK_header,
LRQ request)
{
/**************************************
*
* p r t _ r e q u e s t
*
**************************************
*
* Functional description
* Print a format request block.
*
**************************************/
FPRINTF (outfile, "REQUEST BLOCK %6d\n", REL_PTR (request));
FPRINTF (outfile, "\tOwner: %6d, Lock: %6d, State: %d, Mode: %d, Flags: 0x%02X\n",
request->lrq_owner, request->lrq_lock, request->lrq_state,
request->lrq_requested, request->lrq_flags);
FPRINTF (outfile, "\tAST: 0x%X, argument: 0x%X\n", request->lrq_ast_routine,
request->lrq_ast_argument);
prt_que2 (outfile, LOCK_header, "\tlrq_own_requests", &request->lrq_own_requests, OFFSET (LRQ, lrq_own_requests));
prt_que2 (outfile, LOCK_header, "\tlrq_lbl_requests", &request->lrq_lbl_requests, OFFSET (LRQ, lrq_lbl_requests));
prt_que2 (outfile, LOCK_header, "\tlrq_own_blocks ", &request->lrq_own_blocks, OFFSET (LRQ, lrq_own_blocks));
FPRINTF (outfile, "\n");
}
static void prt_que (
OUTFILE outfile,
LHB LOCK_header,
SCHAR *string,
SRQ que,
USHORT que_offset)
{
/**************************************
*
* p r t _ q u e
*
**************************************
*
* Functional description
* Print the contents of a self-relative que.
*
**************************************/
SLONG count, offset;
SRQ next;
offset = REL_PTR (que);
if (offset == que->srq_forward && offset == que->srq_backward)
{
FPRINTF (outfile, "%s: *empty*\n", string);
return;
}
count = 0;
QUE_LOOP ((*que), next)
++count;
FPRINTF (outfile, "%s (%ld):\tforward: %6d, backward: %6d\n",
string, count,
que->srq_forward - que_offset,
que->srq_backward - que_offset);
}
static void prt_que2 (
OUTFILE outfile,
LHB LOCK_header,
SCHAR *string,
SRQ que,
USHORT que_offset)
{
/**************************************
*
* p r t _ q u e 2
*
**************************************
*
* Functional description
* Print the contents of a self-relative que.
* But don't try to count the entries, as they might be invalid
*
**************************************/
SLONG offset;
offset = REL_PTR (que);
if (offset == que->srq_forward && offset == que->srq_backward)
{
FPRINTF (outfile, "%s: *empty*\n", string);
return;
}
FPRINTF (outfile, "%s:\tforward: %6d, backward: %6d\n",
string,
que->srq_forward - que_offset,
que->srq_backward - que_offset);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -