mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 22:03:03 +01:00
-Unify 3 srq implementations and move it to que.h
-Remove duplicated lock constants between jrd.h and lock.h (naming fix and srq move outside lock.h was prerequisites for this change)
This commit is contained in:
parent
50e6d2db87
commit
2add5b1f60
@ -56,7 +56,6 @@
|
||||
|
||||
#ifdef UNIX
|
||||
#include <signal.h>
|
||||
#define EVENT_SIGNAL SIGUSR2
|
||||
#endif
|
||||
|
||||
#ifdef WIN_NT
|
||||
@ -78,9 +77,12 @@
|
||||
#define MUTEX EVENT_header->evh_mutex
|
||||
#endif
|
||||
|
||||
#define EVENT_FLAG 64
|
||||
#define SEMAPHORES 1
|
||||
#define MAX_EVENT_BUFFER 65500
|
||||
#define SRQ_BASE ((UCHAR *) EVENT_header)
|
||||
|
||||
// Not used
|
||||
// #define EVENT_FLAG 64
|
||||
const int SEMAPHORES = 1;
|
||||
const int MAX_EVENT_BUFFER = 65500;
|
||||
|
||||
|
||||
|
||||
@ -98,14 +100,14 @@ static EVNT find_event(USHORT, const TEXT*, EVNT);
|
||||
static void free_global(FRB);
|
||||
static RINT historical_interest(SES, SLONG);
|
||||
static void init(void*, SH_MEM, bool);
|
||||
static void insert_tail(SRQ *, SRQ *);
|
||||
static void insert_tail(srq *, srq *);
|
||||
static EVNT make_event(USHORT, const TEXT*, SLONG);
|
||||
static void mutex_bugcheck(const TEXT*, int);
|
||||
static void post_process(PRB);
|
||||
static void probe_processes(void);
|
||||
static void punt(const TEXT*);
|
||||
static void release(void);
|
||||
static void remove_que(SRQ *);
|
||||
static void remove_que(srq *);
|
||||
static bool request_completed(EVT_REQ);
|
||||
static ISC_STATUS return_ok(ISC_STATUS *);
|
||||
#ifdef MULTI_THREAD
|
||||
@ -137,28 +139,28 @@ void EVENT_cancel(SLONG request_id)
|
||||
* Cancel an outstanding event.
|
||||
*
|
||||
**************************************/
|
||||
SRQ *que, *que2;
|
||||
srq *event_srq, *que2;
|
||||
|
||||
if (!EVENT_header)
|
||||
return;
|
||||
|
||||
ACQUIRE;
|
||||
acquire();
|
||||
|
||||
PRB process = (PRB) ABS_PTR(EVENT_process_offset);
|
||||
PRB process = (PRB) SRQ_ABS_PTR(EVENT_process_offset);
|
||||
|
||||
QUE_LOOP(process->prb_sessions, que2) {
|
||||
SRQ_LOOP(process->prb_sessions, que2) {
|
||||
SES session = (SES) ((UCHAR *) que2 - OFFSET(SES, ses_sessions));
|
||||
QUE_LOOP(session->ses_requests, que) {
|
||||
EVT_REQ request = (EVT_REQ) ((UCHAR *) que - OFFSET(EVT_REQ, req_requests));
|
||||
SRQ_LOOP(session->ses_requests, event_srq) {
|
||||
EVT_REQ request = (EVT_REQ) ((UCHAR *) event_srq - OFFSET(EVT_REQ, req_requests));
|
||||
if (request->req_request_id == request_id) {
|
||||
delete_request(request);
|
||||
RELEASE;
|
||||
release();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RELEASE;
|
||||
release();
|
||||
}
|
||||
|
||||
|
||||
@ -182,9 +184,9 @@ SLONG EVENT_create_session(ISC_STATUS * status_vector)
|
||||
if (!EVENT_process_offset)
|
||||
create_process();
|
||||
|
||||
ACQUIRE;
|
||||
acquire();
|
||||
SES session = (SES) alloc_global(type_ses, (SLONG) sizeof(ses), false);
|
||||
PRB process = (PRB) ABS_PTR(EVENT_process_offset);
|
||||
PRB process = (PRB) SRQ_ABS_PTR(EVENT_process_offset);
|
||||
session->ses_process = EVENT_process_offset;
|
||||
|
||||
#ifdef MULTI_THREAD
|
||||
@ -192,9 +194,9 @@ SLONG EVENT_create_session(ISC_STATUS * status_vector)
|
||||
#endif
|
||||
|
||||
insert_tail(&process->prb_sessions, &session->ses_sessions);
|
||||
QUE_INIT(session->ses_requests);
|
||||
const SLONG id = REL_PTR(session);
|
||||
RELEASE;
|
||||
SRQ_INIT(session->ses_requests);
|
||||
const SLONG id = SRQ_REL_PTR(session);
|
||||
release();
|
||||
|
||||
return id;
|
||||
}
|
||||
@ -216,9 +218,9 @@ void EVENT_delete_session(SLONG session_id)
|
||||
if (!EVENT_header)
|
||||
return;
|
||||
|
||||
ACQUIRE;
|
||||
acquire();
|
||||
delete_session(session_id);
|
||||
RELEASE;
|
||||
release();
|
||||
}
|
||||
|
||||
|
||||
@ -240,14 +242,14 @@ void EVENT_deliver()
|
||||
* for delivery with EVENT_post.
|
||||
*
|
||||
**************************************/
|
||||
SRQ *que;
|
||||
srq *event_srq;
|
||||
|
||||
/* If we're not initialized, do so now */
|
||||
|
||||
if (!EVENT_header)
|
||||
return;
|
||||
|
||||
ACQUIRE;
|
||||
acquire();
|
||||
|
||||
/* Deliver requests for posted events */
|
||||
|
||||
@ -255,8 +257,8 @@ void EVENT_deliver()
|
||||
|
||||
while (flag) {
|
||||
flag = false;
|
||||
QUE_LOOP (EVENT_header->evh_processes, que) {
|
||||
PRB process = (PRB) ((UCHAR*) que - OFFSET (PRB, prb_processes));
|
||||
SRQ_LOOP (EVENT_header->evh_processes, event_srq) {
|
||||
PRB process = (PRB) ((UCHAR*) event_srq - OFFSET (PRB, prb_processes));
|
||||
if (process->prb_flags & PRB_wakeup) {
|
||||
post_process(process);
|
||||
flag = true;
|
||||
@ -265,7 +267,7 @@ void EVENT_deliver()
|
||||
}
|
||||
}
|
||||
|
||||
RELEASE;
|
||||
release();
|
||||
}
|
||||
|
||||
|
||||
@ -364,14 +366,14 @@ int EVENT_post(ISC_STATUS * status_vector,
|
||||
* Post an event.
|
||||
*
|
||||
**************************************/
|
||||
SRQ *que;
|
||||
srq *event_srq;
|
||||
|
||||
/* If we're not initialized, do so now */
|
||||
|
||||
if (!EVENT_header && !EVENT_init(status_vector, false))
|
||||
return status_vector[1];
|
||||
|
||||
ACQUIRE;
|
||||
acquire();
|
||||
|
||||
EVNT event;
|
||||
EVNT parent = find_event(major_length, major_code, 0);
|
||||
@ -379,20 +381,20 @@ int EVENT_post(ISC_STATUS * status_vector,
|
||||
(event = find_event(minor_length, minor_code, parent)))
|
||||
{
|
||||
event->evnt_count += count;
|
||||
QUE_LOOP(event->evnt_interests, que) {
|
||||
RINT interest = (RINT) ((UCHAR *) que - OFFSET(RINT, rint_interests));
|
||||
SRQ_LOOP(event->evnt_interests, event_srq) {
|
||||
RINT interest = (RINT) ((UCHAR *) event_srq - OFFSET(RINT, rint_interests));
|
||||
if (interest->rint_request) {
|
||||
EVT_REQ request = (EVT_REQ) ABS_PTR(interest->rint_request);
|
||||
EVT_REQ request = (EVT_REQ) SRQ_ABS_PTR(interest->rint_request);
|
||||
|
||||
if (interest->rint_count <= event->evnt_count) {
|
||||
PRB process = (PRB) ABS_PTR(request->req_process);
|
||||
PRB process = (PRB) SRQ_ABS_PTR(request->req_process);
|
||||
process->prb_flags |= PRB_wakeup;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RELEASE;
|
||||
release();
|
||||
|
||||
return return_ok(status_vector);
|
||||
}
|
||||
@ -417,9 +419,9 @@ SLONG EVENT_que(ISC_STATUS* status_vector,
|
||||
**************************************/
|
||||
// Allocate request block
|
||||
|
||||
ACQUIRE;
|
||||
acquire();
|
||||
EVT_REQ request = (EVT_REQ) alloc_global(type_reqb, sizeof(evt_req), false);
|
||||
SES session = (SES) ABS_PTR(session_id);
|
||||
SES session = (SES) SRQ_ABS_PTR(session_id);
|
||||
insert_tail(&session->ses_requests, &request->req_requests);
|
||||
request->req_session = session_id;
|
||||
request->req_process = EVENT_process_offset;
|
||||
@ -428,22 +430,22 @@ SLONG EVENT_que(ISC_STATUS* status_vector,
|
||||
const SLONG id = ++EVENT_header->evh_request_id;
|
||||
request->req_request_id = id;
|
||||
|
||||
const SLONG request_offset = REL_PTR(request);
|
||||
const SLONG request_offset = SRQ_REL_PTR(request);
|
||||
|
||||
/* Find parent block */
|
||||
EVNT parent = find_event(string_length, string, 0);
|
||||
if (!parent) {
|
||||
parent = make_event(string_length, string, 0);
|
||||
request = (EVT_REQ) ABS_PTR(request_offset);
|
||||
session = (SES) ABS_PTR(session_id);
|
||||
request = (EVT_REQ) SRQ_ABS_PTR(request_offset);
|
||||
session = (SES) SRQ_ABS_PTR(session_id);
|
||||
}
|
||||
|
||||
const SLONG parent_offset = REL_PTR(parent);
|
||||
const SLONG parent_offset = SRQ_REL_PTR(parent);
|
||||
|
||||
/* Process event block */
|
||||
|
||||
PTR* ptr = &request->req_interests;
|
||||
SLONG ptr_offset = REL_PTR(ptr);
|
||||
SRQ_PTR* ptr = &request->req_interests;
|
||||
SLONG ptr_offset = SRQ_REL_PTR(ptr);
|
||||
const UCHAR* p = events + 1;
|
||||
const UCHAR* const end = events + events_length;
|
||||
bool flag = false;
|
||||
@ -462,17 +464,17 @@ SLONG EVENT_que(ISC_STATUS* status_vector,
|
||||
if (!event) {
|
||||
event =
|
||||
make_event(len, reinterpret_cast<const char*>(p), parent_offset);
|
||||
parent = (EVNT) ABS_PTR(parent_offset);
|
||||
session = (SES) ABS_PTR(session_id);
|
||||
request = (EVT_REQ) ABS_PTR(request_offset);
|
||||
ptr = (PTR *) ABS_PTR(ptr_offset);
|
||||
parent = (EVNT) SRQ_ABS_PTR(parent_offset);
|
||||
session = (SES) SRQ_ABS_PTR(session_id);
|
||||
request = (EVT_REQ) SRQ_ABS_PTR(request_offset);
|
||||
ptr = (SRQ_PTR *) SRQ_ABS_PTR(ptr_offset);
|
||||
}
|
||||
p += count;
|
||||
const SLONG event_offset = REL_PTR(event);
|
||||
const SLONG event_offset = SRQ_REL_PTR(event);
|
||||
RINT interest, prior;
|
||||
if (interest = historical_interest(session, event_offset)) {
|
||||
for (PTR* ptr2 = &session->ses_interests;
|
||||
*ptr2 && (prior = (RINT) ABS_PTR(*ptr2));
|
||||
for (SRQ_PTR* ptr2 = &session->ses_interests;
|
||||
*ptr2 && (prior = (RINT) SRQ_ABS_PTR(*ptr2));
|
||||
ptr2 = &prior->rint_next)
|
||||
{
|
||||
if (prior == interest) {
|
||||
@ -485,18 +487,18 @@ SLONG EVENT_que(ISC_STATUS* status_vector,
|
||||
else {
|
||||
interest =
|
||||
(RINT) alloc_global(type_rint, (SLONG) sizeof(req_int), false);
|
||||
event = (EVNT) ABS_PTR(event_offset);
|
||||
event = (EVNT) SRQ_ABS_PTR(event_offset);
|
||||
insert_tail(&event->evnt_interests, &interest->rint_interests);
|
||||
interest->rint_event = event_offset;
|
||||
|
||||
parent = (EVNT) ABS_PTR(parent_offset);
|
||||
request = (EVT_REQ) ABS_PTR(request_offset);
|
||||
ptr = (PTR *) ABS_PTR(ptr_offset);
|
||||
session = (SES) ABS_PTR(session_id);
|
||||
parent = (EVNT) SRQ_ABS_PTR(parent_offset);
|
||||
request = (EVT_REQ) SRQ_ABS_PTR(request_offset);
|
||||
ptr = (SRQ_PTR *) SRQ_ABS_PTR(ptr_offset);
|
||||
session = (SES) SRQ_ABS_PTR(session_id);
|
||||
}
|
||||
*ptr = REL_PTR(interest);
|
||||
*ptr = SRQ_REL_PTR(interest);
|
||||
ptr = &interest->rint_next;
|
||||
ptr_offset = REL_PTR(ptr);
|
||||
ptr_offset = SRQ_REL_PTR(ptr);
|
||||
interest->rint_request = request_offset;
|
||||
interest->rint_count = gds__vax_integer(p, 4);
|
||||
p += 4;
|
||||
@ -505,9 +507,9 @@ SLONG EVENT_que(ISC_STATUS* status_vector,
|
||||
}
|
||||
|
||||
if (flag)
|
||||
post_process((PRB) ABS_PTR(EVENT_process_offset));
|
||||
post_process((PRB) SRQ_ABS_PTR(EVENT_process_offset));
|
||||
|
||||
RELEASE;
|
||||
release();
|
||||
return_ok(status_vector);
|
||||
|
||||
return id;
|
||||
@ -554,18 +556,18 @@ static EVH acquire(void)
|
||||
* platforms. Postponed for now. B.Sriram, 10-Jul-1997
|
||||
*/
|
||||
|
||||
PRB process = (PRB) ABS_PTR(EVENT_process_offset);
|
||||
PRB process = (PRB) SRQ_ABS_PTR(EVENT_process_offset);
|
||||
process->prb_flags |= PRB_remap;
|
||||
event_t* event = process->prb_event;
|
||||
|
||||
post_process(process);
|
||||
|
||||
while (true) {
|
||||
RELEASE;
|
||||
release();
|
||||
Sleep(3);
|
||||
ACQUIRE;
|
||||
acquire();
|
||||
|
||||
process = (PRB) ABS_PTR(EVENT_process_offset);
|
||||
process = (PRB) SRQ_ABS_PTR(EVENT_process_offset);
|
||||
if (!(process->prb_flags & PRB_remap))
|
||||
break;
|
||||
}
|
||||
@ -577,14 +579,14 @@ static EVH acquire(void)
|
||||
header = (evh*) ISC_remap_file(status_vector, &EVENT_data, length, false);
|
||||
#endif
|
||||
if (!header) {
|
||||
RELEASE;
|
||||
release();
|
||||
gds__log("acquire: Event table remap failed");
|
||||
exit(FINI_ERROR);
|
||||
}
|
||||
EVENT_header = header;
|
||||
|
||||
#ifdef WIN_NT
|
||||
process = (PRB) ABS_PTR(EVENT_process_offset);
|
||||
process = (PRB) SRQ_ABS_PTR(EVENT_process_offset);
|
||||
process->prb_flags &= ~PRB_remap_over;
|
||||
#endif /* WIN_NT */
|
||||
}
|
||||
@ -605,14 +607,14 @@ static FRB alloc_global(UCHAR type, ULONG length, bool recurse)
|
||||
* Allocate a block in shared global region.
|
||||
*
|
||||
**************************************/
|
||||
PTR *ptr;
|
||||
SRQ_PTR *ptr;
|
||||
FRB free;
|
||||
SLONG best_tail = MAX_SLONG;
|
||||
|
||||
length = ROUNDUP(length, sizeof(IPTR));
|
||||
PTR* best = NULL;
|
||||
SRQ_PTR* best = NULL;
|
||||
|
||||
for (ptr = &EVENT_header->evh_free; (free = (FRB) ABS_PTR(*ptr)) && *ptr;
|
||||
for (ptr = &EVENT_header->evh_free; (free = (FRB) SRQ_ABS_PTR(*ptr)) && *ptr;
|
||||
ptr = &free->frb_next)
|
||||
{
|
||||
const SLONG tail = free->frb_header.hdr_length - length;
|
||||
@ -633,19 +635,19 @@ static FRB alloc_global(UCHAR type, ULONG length, bool recurse)
|
||||
* to remap.
|
||||
*/
|
||||
|
||||
PRB process = (PRB) ABS_PTR(EVENT_process_offset);
|
||||
PRB process = (PRB) SRQ_ABS_PTR(EVENT_process_offset);
|
||||
process->prb_flags |= PRB_remap;
|
||||
event_t* event = process->prb_event;
|
||||
post_process(process);
|
||||
|
||||
while (true) {
|
||||
RELEASE;
|
||||
release();
|
||||
THREAD_EXIT;
|
||||
Sleep(3);
|
||||
THREAD_ENTER;
|
||||
ACQUIRE;
|
||||
acquire();
|
||||
|
||||
process = (PRB) ABS_PTR(EVENT_process_offset);
|
||||
process = (PRB) SRQ_ABS_PTR(EVENT_process_offset);
|
||||
if (!(process->prb_flags & PRB_remap))
|
||||
break;
|
||||
}
|
||||
@ -674,7 +676,7 @@ static FRB alloc_global(UCHAR type, ULONG length, bool recurse)
|
||||
free_global(free);
|
||||
|
||||
#ifdef WIN_NT
|
||||
process = (PRB) ABS_PTR(EVENT_process_offset);
|
||||
process = (PRB) SRQ_ABS_PTR(EVENT_process_offset);
|
||||
process->prb_flags &= ~PRB_remap_over;
|
||||
#endif /* WIN_NT */
|
||||
|
||||
@ -683,12 +685,12 @@ static FRB alloc_global(UCHAR type, ULONG length, bool recurse)
|
||||
}
|
||||
|
||||
if (!best) {
|
||||
RELEASE;
|
||||
release();
|
||||
gds__log("alloc_global: Event table space exhausted");
|
||||
exit(FINI_ERROR);
|
||||
}
|
||||
|
||||
free = (FRB) ABS_PTR(*best);
|
||||
free = (FRB) SRQ_ABS_PTR(*best);
|
||||
|
||||
if (best_tail < (SLONG) sizeof(frb))
|
||||
*best = free->frb_next;
|
||||
@ -721,11 +723,11 @@ static SLONG create_process(void)
|
||||
if (EVENT_process_offset)
|
||||
return EVENT_process_offset;
|
||||
|
||||
ACQUIRE;
|
||||
acquire();
|
||||
PRB process = (PRB) alloc_global(type_prb, (SLONG) sizeof(prb), false);
|
||||
insert_tail(&EVENT_header->evh_processes, &process->prb_processes);
|
||||
QUE_INIT(process->prb_sessions);
|
||||
EVENT_process_offset = REL_PTR(process);
|
||||
SRQ_INIT(process->prb_sessions);
|
||||
EVENT_process_offset = SRQ_REL_PTR(process);
|
||||
|
||||
#ifdef MULTI_THREAD
|
||||
|
||||
@ -745,7 +747,7 @@ static SLONG create_process(void)
|
||||
process->prb_process_id = getpid();
|
||||
|
||||
probe_processes();
|
||||
RELEASE;
|
||||
release();
|
||||
|
||||
#ifdef MULTI_THREAD
|
||||
if (gds__thread_start
|
||||
@ -773,7 +775,7 @@ static void delete_event(EVNT event)
|
||||
remove_que(&event->evnt_events);
|
||||
|
||||
if (event->evnt_parent) {
|
||||
EVNT parent = (EVNT) ABS_PTR(event->evnt_parent);
|
||||
EVNT parent = (EVNT) SRQ_ABS_PTR(event->evnt_parent);
|
||||
if (!--parent->evnt_count)
|
||||
delete_event(parent);
|
||||
}
|
||||
@ -794,15 +796,15 @@ static void delete_process(SLONG process_offset)
|
||||
* Delete a process block including friends and relations.
|
||||
*
|
||||
**************************************/
|
||||
PRB process = (PRB) ABS_PTR(process_offset);
|
||||
PRB process = (PRB) SRQ_ABS_PTR(process_offset);
|
||||
|
||||
/* Delete any open sessions */
|
||||
|
||||
while (!QUE_EMPTY(process->prb_sessions)) {
|
||||
while (!SRQ_EMPTY(process->prb_sessions)) {
|
||||
SES session =
|
||||
(SES) ((UCHAR *) QUE_NEXT(process->prb_sessions) -
|
||||
(SES) ((UCHAR *) SRQ_NEXT(process->prb_sessions) -
|
||||
OFFSET(SES, ses_sessions));
|
||||
delete_session(REL_PTR(session));
|
||||
delete_session(SRQ_REL_PTR(session));
|
||||
}
|
||||
|
||||
/* Untangle and release process block */
|
||||
@ -824,14 +826,14 @@ static void delete_process(SLONG process_offset)
|
||||
while (process->prb_flags & PRB_exiting && !timeout) {
|
||||
ISC_event_post(process->prb_event);
|
||||
SLONG value = ISC_event_clear(process->prb_event);
|
||||
RELEASE;
|
||||
release();
|
||||
#ifdef SOLARIS_MT
|
||||
event_t* events = EVENT_process->prb_event;
|
||||
#else
|
||||
event_t* events = process->prb_event;
|
||||
#endif
|
||||
timeout = ISC_event_wait(1, &events, &value, 5 * 1000000, 0, 0);
|
||||
ACQUIRE;
|
||||
acquire();
|
||||
}
|
||||
EVENT_process_offset = 0;
|
||||
#endif
|
||||
@ -851,10 +853,10 @@ static void delete_request(EVT_REQ request)
|
||||
* Release an unwanted and unloved request.
|
||||
*
|
||||
**************************************/
|
||||
SES session = (SES) ABS_PTR(request->req_session);
|
||||
SES session = (SES) SRQ_ABS_PTR(request->req_session);
|
||||
|
||||
while (request->req_interests) {
|
||||
RINT interest = (RINT) ABS_PTR(request->req_interests);
|
||||
RINT interest = (RINT) SRQ_ABS_PTR(request->req_interests);
|
||||
|
||||
request->req_interests = interest->rint_next;
|
||||
if (historical_interest(session, interest->rint_event)) {
|
||||
@ -863,8 +865,8 @@ static void delete_request(EVT_REQ request)
|
||||
}
|
||||
else {
|
||||
interest->rint_next = session->ses_interests;
|
||||
session->ses_interests = REL_PTR(interest);
|
||||
interest->rint_request = (PTR)0;
|
||||
session->ses_interests = SRQ_REL_PTR(interest);
|
||||
interest->rint_request = (SRQ_PTR)0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -894,14 +896,14 @@ static void delete_session(SLONG session_id)
|
||||
/* (Generally means session's deliver is hung. */
|
||||
#endif
|
||||
|
||||
SES session = (SES) ABS_PTR(session_id);
|
||||
SES session = (SES) SRQ_ABS_PTR(session_id);
|
||||
|
||||
#ifdef MULTI_THREAD
|
||||
/* delay gives up control for 250ms, so a 40 iteration timeout is a
|
||||
* up to 10 second wait for session to finish delivering its message.
|
||||
*/
|
||||
while (session->ses_flags & SES_delivering && (++kill_anyway != 40)) {
|
||||
RELEASE;
|
||||
release();
|
||||
THREAD_EXIT;
|
||||
#ifdef WIN_NT
|
||||
Sleep(250);
|
||||
@ -910,29 +912,29 @@ static void delete_session(SLONG session_id)
|
||||
sleep(1);
|
||||
#endif
|
||||
THREAD_ENTER;
|
||||
ACQUIRE;
|
||||
session = (SES) ABS_PTR(session_id);
|
||||
acquire();
|
||||
session = (SES) SRQ_ABS_PTR(session_id);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Delete all requests */
|
||||
|
||||
while (!QUE_EMPTY(session->ses_requests)) {
|
||||
SRQ requests = session->ses_requests;
|
||||
while (!SRQ_EMPTY(session->ses_requests)) {
|
||||
srq requests = session->ses_requests;
|
||||
EVT_REQ request =
|
||||
(EVT_REQ) ((UCHAR *) QUE_NEXT(requests) - OFFSET(EVT_REQ, req_requests));
|
||||
(EVT_REQ) ((UCHAR *) SRQ_NEXT(requests) - OFFSET(EVT_REQ, req_requests));
|
||||
delete_request(request);
|
||||
}
|
||||
|
||||
/* Delete any historical interests */
|
||||
|
||||
while (session->ses_interests) {
|
||||
RINT interest = (RINT) ABS_PTR(session->ses_interests);
|
||||
EVNT event = (EVNT) ABS_PTR(interest->rint_event);
|
||||
RINT interest = (RINT) SRQ_ABS_PTR(session->ses_interests);
|
||||
EVNT event = (EVNT) SRQ_ABS_PTR(interest->rint_event);
|
||||
session->ses_interests = interest->rint_next;
|
||||
remove_que(&interest->rint_interests);
|
||||
free_global((FRB) interest);
|
||||
if (QUE_EMPTY(event->evnt_interests))
|
||||
if (SRQ_EMPTY(event->evnt_interests))
|
||||
delete_event(event);
|
||||
}
|
||||
|
||||
@ -953,33 +955,33 @@ static AST_TYPE deliver(void* arg)
|
||||
* We've been poked -- deliver any satisfying requests.
|
||||
*
|
||||
**************************************/
|
||||
SRQ *que, *que2;
|
||||
srq *event_srq, *que2;
|
||||
|
||||
#ifdef UNIX
|
||||
if (acquire_count)
|
||||
return;
|
||||
#endif
|
||||
|
||||
ACQUIRE;
|
||||
PRB process = (PRB) ABS_PTR(EVENT_process_offset);
|
||||
acquire();
|
||||
PRB process = (PRB) SRQ_ABS_PTR(EVENT_process_offset);
|
||||
process->prb_flags &= ~PRB_pending;
|
||||
|
||||
QUE_LOOP(process->prb_sessions, que2) {
|
||||
SRQ_LOOP(process->prb_sessions, que2) {
|
||||
SES session = (SES) ((UCHAR *) que2 - OFFSET(SES, ses_sessions));
|
||||
#ifdef MULTI_THREAD
|
||||
session->ses_flags |= SES_delivering;
|
||||
#endif
|
||||
const SLONG session_offset = REL_PTR(session);
|
||||
const SLONG que2_offset = REL_PTR(que2);
|
||||
const SLONG session_offset = SRQ_REL_PTR(session);
|
||||
const SLONG que2_offset = SRQ_REL_PTR(que2);
|
||||
for (bool flag = true; flag;) {
|
||||
flag = false;
|
||||
QUE_LOOP(session->ses_requests, que) {
|
||||
EVT_REQ request = (EVT_REQ) ((UCHAR *) que - OFFSET(EVT_REQ, req_requests));
|
||||
SRQ_LOOP(session->ses_requests, event_srq) {
|
||||
EVT_REQ request = (EVT_REQ) ((UCHAR *) event_srq - OFFSET(EVT_REQ, req_requests));
|
||||
if (request_completed(request)) {
|
||||
deliver_request(request);
|
||||
process = (PRB) ABS_PTR(EVENT_process_offset);
|
||||
session = (SES) ABS_PTR(session_offset);
|
||||
que2 = (SRQ *) ABS_PTR(que2_offset);
|
||||
process = (PRB) SRQ_ABS_PTR(EVENT_process_offset);
|
||||
session = (SES) SRQ_ABS_PTR(session_offset);
|
||||
que2 = (srq *) SRQ_ABS_PTR(que2_offset);
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
@ -990,7 +992,7 @@ static AST_TYPE deliver(void* arg)
|
||||
#endif
|
||||
}
|
||||
|
||||
RELEASE;
|
||||
release();
|
||||
}
|
||||
|
||||
|
||||
@ -1020,12 +1022,12 @@ static void deliver_request(EVT_REQ request)
|
||||
stuff */
|
||||
|
||||
RINT interest;
|
||||
for (PTR next = request->req_interests;
|
||||
next && (interest = (RINT) ABS_PTR(next));
|
||||
for (SRQ_PTR next = request->req_interests;
|
||||
next && (interest = (RINT) SRQ_ABS_PTR(next));
|
||||
next = interest->rint_next)
|
||||
{
|
||||
interest = (RINT) ABS_PTR(next);
|
||||
EVNT event = (EVNT) ABS_PTR(interest->rint_event);
|
||||
interest = (RINT) SRQ_ABS_PTR(next);
|
||||
EVNT event = (EVNT) SRQ_ABS_PTR(interest->rint_event);
|
||||
if (end < p + event->evnt_length + 5)
|
||||
{
|
||||
/* Running out of space - allocate some more and copy it over */
|
||||
@ -1056,13 +1058,13 @@ static void deliver_request(EVT_REQ request)
|
||||
}
|
||||
|
||||
delete_request(request);
|
||||
RELEASE;
|
||||
release();
|
||||
(*ast)(arg, p - event_buffer, event_buffer);
|
||||
if (event_buffer != buffer)
|
||||
{
|
||||
gds__free(event_buffer);
|
||||
}
|
||||
ACQUIRE;
|
||||
acquire();
|
||||
}
|
||||
|
||||
|
||||
@ -1080,13 +1082,13 @@ static void exit_handler(void* arg)
|
||||
**************************************/
|
||||
if (EVENT_process_offset) {
|
||||
if (EVENT_header->evh_current_process != EVENT_process_offset)
|
||||
ACQUIRE;
|
||||
acquire();
|
||||
delete_process(EVENT_process_offset);
|
||||
RELEASE;
|
||||
release();
|
||||
}
|
||||
|
||||
while (acquire_count > 0)
|
||||
RELEASE;
|
||||
release();
|
||||
|
||||
ISC_STATUS_ARRAY local_status;
|
||||
|
||||
@ -1114,12 +1116,12 @@ static EVNT find_event(USHORT length, const TEXT* string, EVNT parent)
|
||||
* Lookup an event.
|
||||
*
|
||||
**************************************/
|
||||
SRQ* que;
|
||||
srq* event_srq;
|
||||
|
||||
PTR parent_offset = (parent) ? REL_PTR(parent) : 0;
|
||||
SRQ_PTR parent_offset = (parent) ? SRQ_REL_PTR(parent) : 0;
|
||||
|
||||
QUE_LOOP(EVENT_header->evh_events, que) {
|
||||
EVNT event = (EVNT) ((UCHAR *) que - OFFSET(EVNT, evnt_events));
|
||||
SRQ_LOOP(EVENT_header->evh_events, event_srq) {
|
||||
EVNT event = (EVNT) ((UCHAR *) event_srq - OFFSET(EVNT, evnt_events));
|
||||
if (event->evnt_parent == parent_offset &&
|
||||
event->evnt_length == length &&
|
||||
!memcmp(string, event->evnt_name, length))
|
||||
@ -1144,14 +1146,14 @@ static void free_global(FRB block)
|
||||
* Free a previous allocated block.
|
||||
*
|
||||
**************************************/
|
||||
PTR *ptr;
|
||||
SRQ_PTR *ptr;
|
||||
FRB free;
|
||||
|
||||
FRB prior = NULL;
|
||||
PTR offset = REL_PTR(block);
|
||||
SRQ_PTR offset = SRQ_REL_PTR(block);
|
||||
block->frb_header.hdr_type = type_frb;
|
||||
|
||||
for (ptr = &EVENT_header->evh_free; (free = (FRB) ABS_PTR(*ptr)) && *ptr;
|
||||
for (ptr = &EVENT_header->evh_free; (free = (FRB) SRQ_ABS_PTR(*ptr)) && *ptr;
|
||||
prior = free, ptr = &free->frb_next)
|
||||
{
|
||||
if ((SCHAR *) block < (SCHAR *) free)
|
||||
@ -1189,7 +1191,7 @@ static void free_global(FRB block)
|
||||
}
|
||||
|
||||
|
||||
static RINT historical_interest(SES session, PTR event)
|
||||
static RINT historical_interest(SES session, SRQ_PTR event)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -1203,8 +1205,8 @@ static RINT historical_interest(SES session, PTR event)
|
||||
**************************************/
|
||||
RINT interest;
|
||||
|
||||
for (PTR ptr = session->ses_interests;
|
||||
ptr && (interest = (RINT) ABS_PTR(ptr)); ptr = interest->rint_next)
|
||||
for (SRQ_PTR ptr = session->ses_interests;
|
||||
ptr && (interest = (RINT) SRQ_ABS_PTR(ptr)); ptr = interest->rint_next)
|
||||
{
|
||||
if (interest->rint_event == event)
|
||||
return interest;
|
||||
@ -1240,8 +1242,8 @@ static void init(void* arg, SH_MEM shmem_data, bool initialize)
|
||||
EVENT_header->evh_length = EVENT_data.sh_mem_length_mapped;
|
||||
EVENT_header->evh_version = EVENT_VERSION;
|
||||
EVENT_header->evh_request_id = 0;
|
||||
QUE_INIT(EVENT_header->evh_processes);
|
||||
QUE_INIT(EVENT_header->evh_events);
|
||||
SRQ_INIT(EVENT_header->evh_processes);
|
||||
SRQ_INIT(EVENT_header->evh_events);
|
||||
|
||||
#ifndef SERVER
|
||||
#if !defined(WIN_NT)
|
||||
@ -1260,7 +1262,7 @@ static void init(void* arg, SH_MEM shmem_data, bool initialize)
|
||||
}
|
||||
|
||||
|
||||
static void insert_tail(SRQ * que, SRQ * node)
|
||||
static void insert_tail(srq * event_srq, srq * node)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -1269,15 +1271,15 @@ static void insert_tail(SRQ * que, SRQ * node)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Insert a node at the tail of a que.
|
||||
* Insert a node at the tail of a event_srq.
|
||||
*
|
||||
**************************************/
|
||||
node->srq_forward = REL_PTR(que);
|
||||
node->srq_backward = que->srq_backward;
|
||||
node->srq_forward = SRQ_REL_PTR(event_srq);
|
||||
node->srq_backward = event_srq->srq_backward;
|
||||
|
||||
SRQ* prior = (SRQ *) ABS_PTR(que->srq_backward);
|
||||
prior->srq_forward = REL_PTR(node);
|
||||
que->srq_backward = REL_PTR(node);
|
||||
srq* prior = (srq *) SRQ_ABS_PTR(event_srq->srq_backward);
|
||||
prior->srq_forward = SRQ_REL_PTR(node);
|
||||
event_srq->srq_backward = SRQ_REL_PTR(node);
|
||||
}
|
||||
|
||||
|
||||
@ -1296,11 +1298,11 @@ static EVNT make_event(USHORT length, const TEXT* string, SLONG parent_offset)
|
||||
EVNT event =
|
||||
(EVNT) alloc_global(type_evnt, (SLONG) (sizeof(evnt) + length), false);
|
||||
insert_tail(&EVENT_header->evh_events, &event->evnt_events);
|
||||
QUE_INIT(event->evnt_interests);
|
||||
SRQ_INIT(event->evnt_interests);
|
||||
|
||||
if (parent_offset) {
|
||||
event->evnt_parent = parent_offset;
|
||||
EVNT parent = (EVNT) ABS_PTR(parent_offset);
|
||||
EVNT parent = (EVNT) SRQ_ABS_PTR(parent_offset);
|
||||
++parent->evnt_count;
|
||||
}
|
||||
|
||||
@ -1349,7 +1351,7 @@ static void post_process(PRB process)
|
||||
|
||||
process->prb_flags &= ~PRB_wakeup;
|
||||
process->prb_flags |= PRB_pending;
|
||||
RELEASE;
|
||||
release();
|
||||
|
||||
#ifdef SERVER
|
||||
deliver();
|
||||
@ -1360,12 +1362,12 @@ static void post_process(PRB process)
|
||||
#else
|
||||
|
||||
#ifdef UNIX
|
||||
if (REL_PTR(process) != EVENT_process_offset)
|
||||
if (SRQ_REL_PTR(process) != EVENT_process_offset)
|
||||
ISC_kill(process->prb_process_id, EVENT_SIGNAL);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
ACQUIRE;
|
||||
acquire();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1383,16 +1385,16 @@ static void probe_processes(void)
|
||||
* rid of it.
|
||||
*
|
||||
**************************************/
|
||||
SRQ* que;
|
||||
srq* event_srq;
|
||||
|
||||
QUE_LOOP(EVENT_header->evh_processes, que) {
|
||||
PRB process = (PRB) ((UCHAR *) que - OFFSET(PRB, prb_processes));
|
||||
const SLONG process_offset = REL_PTR(process);
|
||||
SRQ_LOOP(EVENT_header->evh_processes, event_srq) {
|
||||
PRB process = (PRB) ((UCHAR *) event_srq - OFFSET(PRB, prb_processes));
|
||||
const SLONG process_offset = SRQ_REL_PTR(process);
|
||||
if (process_offset != EVENT_process_offset &&
|
||||
!ISC_check_process_existence(process->prb_process_id,
|
||||
process->prb_process_uid[0], false))
|
||||
{
|
||||
que = (SRQ *) ABS_PTR(que->srq_backward);
|
||||
event_srq = (srq *) SRQ_ABS_PTR(event_srq->srq_backward);
|
||||
delete_process(process_offset);
|
||||
}
|
||||
}
|
||||
@ -1446,7 +1448,7 @@ static void release(void)
|
||||
#endif
|
||||
#ifdef UNIX
|
||||
if (EVENT_process_offset) {
|
||||
PRB process = (PRB) ABS_PTR(EVENT_process_offset);
|
||||
PRB process = (PRB) SRQ_ABS_PTR(EVENT_process_offset);
|
||||
if (process->prb_flags & PRB_pending)
|
||||
ISC_kill(process->prb_process_id, EVENT_SIGNAL);
|
||||
}
|
||||
@ -1456,7 +1458,7 @@ static void release(void)
|
||||
}
|
||||
|
||||
|
||||
static void remove_que(SRQ* node)
|
||||
static void remove_que(srq* node)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -1465,14 +1467,14 @@ static void remove_que(SRQ* node)
|
||||
**************************************
|
||||
*
|
||||
* Functional description
|
||||
* Remove a node from a self-relative que.
|
||||
* Remove a node from a self-relative event_srq.
|
||||
*
|
||||
**************************************/
|
||||
SRQ* que = (SRQ *) ABS_PTR(node->srq_forward);
|
||||
que->srq_backward = node->srq_backward;
|
||||
srq* event_srq = (srq *) SRQ_ABS_PTR(node->srq_forward);
|
||||
event_srq->srq_backward = node->srq_backward;
|
||||
|
||||
que = (SRQ *) ABS_PTR(node->srq_backward);
|
||||
que->srq_forward = node->srq_forward;
|
||||
event_srq = (srq *) SRQ_ABS_PTR(node->srq_backward);
|
||||
event_srq->srq_forward = node->srq_forward;
|
||||
node->srq_forward = node->srq_backward = 0;
|
||||
}
|
||||
|
||||
@ -1490,9 +1492,9 @@ static bool request_completed(EVT_REQ request)
|
||||
*
|
||||
**************************************/
|
||||
RINT interest;
|
||||
for (PTR next = request->req_interests; next; next = interest->rint_next) {
|
||||
interest = (RINT) ABS_PTR(next);
|
||||
EVNT event = (EVNT) ABS_PTR(interest->rint_event);
|
||||
for (SRQ_PTR next = request->req_interests; next; next = interest->rint_next) {
|
||||
interest = (RINT) SRQ_ABS_PTR(next);
|
||||
EVNT event = (EVNT) SRQ_ABS_PTR(interest->rint_event);
|
||||
if (interest->rint_count <= event->evnt_count)
|
||||
return true;
|
||||
}
|
||||
@ -1537,13 +1539,13 @@ static int validate(void)
|
||||
**************************************/
|
||||
// Check consistency of global region (debugging only)
|
||||
|
||||
PTR next_free = 0;
|
||||
SRQ_PTR next_free = 0;
|
||||
SLONG offset;
|
||||
|
||||
for (offset = sizeof(evh); offset < EVENT_header->evh_length;
|
||||
offset += block->frb_header.hdr_length)
|
||||
{
|
||||
event_hdr* block = (event_hdr*) ABS_PTR(offset);
|
||||
event_hdr* block = (event_hdr*) SRQ_ABS_PTR(offset);
|
||||
if (!block->frb_header.hdr_length || !block->frb_header.hdr_type
|
||||
|| block->frb_header.hdr_type >= type_max)
|
||||
{
|
||||
@ -1582,40 +1584,40 @@ static void THREAD_ROUTINE watcher_thread(void *dummy)
|
||||
*
|
||||
**************************************/
|
||||
while (EVENT_process_offset) {
|
||||
ACQUIRE;
|
||||
PRB process = (PRB) ABS_PTR(EVENT_process_offset);
|
||||
acquire();
|
||||
PRB process = (PRB) SRQ_ABS_PTR(EVENT_process_offset);
|
||||
process->prb_flags &= ~PRB_wakeup;
|
||||
|
||||
if (process->prb_flags & PRB_exiting) {
|
||||
process->prb_flags &= ~PRB_exiting;
|
||||
ISC_event_post(process->prb_event);
|
||||
RELEASE;
|
||||
release();
|
||||
break;
|
||||
}
|
||||
#ifdef WIN_NT
|
||||
if (process->prb_flags & PRB_remap) {
|
||||
process->prb_flags |= PRB_remap_over;
|
||||
process->prb_flags &= ~PRB_remap;
|
||||
RELEASE;
|
||||
release();
|
||||
while (true) {
|
||||
Sleep(3);
|
||||
ACQUIRE;
|
||||
process = (PRB) ABS_PTR(EVENT_process_offset);
|
||||
RELEASE;
|
||||
acquire();
|
||||
process = (PRB) SRQ_ABS_PTR(EVENT_process_offset);
|
||||
release();
|
||||
if (!(process->prb_flags & PRB_remap_over))
|
||||
break;
|
||||
}
|
||||
ACQUIRE;
|
||||
process = (PRB) ABS_PTR(EVENT_process_offset);
|
||||
acquire();
|
||||
process = (PRB) SRQ_ABS_PTR(EVENT_process_offset);
|
||||
}
|
||||
#endif
|
||||
|
||||
SLONG value = ISC_event_clear(process->prb_event);
|
||||
RELEASE;
|
||||
release();
|
||||
deliver(NULL);
|
||||
ACQUIRE;
|
||||
process = (PRB) ABS_PTR(EVENT_process_offset);
|
||||
RELEASE;
|
||||
acquire();
|
||||
process = (PRB) SRQ_ABS_PTR(EVENT_process_offset);
|
||||
release();
|
||||
#ifdef SOLARIS_MT
|
||||
event_t* events = EVENT_process->prb_event;
|
||||
#else
|
||||
|
@ -32,33 +32,11 @@
|
||||
|
||||
#include "../jrd/isc.h"
|
||||
#include "../jrd/file_params.h"
|
||||
|
||||
#define PTR SLONG
|
||||
#define BASE ((UCHAR *) EVENT_header)
|
||||
#define REL_PTR(item) ((UCHAR *) item - BASE)
|
||||
#define ABS_PTR(item) (BASE + item)
|
||||
#define ACQUIRE acquire()
|
||||
#define RELEASE release()
|
||||
|
||||
#define QUE_INIT(que) {que.srq_forward = que.srq_backward = REL_PTR (&que);}
|
||||
#define QUE_EMPTY(que) (que.srq_forward == REL_PTR (&que))
|
||||
#define QUE_NEXT(que) ABS_PTR (que.srq_forward)
|
||||
#define QUE_PREV(que) ABS_PTR (que.srq_backward)
|
||||
|
||||
#define QUE_LOOP(header,que) for (que = (SRQ*) QUE_NEXT (header);\
|
||||
que != &header; que = (SRQ*) QUE_NEXT ((*que)))
|
||||
|
||||
#include "../jrd/que.h"
|
||||
|
||||
const int SIZE_SHIFT = 2;
|
||||
const int FAST_ALLOC = 16;
|
||||
|
||||
/* Self-relative que block. Offsets are from the block itself. */
|
||||
|
||||
typedef struct srq {
|
||||
PTR srq_forward; /* Forward offset */
|
||||
PTR srq_backward; /* Backward offset */
|
||||
} SRQ;
|
||||
|
||||
/* Global section header */
|
||||
|
||||
const int EVH_HASH_SIZE = 7;
|
||||
@ -66,13 +44,13 @@ const int EVH_HASH_SIZE = 7;
|
||||
typedef struct evh {
|
||||
SLONG evh_length; /* Current length of global section */
|
||||
UCHAR evh_version; /* Version number of global section */
|
||||
SRQ evh_events; /* Known processes */
|
||||
SRQ evh_processes; /* Known processes */
|
||||
PTR evh_free; /* Free blocks */
|
||||
PTR evh_current_process; /* Current process, if any */
|
||||
srq evh_events; /* Known processes */
|
||||
srq evh_processes; /* Known processes */
|
||||
SRQ_PTR evh_free; /* Free blocks */
|
||||
SRQ_PTR evh_current_process; /* Current process, if any */
|
||||
MTX_T evh_mutex[1]; /* Mutex controlling access */
|
||||
SLONG evh_request_id; /* Next request id */
|
||||
PTR evh_hash_table[EVH_HASH_SIZE];
|
||||
SRQ_PTR evh_hash_table[EVH_HASH_SIZE];
|
||||
} *EVH;
|
||||
|
||||
/* Common block header */
|
||||
@ -106,8 +84,8 @@ typedef frb *FRB;
|
||||
struct prb
|
||||
{
|
||||
event_hdr prb_header;
|
||||
SRQ prb_processes; /* Process que owned by header */
|
||||
SRQ prb_sessions; /* Sessions within process */
|
||||
srq prb_processes; /* Process que owned by header */
|
||||
srq prb_sessions; /* Sessions within process */
|
||||
SLONG prb_process_id; /* Process id */
|
||||
SLONG prb_process_uid[2]; /* Process UID (apollo) */
|
||||
event_t prb_event[1]; /* Event on which to wait */
|
||||
@ -125,26 +103,26 @@ const int PRB_exiting = 16; /* Process is exiting */
|
||||
|
||||
struct ses {
|
||||
event_hdr ses_header;
|
||||
SRQ ses_sessions; /* Sessions within process */
|
||||
SRQ ses_requests; /* Outstanding requests */
|
||||
PTR ses_interests; /* Historical interests */
|
||||
PTR ses_process; /* Parent process */
|
||||
srq ses_sessions; /* Sessions within process */
|
||||
srq ses_requests; /* Outstanding requests */
|
||||
SRQ_PTR ses_interests; /* Historical interests */
|
||||
SRQ_PTR ses_process; /* Parent process */
|
||||
#ifdef MULTI_THREAD
|
||||
USHORT ses_flags;
|
||||
#endif
|
||||
};
|
||||
typedef ses *SES;
|
||||
|
||||
#define SES_delivering 1 /* Watcher thread is delivering an event */
|
||||
const int SES_delivering = 1; /* Watcher thread is delivering an event */
|
||||
|
||||
/* Event block */
|
||||
|
||||
struct evnt {
|
||||
event_hdr evnt_header;
|
||||
SRQ evnt_events; /* System event que (owned by header) */
|
||||
SRQ evnt_interests; /* Que of request interests in event */
|
||||
PTR evnt_hash_collision; /* Hash table collision pointer */
|
||||
PTR evnt_parent; /* Major event name */
|
||||
srq evnt_events; /* System event que (owned by header) */
|
||||
srq evnt_interests; /* Que of request interests in event */
|
||||
SRQ_PTR evnt_hash_collision; /* Hash table collision pointer */
|
||||
SRQ_PTR evnt_parent; /* Major event name */
|
||||
SLONG evnt_count; /* Current event count */
|
||||
USHORT evnt_length; /* Length of event name */
|
||||
TEXT evnt_name[1]; /* Event name */
|
||||
@ -155,10 +133,10 @@ typedef evnt *EVNT;
|
||||
|
||||
struct evt_req {
|
||||
event_hdr req_header;
|
||||
SRQ req_requests; /* Request que owned by session block */
|
||||
PTR req_process; /* Parent process block */
|
||||
PTR req_session; /* Parent session block */
|
||||
PTR req_interests; /* First interest in request */
|
||||
srq req_requests; /* Request que owned by session block */
|
||||
SRQ_PTR req_process; /* Parent process block */
|
||||
SRQ_PTR req_session; /* Parent session block */
|
||||
SRQ_PTR req_interests; /* First interest in request */
|
||||
FPTR_EVENT_CALLBACK req_ast; /* Asynchronous routine */
|
||||
void *req_ast_arg; /* Argument for ast */
|
||||
SLONG req_request_id; /* Request id, dummy */
|
||||
@ -169,10 +147,10 @@ typedef evt_req *EVT_REQ;
|
||||
|
||||
struct req_int {
|
||||
event_hdr rint_header;
|
||||
SRQ rint_interests; /* Que owned by event */
|
||||
PTR rint_event; /* Event of interest */
|
||||
PTR rint_request; /* Request of interest */
|
||||
PTR rint_next; /* Next interest of request */
|
||||
srq rint_interests; /* Que owned by event */
|
||||
SRQ_PTR rint_event; /* Event of interest */
|
||||
SRQ_PTR rint_request; /* Request of interest */
|
||||
SRQ_PTR rint_next; /* Next interest of request */
|
||||
SLONG rint_count; /* Threshhold count */
|
||||
};
|
||||
typedef req_int *RINT;
|
||||
|
@ -835,14 +835,6 @@ typedef vcl* VCL;
|
||||
#define TEST_VECTOR(vector,number) ((vector && number < vector->vec_count) ? \
|
||||
vector->vec_object [number] : NULL)
|
||||
|
||||
//
|
||||
// general purpose queue
|
||||
//
|
||||
typedef struct que {
|
||||
struct que* que_forward;
|
||||
struct que* que_backward;
|
||||
} *QUE;
|
||||
|
||||
|
||||
//
|
||||
// Transaction element block
|
||||
@ -862,32 +854,6 @@ class BlockingThread : public pool_alloc<type_btb>
|
||||
thread* btb_thread_id;
|
||||
};
|
||||
|
||||
/* Lock levels */
|
||||
|
||||
const int LCK_none = 0;
|
||||
const int LCK_null = 1;
|
||||
const int LCK_SR = 2;
|
||||
const int LCK_PR = 3;
|
||||
const int LCK_SW = 4;
|
||||
const int LCK_PW = 5;
|
||||
const int LCK_EX = 6;
|
||||
|
||||
const int LCK_read = LCK_PR;
|
||||
const int LCK_write = LCK_EX;
|
||||
|
||||
const int LCK_WAIT = TRUE;
|
||||
const int LCK_NO_WAIT = FALSE;
|
||||
|
||||
/* Lock query data aggregates */
|
||||
|
||||
const int LCK_MIN = 1;
|
||||
const int LCK_MAX = 2;
|
||||
const int LCK_CNT = 3;
|
||||
const int LCK_SUM = 4;
|
||||
const int LCK_AVG = 5;
|
||||
const int LCK_ANY = 6;
|
||||
|
||||
|
||||
/* Window block for loading cached pages into */
|
||||
// CVC: Apparently, the only possible values are HEADER_PAGE==0 and LOG_PAGE==2
|
||||
// and reside in ods.h, although I watched a place with 1 and others with members
|
||||
@ -985,6 +951,8 @@ inline char* stringDup(MemoryPool& p, const char* s, int l)
|
||||
|
||||
} //namespace Jrd
|
||||
|
||||
/* Lock levels */
|
||||
#include "../lock/lock.h"
|
||||
|
||||
/* Random string block -- jack of all kludges */
|
||||
|
||||
|
@ -136,7 +136,6 @@ static const UCHAR compatibility[] = {
|
||||
/* EX */ 1, 1, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
#define LCK_max (LCK_EX + 1)
|
||||
#define COMPATIBLE(st1, st2) compatibility [st1 * LCK_max + st2]
|
||||
#define LOCK_HASH_SIZE 19
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
(que).que_backward = &(que);\
|
||||
(que).que_forward = &(que);}
|
||||
|
||||
|
||||
#define QUE_DELETE(node) {\
|
||||
(node).que_backward->que_forward = (node).que_forward;\
|
||||
(node).que_forward->que_backward = (node).que_backward;}
|
||||
@ -67,4 +68,37 @@
|
||||
QUE_DELETE (in_use_que);\
|
||||
QUE_APPEND (bcb->bcb_in_use, in_use_que);}
|
||||
|
||||
//
|
||||
// general purpose queue
|
||||
//
|
||||
namespace Jrd {
|
||||
|
||||
typedef struct que {
|
||||
struct que* que_forward;
|
||||
struct que* que_backward;
|
||||
} *QUE;
|
||||
|
||||
}
|
||||
// Self-referencing queue BASE should be defined in the source which includes this
|
||||
#define SRQ_PTR SLONG
|
||||
|
||||
#define SRQ_REL_PTR(item) (SRQ_PTR) ((UCHAR*) item - SRQ_BASE)
|
||||
#define SRQ_ABS_PTR(item) (SRQ_PTR) (SRQ_BASE + item)
|
||||
|
||||
#define SRQ_INIT(que) {que.srq_forward = que.srq_backward = SRQ_REL_PTR (&que);}
|
||||
#define SRQ_EMPTY(que) (que.srq_forward == SRQ_REL_PTR (&que))
|
||||
#define SRQ_NEXT(que) (srq*) SRQ_ABS_PTR (que.srq_forward)
|
||||
#define SRQ_PREV(que) (srq*) SRQ_ABS_PTR (que.srq_backward)
|
||||
|
||||
#define SRQ_LOOP(header,que) for (que = SRQ_NEXT (header);\
|
||||
que != &header; que = SRQ_NEXT ((*que)))
|
||||
|
||||
/* Self-relative que block. Offsets are from the block itself. */
|
||||
|
||||
typedef struct srq {
|
||||
SRQ_PTR srq_forward; /* Forward offset */
|
||||
SRQ_PTR srq_backward; /* Backward offset */
|
||||
} *SRQ;
|
||||
|
||||
|
||||
#endif /* JRD_QUE_H */
|
||||
|
File diff suppressed because it is too large
Load Diff
203
src/lock/lock.h
203
src/lock/lock.h
@ -54,9 +54,10 @@
|
||||
|
||||
#include "../jrd/common.h"
|
||||
#include "../jrd/file_params.h"
|
||||
#include "../jrd/que.h"
|
||||
|
||||
#ifdef WIN_NT
|
||||
#define DEFAULT_SIZE 32768
|
||||
#define DEFAULT_SIZE 32768
|
||||
#include "../jrd/isc_signal.h"
|
||||
#endif
|
||||
|
||||
@ -65,38 +66,25 @@
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_SIZE
|
||||
#define DEFAULT_SIZE 98304
|
||||
#define DEFAULT_SIZE 98304
|
||||
#endif
|
||||
|
||||
#ifndef EXTEND_SIZE
|
||||
#define EXTEND_SIZE 32768
|
||||
#endif
|
||||
|
||||
#ifdef SCO_UNIX
|
||||
#define SEMAPHORES 25
|
||||
#endif
|
||||
|
||||
#ifdef SINIXZ
|
||||
#define SEMAPHORES 25
|
||||
#endif
|
||||
|
||||
#ifndef SEMAPHORES
|
||||
#define SEMAPHORES 32
|
||||
#endif
|
||||
|
||||
#undef BASE
|
||||
#define BASE ((UCHAR*) LOCK_header)
|
||||
#define REL_PTR(item) (PTR) ((UCHAR*) item - BASE)
|
||||
#define ABS_PTR(item) (BASE + item)
|
||||
|
||||
#define QUE_INIT(que) {que.srq_forward = que.srq_backward = REL_PTR (&que);}
|
||||
#define QUE_EMPTY(que) (que.srq_forward == REL_PTR (&que))
|
||||
#define QUE_NEXT(que) (SRQ) ABS_PTR (que.srq_forward)
|
||||
|
||||
#define QUE_LOOP(header,que) for (que = QUE_NEXT (header);\
|
||||
que != &header; que = QUE_NEXT ((*que)))
|
||||
|
||||
#define PTR SLONG
|
||||
// not used
|
||||
//#ifdef SCO_UNIX
|
||||
//#define SEMAPHORES 25
|
||||
//#endif
|
||||
//
|
||||
//#ifdef SINIXZ
|
||||
//#define SEMAPHORES 25
|
||||
//#endif
|
||||
//
|
||||
//#ifndef SEMAPHORES
|
||||
//#define SEMAPHORES 32
|
||||
//#endif
|
||||
|
||||
/* Maximum lock series for gathering statistics
|
||||
and querying data */
|
||||
@ -114,37 +102,34 @@
|
||||
|
||||
/* Lock states */
|
||||
|
||||
#define LCK_none 0
|
||||
#define LCK_null 1
|
||||
#define LCK_SR 2 /* Shared Read */
|
||||
#define LCK_PR 3 /* Protected Read */
|
||||
#define LCK_SW 4 /* Shared Write */
|
||||
#define LCK_PW 5 /* Protected Write */
|
||||
#define LCK_EX 6 /* Exclusive */
|
||||
#define LCK_max 7
|
||||
#define LCK_none 0
|
||||
#define LCK_null 1
|
||||
#define LCK_SR 2 // Shared Read
|
||||
#define LCK_PR 3 // Protected Read
|
||||
#define LCK_SW 4 // Shared Write
|
||||
#define LCK_PW 5 // Protected Write
|
||||
#define LCK_EX 6 // Exclusive
|
||||
#define LCK_max 7
|
||||
|
||||
#define LCK_read LCK_PR
|
||||
#define LCK_write LCK_EX
|
||||
|
||||
#define LCK_WAIT TRUE
|
||||
#define LCK_NO_WAIT FALSE
|
||||
|
||||
/* Lock block types */
|
||||
|
||||
#define type_null 0
|
||||
#define type_lhb 1
|
||||
#define type_prb 2
|
||||
#define type_lrq 3
|
||||
#define type_lbl 4
|
||||
#define type_his 5
|
||||
#define type_smb 6
|
||||
#define type_shb 7
|
||||
#define type_own 8
|
||||
#define type_null 0
|
||||
#define type_lhb 1
|
||||
#define type_prb 2
|
||||
#define type_lrq 3
|
||||
#define type_lbl 4
|
||||
#define type_his 5
|
||||
#define type_smb 6
|
||||
#define type_shb 7
|
||||
#define type_own 8
|
||||
|
||||
#define type_MAX type_own
|
||||
|
||||
|
||||
|
||||
/* Self-relative que block. Offsets are from the block itself. */
|
||||
|
||||
typedef struct srq {
|
||||
PTR srq_forward; /* Forward offset */
|
||||
PTR srq_backward; /* Backward offset */
|
||||
} *SRQ;
|
||||
#define type_MAX type_own
|
||||
|
||||
|
||||
#define CLASSIC_LHB_VERSION 15 // Firebird 1.5
|
||||
@ -189,8 +174,8 @@ typedef struct srq {
|
||||
typedef struct lhb {
|
||||
UCHAR lhb_type; /* memory tag - always type_lbh */
|
||||
UCHAR lhb_version; /* Version of lock table */
|
||||
PTR lhb_secondary; /* Secondary lock header block */
|
||||
PTR lhb_active_owner; /* Active owner, if any */
|
||||
SRQ_PTR lhb_secondary; /* Secondary lock header block */
|
||||
SRQ_PTR lhb_active_owner; /* Active owner, if any */
|
||||
srq lhb_owners; /* Que of active owners */
|
||||
srq lhb_free_owners; /* Free owners blocks */
|
||||
srq lhb_free_locks; /* Free lock blocks */
|
||||
@ -200,10 +185,10 @@ typedef struct lhb {
|
||||
USHORT lhb_hash_slots; /* Number of hash slots allocated */
|
||||
USHORT lhb_flags; /* Miscellaneous info */
|
||||
MTX_T lhb_mutex[1]; /* Mutex controlling access */
|
||||
PTR lhb_manager; /* Lock manager owner block */
|
||||
PTR lhb_history;
|
||||
SRQ_PTR lhb_manager; /* Lock manager owner block */
|
||||
SRQ_PTR lhb_history;
|
||||
ULONG lhb_process_count; /* To give a unique id to each process attachment to the lock table */
|
||||
PTR lhb_mask; /* Semaphore mask block */
|
||||
SRQ_PTR lhb_mask; /* Semaphore mask block */
|
||||
ULONG lhb_scan_interval; /* Deadlock scan interval (secs) */
|
||||
ULONG lhb_acquire_spins;
|
||||
ULONG lhb_acquires;
|
||||
@ -243,10 +228,10 @@ typedef struct lhb {
|
||||
typedef struct shb {
|
||||
UCHAR shb_type; /* memory tag - always type_shb */
|
||||
UCHAR shb_flags;
|
||||
PTR shb_history;
|
||||
PTR shb_remove_node; /* Node removing itself */
|
||||
PTR shb_insert_que; /* Queue inserting into */
|
||||
PTR shb_insert_prior; /* Prior of inserting queue */
|
||||
SRQ_PTR shb_history;
|
||||
SRQ_PTR shb_remove_node; /* Node removing itself */
|
||||
SRQ_PTR shb_insert_que; /* Queue inserting into */
|
||||
SRQ_PTR shb_insert_prior; /* Prior of inserting queue */
|
||||
SLONG shb_misc[10]; /* Unused space */
|
||||
} *SHB;
|
||||
|
||||
@ -263,7 +248,7 @@ typedef struct lbl
|
||||
srq lbl_lhb_hash; /* Collision que for hash table */
|
||||
srq lbl_lhb_data; /* Lock data que by series */
|
||||
SLONG lbl_data; /* user data */
|
||||
PTR lbl_parent; /* Parent */
|
||||
SRQ_PTR lbl_parent; /* Parent */
|
||||
UCHAR lbl_series; /* Lock series */
|
||||
UCHAR lbl_flags; /* Misc flags */
|
||||
USHORT lbl_pending_lrq_count; /* count of lbl_requests with LRQ_pending */
|
||||
@ -280,8 +265,8 @@ typedef struct lrq {
|
||||
UCHAR lrq_requested; /* Level requested */
|
||||
UCHAR lrq_state; /* State of lock request */
|
||||
USHORT lrq_flags; /* Misc crud */
|
||||
PTR lrq_owner; /* Owner making request */
|
||||
PTR lrq_lock; /* Lock requested */
|
||||
SRQ_PTR lrq_owner; /* Owner making request */
|
||||
SRQ_PTR lrq_lock; /* Lock requested */
|
||||
SLONG lrq_data; /* Lock data requested */
|
||||
srq lrq_own_requests; /* Locks granted for owner */
|
||||
srq lrq_lbl_requests; /* Que of requests (active, pending) */
|
||||
@ -290,15 +275,15 @@ typedef struct lrq {
|
||||
void* lrq_ast_argument; /* Ast argument */
|
||||
} *LRQ;
|
||||
|
||||
#define LRQ_blocking 1 /* Request is blocking */
|
||||
#define LRQ_pending 2 /* Request is pending */
|
||||
#define LRQ_converting 4 /* Request is pending conversion */
|
||||
#define LRQ_rejected 8 /* Request is rejected */
|
||||
#define LRQ_timed_out 16 /* Wait timed out */
|
||||
#define LRQ_deadlock 32 /* Request has been seen by the deadlock-walk */
|
||||
#define LRQ_repost 64 /* Request block used for repost */
|
||||
#define LRQ_scanned 128 /* Request already scanned for deadlock */
|
||||
#define LRQ_blocking_seen 256 /* Blocking notification received by owner */
|
||||
#define LRQ_blocking 1 /* Request is blocking */
|
||||
#define LRQ_pending 2 /* Request is pending */
|
||||
#define LRQ_converting 4 /* Request is pending conversion */
|
||||
#define LRQ_rejected 8 /* Request is rejected */
|
||||
#define LRQ_timed_out 16 /* Wait timed out */
|
||||
#define LRQ_deadlock 32 /* Request has been seen by the deadlock-walk */
|
||||
#define LRQ_repost 64 /* Request block used for repost */
|
||||
#define LRQ_scanned 128 /* Request already scanned for deadlock */
|
||||
#define LRQ_blocking_seen 256 /* Blocking notification received by owner */
|
||||
|
||||
/* Owner block */
|
||||
|
||||
@ -313,7 +298,7 @@ typedef struct own
|
||||
srq own_lhb_owners; /* Owner que */
|
||||
srq own_requests; /* Lock requests granted */
|
||||
srq own_blocks; /* Lock requests blocking */
|
||||
PTR own_pending_request; /* Request we're waiting on */
|
||||
SRQ_PTR own_pending_request; /* Request we're waiting on */
|
||||
int own_process_id; /* Owner's process ID */
|
||||
int own_process_uid; /* Owner's process UID */
|
||||
ULONG own_acquire_time; /* lhb_acquires when owner last tried acquire() */
|
||||
@ -336,21 +321,21 @@ typedef struct own
|
||||
} *OWN;
|
||||
|
||||
/* Flags in own_flags */
|
||||
#define OWN_blocking 1 // Owner is blocking
|
||||
#define OWN_scanned 2 // Owner has been deadlock scanned
|
||||
#define OWN_manager 4 // Owner is privileged manager
|
||||
#define OWN_signal 8 // Owner needs signal delivered
|
||||
#define OWN_wakeup 32 // Owner has been awoken
|
||||
#define OWN_starved 128 // This thread may be starved
|
||||
#define OWN_blocking 1 // Owner is blocking
|
||||
#define OWN_scanned 2 // Owner has been deadlock scanned
|
||||
#define OWN_manager 4 // Owner is privileged manager
|
||||
#define OWN_signal 8 // Owner needs signal delivered
|
||||
#define OWN_wakeup 32 // Owner has been awoken
|
||||
#define OWN_starved 128 // This thread may be starved
|
||||
|
||||
/* Flags in own_ast_flags */
|
||||
#define OWN_signaled 16 /* Signal is thought to be delivered */
|
||||
#define OWN_signaled 16 /* Signal is thought to be delivered */
|
||||
|
||||
/* Flags in own_semaphore */
|
||||
#define OWN_semavail 0x8000 /* Process semaphore is available */
|
||||
#define OWN_semavail 0x8000 /* Process semaphore is available */
|
||||
|
||||
/* Flags in own_ast_hung_flag */
|
||||
#define OWN_hung 64 /* Owner may be hung by OS-level bug */
|
||||
#define OWN_hung 64 /* Owner may be hung by OS-level bug */
|
||||
|
||||
/* NOTE: own_semaphore, when USE_WAKEUP_EVENTS is set, is used to indicate when a
|
||||
owner is waiting inside wait_for_request(). post_wakeup() will only
|
||||
@ -371,33 +356,33 @@ struct semaphore_mask {
|
||||
typedef struct his {
|
||||
UCHAR his_type; /* memory tag - always type_his */
|
||||
UCHAR his_operation; /* operation that occured */
|
||||
PTR his_next; /* PTR to next item in history list */
|
||||
PTR his_process; /* owner to record for this operation */
|
||||
PTR his_lock; /* lock to record for operation */
|
||||
PTR his_request; /* request to record for operation */
|
||||
SRQ_PTR his_next; /* SRQ_PTR to next item in history list */
|
||||
SRQ_PTR his_process; /* owner to record for this operation */
|
||||
SRQ_PTR his_lock; /* lock to record for operation */
|
||||
SRQ_PTR his_request; /* request to record for operation */
|
||||
} *HIS;
|
||||
|
||||
/* his_operation definitions */
|
||||
#define his_enq 1
|
||||
#define his_deq 2
|
||||
#define his_convert 3
|
||||
#define his_signal 4
|
||||
#define his_post_ast 5
|
||||
#define his_wait 6
|
||||
#define his_del_process 7
|
||||
#define his_del_lock 8
|
||||
#define his_del_request 9
|
||||
#define his_deny 10
|
||||
#define his_grant 11
|
||||
#define his_leave_ast 12
|
||||
#define his_scan 13
|
||||
#define his_dead 14
|
||||
#define his_enter 15
|
||||
#define his_bug 16
|
||||
#define his_active 17
|
||||
#define his_cleanup 18
|
||||
#define his_del_owner 19
|
||||
#define his_MAX his_del_owner
|
||||
#define his_enq 1
|
||||
#define his_deq 2
|
||||
#define his_convert 3
|
||||
#define his_signal 4
|
||||
#define his_post_ast 5
|
||||
#define his_wait 6
|
||||
#define his_del_process 7
|
||||
#define his_del_lock 8
|
||||
#define his_del_request 9
|
||||
#define his_deny 10
|
||||
#define his_grant 11
|
||||
#define his_leave_ast 12
|
||||
#define his_scan 13
|
||||
#define his_dead 14
|
||||
#define his_enter 15
|
||||
#define his_bug 16
|
||||
#define his_active 17
|
||||
#define his_cleanup 18
|
||||
#define his_del_owner 19
|
||||
#define his_MAX his_del_owner
|
||||
|
||||
#endif // ISC_LOCK_LOCK_H
|
||||
|
||||
|
@ -70,14 +70,16 @@ typedef FILE* OUTFILE;
|
||||
#define SW_I_TYPE 4
|
||||
#define SW_I_WAIT 8
|
||||
|
||||
#define SRQ_BASE ((UCHAR*) LOCK_header)
|
||||
|
||||
struct waitque {
|
||||
USHORT waitque_depth;
|
||||
PTR waitque_entry[30];
|
||||
SRQ_PTR waitque_entry[30];
|
||||
};
|
||||
|
||||
static void prt_lock_activity(OUTFILE, const lhb*, USHORT, USHORT, USHORT);
|
||||
static void prt_lock_init(void*, sh_mem*, bool);
|
||||
static void prt_history(OUTFILE, const lhb*, PTR, const SCHAR*);
|
||||
static void prt_history(OUTFILE, const lhb*, SRQ_PTR, const SCHAR*);
|
||||
static void prt_lock(OUTFILE, const lhb*, LBL, USHORT);
|
||||
static void prt_owner(OUTFILE, const lhb*, const own*, bool, bool);
|
||||
static void prt_owner_wait_cycle(OUTFILE, const lhb*, const own*, USHORT, waitque*);
|
||||
@ -420,7 +422,7 @@ int CLIB_ROUTINE main( int argc, char *argv[])
|
||||
#ifdef MANAGER_PROCESS
|
||||
int manager_pid = 0;
|
||||
if (LOCK_header->lhb_manager) {
|
||||
OWN manager = (OWN) ABS_PTR(LOCK_header->lhb_manager);
|
||||
OWN manager = (OWN) SRQ_ABS_PTR(LOCK_header->lhb_manager);
|
||||
manager_pid = manager->own_process_id;
|
||||
}
|
||||
|
||||
@ -465,8 +467,8 @@ int CLIB_ROUTINE main( int argc, char *argv[])
|
||||
slot++, i++)
|
||||
{
|
||||
SLONG hash_lock_count = 0;
|
||||
for (const srq* que = (SRQ) ABS_PTR(slot->srq_forward); que != slot;
|
||||
que = (SRQ) ABS_PTR(que->srq_forward))
|
||||
for (const srq* que_inst = (SRQ) SRQ_ABS_PTR(slot->srq_forward); que_inst != slot;
|
||||
que_inst = (SRQ) SRQ_ABS_PTR(que_inst->srq_forward))
|
||||
{
|
||||
++hash_total_count;
|
||||
++hash_lock_count;
|
||||
@ -486,7 +488,7 @@ int CLIB_ROUTINE main( int argc, char *argv[])
|
||||
|
||||
const shb* a_shb = NULL;
|
||||
if (LOCK_header->lhb_secondary != LHB_PATTERN) {
|
||||
a_shb = (shb*) ABS_PTR(LOCK_header->lhb_secondary);
|
||||
a_shb = (shb*) SRQ_ABS_PTR(LOCK_header->lhb_secondary);
|
||||
FPRINTF(outfile,
|
||||
"\tRemove node: %6"SLONGFORMAT", Insert queue: %6"SLONGFORMAT
|
||||
", Insert prior: %6"SLONGFORMAT"\n",
|
||||
@ -513,7 +515,7 @@ int CLIB_ROUTINE main( int argc, char *argv[])
|
||||
/* Print known owners */
|
||||
|
||||
if (sw_owners) {
|
||||
const srq* que;
|
||||
const srq* que_inst;
|
||||
|
||||
#ifdef SOLARIS_MT
|
||||
/* The Lock Starvation recovery code on Solaris rotates the owner
|
||||
@ -521,27 +523,27 @@ int CLIB_ROUTINE main( int argc, char *argv[])
|
||||
printouts when multiple runs are made. So we scan the list
|
||||
of owners once to find the lowest owner_id, and start the printout
|
||||
from there. */
|
||||
PTR least_owner_id = 0x7FFFFFFF;
|
||||
SRQ_PTR least_owner_id = 0x7FFFFFFF;
|
||||
const srq* least_owner_ptr = &LOCK_header->lhb_owners;
|
||||
QUE_LOOP(LOCK_header->lhb_owners, que) {
|
||||
OWN this_owner = (OWN) ((UCHAR*) que - OFFSET(OWN, own_lhb_owners));
|
||||
if (REL_PTR(this_owner) < least_owner_id) {
|
||||
least_owner_id = REL_PTR(this_owner);
|
||||
least_owner_ptr = que;
|
||||
SRQ_LOOP(LOCK_header->lhb_owners, que_inst) {
|
||||
OWN this_owner = (OWN) ((UCHAR*) que_inst - OFFSET(OWN, own_lhb_owners));
|
||||
if (SRQ_REL_PTR(this_owner) < least_owner_id) {
|
||||
least_owner_id = SRQ_REL_PTR(this_owner);
|
||||
least_owner_ptr = que_inst;
|
||||
}
|
||||
}
|
||||
que = least_owner_ptr;
|
||||
que_inst = least_owner_ptr;
|
||||
do {
|
||||
if (que != &LOCK_header->lhb_owners)
|
||||
if (que_inst != &LOCK_header->lhb_owners)
|
||||
prt_owner(outfile, LOCK_header,
|
||||
(OWN) ((UCHAR*) que - OFFSET(OWN, own_lhb_owners)),
|
||||
(OWN) ((UCHAR*) que_inst - OFFSET(OWN, own_lhb_owners)),
|
||||
sw_requests, sw_waitlist);
|
||||
que = QUE_NEXT((*que));
|
||||
} while (que != least_owner_ptr);
|
||||
que_inst = SRQ_NEXT((*que_inst));
|
||||
} while (que_inst != least_owner_ptr);
|
||||
#else
|
||||
QUE_LOOP(LOCK_header->lhb_owners, que) {
|
||||
SRQ_LOOP(LOCK_header->lhb_owners, que_inst) {
|
||||
prt_owner(outfile, LOCK_header,
|
||||
(OWN) ((UCHAR*) que - OFFSET(OWN, own_lhb_owners)),
|
||||
(OWN) ((UCHAR*) que_inst - OFFSET(OWN, own_lhb_owners)),
|
||||
sw_requests, sw_waitlist);
|
||||
}
|
||||
#endif /* SOLARIS_MT */
|
||||
@ -554,11 +556,11 @@ int CLIB_ROUTINE main( int argc, char *argv[])
|
||||
for (const srq* slot = LOCK_header->lhb_hash;
|
||||
i < LOCK_header->lhb_hash_slots; slot++, i++)
|
||||
{
|
||||
for (const srq* que = (SRQ) ABS_PTR(slot->srq_forward); que != slot;
|
||||
que = (SRQ) ABS_PTR(que->srq_forward))
|
||||
for (const srq* que_inst = (SRQ) SRQ_ABS_PTR(slot->srq_forward); que_inst != slot;
|
||||
que_inst = (SRQ) SRQ_ABS_PTR(que_inst->srq_forward))
|
||||
{
|
||||
prt_lock(outfile, LOCK_header,
|
||||
(LBL) ((UCHAR *) que - OFFSET(LBL, lbl_lhb_hash)),
|
||||
(LBL) ((UCHAR *) que_inst - OFFSET(LBL, lbl_lhb_hash)),
|
||||
sw_series);
|
||||
}
|
||||
}
|
||||
@ -847,7 +849,7 @@ static void prt_lock_init(void*, sh_mem*, bool)
|
||||
static void prt_history(
|
||||
OUTFILE outfile,
|
||||
const lhb* LOCK_header,
|
||||
PTR history_header,
|
||||
SRQ_PTR history_header,
|
||||
const SCHAR* title)
|
||||
{
|
||||
/**************************************
|
||||
@ -862,8 +864,8 @@ static void prt_history(
|
||||
**************************************/
|
||||
FPRINTF(outfile, "%s:\n", title);
|
||||
|
||||
for (const his* history = (HIS) ABS_PTR(history_header); true;
|
||||
history = (HIS) ABS_PTR(history->his_next))
|
||||
for (const his* history = (HIS) SRQ_ABS_PTR(history_header); true;
|
||||
history = (HIS) SRQ_ABS_PTR(history->his_next))
|
||||
{
|
||||
if (history->his_operation)
|
||||
FPRINTF(outfile,
|
||||
@ -895,7 +897,7 @@ static void prt_lock(
|
||||
if (sw_series && lock->lbl_series != sw_series)
|
||||
return;
|
||||
|
||||
FPRINTF(outfile, "LOCK BLOCK %6"SLONGFORMAT"\n", REL_PTR(lock));
|
||||
FPRINTF(outfile, "LOCK BLOCK %6"SLONGFORMAT"\n", SRQ_REL_PTR(lock));
|
||||
FPRINTF(outfile,
|
||||
"\tSeries: %d, Parent: %6"ULONGFORMAT
|
||||
", State: %d, size: %d length: %d data: %"ULONGFORMAT"\n",
|
||||
@ -941,13 +943,13 @@ static void prt_lock(
|
||||
prt_que(outfile, LOCK_header, "\tRequests", &lock->lbl_requests,
|
||||
OFFSET(LRQ, lrq_lbl_requests));
|
||||
|
||||
const srq* que;
|
||||
QUE_LOOP(lock->lbl_requests, que) {
|
||||
const lrq* request = (lrq*) ((UCHAR*) que - OFFSET(LRQ, lrq_lbl_requests));
|
||||
const srq* que_inst;
|
||||
SRQ_LOOP(lock->lbl_requests, que_inst) {
|
||||
const lrq* request = (lrq*) ((UCHAR*) que_inst - OFFSET(LRQ, lrq_lbl_requests));
|
||||
FPRINTF(outfile,
|
||||
"\t\tRequest %6"SLONGFORMAT", Owner: %6"SLONGFORMAT
|
||||
", State: %d (%d), Flags: 0x%02X\n",
|
||||
REL_PTR(request), request->lrq_owner, request->lrq_state,
|
||||
SRQ_REL_PTR(request), request->lrq_owner, request->lrq_state,
|
||||
request->lrq_requested, request->lrq_flags);
|
||||
}
|
||||
|
||||
@ -971,7 +973,7 @@ static void prt_owner(OUTFILE outfile,
|
||||
* Print a formatted owner block.
|
||||
*
|
||||
**************************************/
|
||||
FPRINTF(outfile, "OWNER BLOCK %6"SLONGFORMAT"\n", REL_PTR(owner));
|
||||
FPRINTF(outfile, "OWNER BLOCK %6"SLONGFORMAT"\n", SRQ_REL_PTR(owner));
|
||||
FPRINTF(outfile, "\tOwner id: %6"ULONGFORMAT
|
||||
", type: %1d, flags: 0x%02X, pending: %6"SLONGFORMAT", semid: %6d ",
|
||||
owner->own_owner_id, owner->own_owner_type,
|
||||
@ -1026,10 +1028,10 @@ static void prt_owner(OUTFILE outfile,
|
||||
FPRINTF(outfile, "\n");
|
||||
|
||||
if (sw_requests) {
|
||||
const srq* que;
|
||||
QUE_LOOP(owner->own_requests, que)
|
||||
const srq* que_inst;
|
||||
SRQ_LOOP(owner->own_requests, que_inst)
|
||||
prt_request(outfile, LOCK_header,
|
||||
(LRQ) ((UCHAR *) que -
|
||||
(LRQ) ((UCHAR *) que_inst -
|
||||
OFFSET(LRQ, lrq_own_requests)));
|
||||
}
|
||||
}
|
||||
@ -1064,13 +1066,13 @@ static void prt_owner_wait_cycle(
|
||||
their blocking queues */
|
||||
|
||||
for (i = 0; i < waiters->waitque_depth; i++)
|
||||
if (REL_PTR(owner) == waiters->waitque_entry[i]) {
|
||||
if (SRQ_REL_PTR(owner) == waiters->waitque_entry[i]) {
|
||||
FPRINTF(outfile, "%6"SLONGFORMAT" (potential deadlock).\n",
|
||||
REL_PTR(owner));
|
||||
SRQ_REL_PTR(owner));
|
||||
return;
|
||||
};
|
||||
|
||||
FPRINTF(outfile, "%6"SLONGFORMAT" waits on ", REL_PTR(owner));
|
||||
FPRINTF(outfile, "%6"SLONGFORMAT" waits on ", SRQ_REL_PTR(owner));
|
||||
|
||||
if (!owner->own_pending_request)
|
||||
FPRINTF(outfile, "nothing.\n");
|
||||
@ -1080,19 +1082,19 @@ static void prt_owner_wait_cycle(
|
||||
return;
|
||||
};
|
||||
|
||||
waiters->waitque_entry[waiters->waitque_depth++] = REL_PTR(owner);
|
||||
waiters->waitque_entry[waiters->waitque_depth++] = SRQ_REL_PTR(owner);
|
||||
|
||||
FPRINTF(outfile, "\n");
|
||||
const lrq* owner_request = (LRQ) ABS_PTR(owner->own_pending_request);
|
||||
const lrq* owner_request = (LRQ) SRQ_ABS_PTR(owner->own_pending_request);
|
||||
fb_assert(owner_request->lrq_type == type_lrq);
|
||||
const bool owner_conversion = (owner_request->lrq_state > LCK_null);
|
||||
|
||||
const lbl* lock = (LBL) ABS_PTR(owner_request->lrq_lock);
|
||||
const lbl* lock = (LBL) SRQ_ABS_PTR(owner_request->lrq_lock);
|
||||
fb_assert(lock->lbl_type == type_lbl);
|
||||
|
||||
int counter = 0;
|
||||
const srq* que;
|
||||
QUE_LOOP(lock->lbl_requests, que) {
|
||||
const srq* que_inst;
|
||||
SRQ_LOOP(lock->lbl_requests, que_inst) {
|
||||
|
||||
if (counter++ > 50) {
|
||||
for (i = indent + 6; i; i--)
|
||||
@ -1103,7 +1105,7 @@ static void prt_owner_wait_cycle(
|
||||
}
|
||||
|
||||
const lrq* lock_request =
|
||||
(LRQ) ((UCHAR *) que - OFFSET(LRQ, lrq_lbl_requests));
|
||||
(LRQ) ((UCHAR *) que_inst - OFFSET(LRQ, lrq_lbl_requests));
|
||||
fb_assert(lock_request->lrq_type == type_lrq);
|
||||
|
||||
|
||||
@ -1127,7 +1129,7 @@ static void prt_owner_wait_cycle(
|
||||
(owner_request->lrq_requested,
|
||||
lock_request->lrq_state)) continue;
|
||||
};
|
||||
const own* lock_owner = (OWN) ABS_PTR(lock_request->lrq_owner);
|
||||
const own* lock_owner = (OWN) SRQ_ABS_PTR(lock_request->lrq_owner);
|
||||
prt_owner_wait_cycle(outfile, LOCK_header, lock_owner, indent + 4,
|
||||
waiters);
|
||||
}
|
||||
@ -1149,7 +1151,7 @@ static void prt_request(OUTFILE outfile, const lhb* LOCK_header, const lrq* requ
|
||||
*
|
||||
**************************************/
|
||||
|
||||
FPRINTF(outfile, "REQUEST BLOCK %6"SLONGFORMAT"\n", REL_PTR(request));
|
||||
FPRINTF(outfile, "REQUEST BLOCK %6"SLONGFORMAT"\n", SRQ_REL_PTR(request));
|
||||
FPRINTF(outfile, "\tOwner: %6"SLONGFORMAT", Lock: %6"SLONGFORMAT
|
||||
", State: %d, Mode: %d, Flags: 0x%02X\n",
|
||||
request->lrq_owner, request->lrq_lock, request->lrq_state,
|
||||
@ -1169,7 +1171,7 @@ static void prt_request(OUTFILE outfile, const lhb* LOCK_header, const lrq* requ
|
||||
static void prt_que(
|
||||
OUTFILE outfile,
|
||||
const lhb* LOCK_header,
|
||||
const SCHAR* string, const srq* que, USHORT que_offset)
|
||||
const SCHAR* string, const srq* que_inst, USHORT que_offset)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -1181,28 +1183,28 @@ static void prt_que(
|
||||
* Print the contents of a self-relative que.
|
||||
*
|
||||
**************************************/
|
||||
const SLONG offset = REL_PTR(que);
|
||||
const SLONG offset = SRQ_REL_PTR(que_inst);
|
||||
|
||||
if (offset == que->srq_forward && offset == que->srq_backward) {
|
||||
if (offset == que_inst->srq_forward && offset == que_inst->srq_backward) {
|
||||
FPRINTF(outfile, "%s: *empty*\n", string);
|
||||
return;
|
||||
}
|
||||
|
||||
SLONG count = 0;
|
||||
const srq* next;
|
||||
QUE_LOOP((*que), next)
|
||||
SRQ_LOOP((*que_inst), next)
|
||||
++count;
|
||||
|
||||
FPRINTF(outfile, "%s (%ld):\tforward: %6"SLONGFORMAT
|
||||
", backward: %6"SLONGFORMAT"\n", string, count,
|
||||
que->srq_forward - que_offset, que->srq_backward - que_offset);
|
||||
que_inst->srq_forward - que_offset, que_inst->srq_backward - que_offset);
|
||||
}
|
||||
|
||||
|
||||
static void prt_que2(
|
||||
OUTFILE outfile,
|
||||
const lhb* LOCK_header,
|
||||
const SCHAR* string, const srq* que, USHORT que_offset)
|
||||
const SCHAR* string, const srq* que_inst, USHORT que_offset)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -1215,15 +1217,15 @@ static void prt_que2(
|
||||
* But don't try to count the entries, as they might be invalid
|
||||
*
|
||||
**************************************/
|
||||
const SLONG offset = REL_PTR(que);
|
||||
const SLONG offset = SRQ_REL_PTR(que_inst);
|
||||
|
||||
if (offset == que->srq_forward && offset == que->srq_backward) {
|
||||
if (offset == que_inst->srq_forward && offset == que_inst->srq_backward) {
|
||||
FPRINTF(outfile, "%s: *empty*\n", string);
|
||||
return;
|
||||
}
|
||||
|
||||
FPRINTF(outfile, "%s:\tforward: %6"SLONGFORMAT
|
||||
", backward: %6"SLONGFORMAT"\n", string,
|
||||
que->srq_forward - que_offset, que->srq_backward - que_offset);
|
||||
que_inst->srq_forward - que_offset, que_inst->srq_backward - que_offset);
|
||||
}
|
||||
|
||||
|
@ -27,12 +27,13 @@
|
||||
#include "../jrd/event_proto.h"
|
||||
#include "../jrd/gds_proto.h"
|
||||
|
||||
static void prt_que(UCHAR *, SRQ *);
|
||||
static void prt_que(UCHAR *, srq *);
|
||||
static void event_list(void);
|
||||
static void event_dump_list(void);
|
||||
|
||||
static EVH EVENT_header = NULL;
|
||||
|
||||
#define SRQ_BASE ((UCHAR *) EVENT_header)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@ -79,12 +80,12 @@ static void event_list(void)
|
||||
* This format is more readable for humans.
|
||||
*
|
||||
**************************************/
|
||||
SRQ *que;
|
||||
srq *que_inst;
|
||||
EVNT event;
|
||||
SRQ *database_que;
|
||||
srq *database_que;
|
||||
EVNT database_event;
|
||||
|
||||
QUE_LOOP(EVENT_header->evh_events, database_que) {
|
||||
SRQ_LOOP(EVENT_header->evh_events, database_que) {
|
||||
UCHAR *p;
|
||||
ULONG l;
|
||||
|
||||
@ -109,10 +110,10 @@ static void event_list(void)
|
||||
|
||||
{
|
||||
RINT interest;
|
||||
SRQ *interest_que;
|
||||
srq *interest_que;
|
||||
/* Print out the interest list for this event */
|
||||
|
||||
QUE_LOOP(database_event->evnt_interests, interest_que) {
|
||||
SRQ_LOOP(database_event->evnt_interests, interest_que) {
|
||||
interest =
|
||||
(RINT) ((UCHAR *) interest_que -
|
||||
OFFSET(RINT, rint_interests));
|
||||
@ -122,8 +123,8 @@ static void event_list(void)
|
||||
jrd_req* request;
|
||||
PRB process;
|
||||
|
||||
request = (jrd_req*) ABS_PTR(interest->rint_request);
|
||||
process = (PRB) ABS_PTR(request->req_process);
|
||||
request = (jrd_req*) SRQ_ABS_PTR(interest->rint_request);
|
||||
process = (PRB) SRQ_ABS_PTR(request->req_process);
|
||||
printf("%6d ", process->prb_process_id);
|
||||
}
|
||||
}
|
||||
@ -131,21 +132,21 @@ static void event_list(void)
|
||||
|
||||
/* Print out each event belonging to this database */
|
||||
|
||||
QUE_LOOP(EVENT_header->evh_events, que) {
|
||||
SRQ_LOOP(EVENT_header->evh_events, que_inst) {
|
||||
|
||||
event = (EVNT) ((UCHAR *) que - OFFSET(EVNT, evnt_events));
|
||||
event = (EVNT) ((UCHAR *) que_inst - OFFSET(EVNT, evnt_events));
|
||||
fb_assert(event->evnt_header.hdr_type == type_evnt);
|
||||
if (event->evnt_parent != REL_PTR(database_event))
|
||||
if (event->evnt_parent != SRQ_REL_PTR(database_event))
|
||||
continue;
|
||||
printf(" \"%-15s\" count: %6ld Interest",
|
||||
event->evnt_name, event->evnt_count);
|
||||
|
||||
{
|
||||
RINT interest;
|
||||
SRQ *interest_que;
|
||||
srq *interest_que;
|
||||
/* Print out the interest list for this event */
|
||||
|
||||
QUE_LOOP(event->evnt_interests, interest_que) {
|
||||
SRQ_LOOP(event->evnt_interests, interest_que) {
|
||||
interest =
|
||||
(RINT) ((UCHAR *) interest_que -
|
||||
OFFSET(RINT, rint_interests));
|
||||
@ -155,8 +156,8 @@ static void event_list(void)
|
||||
jrd_req* request;
|
||||
PRB process;
|
||||
|
||||
request = (jrd_req*) ABS_PTR(interest->rint_request);
|
||||
process = (PRB) ABS_PTR(request->req_process);
|
||||
request = (jrd_req*) SRQ_ABS_PTR(interest->rint_request);
|
||||
process = (PRB) SRQ_ABS_PTR(request->req_process);
|
||||
printf("%6d ", process->prb_process_id);
|
||||
}
|
||||
}
|
||||
@ -181,7 +182,7 @@ static void event_table_dump(void)
|
||||
* is not very readable by humans.
|
||||
*
|
||||
**************************************/
|
||||
SRQ *que;
|
||||
srq *que_inst;
|
||||
PRB process;
|
||||
FRB free;
|
||||
EVNT event, parent;
|
||||
@ -204,7 +205,7 @@ static void event_table_dump(void)
|
||||
offset += block->hdr_length)
|
||||
{
|
||||
printf("\n%.5ld ", offset);
|
||||
event_hdr* block = (event_hdr*) ABS_PTR(offset);
|
||||
event_hdr* block = (event_hdr*) SRQ_ABS_PTR(offset);
|
||||
switch (block->hdr_type) {
|
||||
case type_prb:
|
||||
printf("PROCESS_BLOCK (%ld)\n", block->hdr_length);
|
||||
@ -254,9 +255,9 @@ static void event_table_dump(void)
|
||||
printf("INTEREST (%ld)\n", block->hdr_length);
|
||||
interest = (RINT) block;
|
||||
if (interest->rint_event) {
|
||||
event = (EVNT) ABS_PTR(interest->rint_event);
|
||||
event = (EVNT) SRQ_ABS_PTR(interest->rint_event);
|
||||
if (event->evnt_parent) {
|
||||
parent = (EVNT) ABS_PTR(event->evnt_parent);
|
||||
parent = (EVNT) SRQ_ABS_PTR(event->evnt_parent);
|
||||
printf("\t\"%s\".\"%s\"\n", parent->evnt_name,
|
||||
event->evnt_name);
|
||||
}
|
||||
@ -280,7 +281,7 @@ static void event_table_dump(void)
|
||||
}
|
||||
|
||||
|
||||
static void prt_que(UCHAR * string, SRQ * que)
|
||||
static void prt_que(UCHAR * string, srq * que_inst)
|
||||
{
|
||||
/**************************************
|
||||
*
|
||||
@ -294,11 +295,11 @@ static void prt_que(UCHAR * string, SRQ * que)
|
||||
**************************************/
|
||||
SLONG offset;
|
||||
|
||||
offset = REL_PTR(que);
|
||||
offset = SRQ_REL_PTR(que_inst);
|
||||
|
||||
if (offset == que->srq_forward && offset == que->srq_backward)
|
||||
if (offset == que_inst->srq_forward && offset == que_inst->srq_backward)
|
||||
printf("%s: *empty*\n", string);
|
||||
else
|
||||
printf("%s: forward: %d, backward: %d\n",
|
||||
string, que->srq_forward, que->srq_backward);
|
||||
string, que_inst->srq_forward, que_inst->srq_backward);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user