Changeset: 782af56d7454 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=782af56d7454
Modified Files:
clients/Tests/exports.stable.out
gdk/gdk_system.c
gdk/gdk_system.h
gdk/gdk_system_private.h
gdk/gdk_utils.c
monetdb5/mal/mal_client.c
monetdb5/mal/mal_client.h
monetdb5/mal/mal_dataflow.c
monetdb5/mal/mal_profiler.c
monetdb5/mal/mal_scenario.c
monetdb5/mal/mal_session.c
monetdb5/modules/mal/mal_mapi.c
sql/backends/monet5/sql_execute.c
sql/backends/monet5/sql_scenario.c
sql/backends/monet5/wlr.c
sql/storage/store.c
Branch: Apr2019
Log Message:
Keep track of what threads are doing, and print info at exit with -d1.
diffs (truncated from 490 to 300 lines):
diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out
--- a/clients/Tests/exports.stable.out
+++ b/clients/Tests/exports.stable.out
@@ -319,6 +319,7 @@ bool MT_thread_init(void);
void MT_thread_setdata(void *data);
void MT_thread_setlockwait(MT_Lock *lock);
void MT_thread_setsemawait(MT_Sema *sema);
+void MT_thread_setworking(const char *work);
void OIDXdestroy(BAT *b);
ssize_t OIDfromStr(const char *src, size_t *len, oid **dst, bool external);
ssize_t OIDtoStr(str *dst, size_t *len, const oid *src, bool external);
diff --git a/gdk/gdk_system.c b/gdk/gdk_system.c
--- a/gdk/gdk_system.c
+++ b/gdk/gdk_system.c
@@ -174,6 +174,7 @@ static struct winthread {
MT_Lock *lockwait; /* lock we're waiting for */
MT_Sema *semawait; /* semaphore we're waiting for */
struct winthread *joinwait; /* process we are joining with */
+ const char *working; /* what we're currently doing */
ATOMIC_TYPE exited;
bool detached:1, waiting:1;
char threadname[16];
@@ -186,6 +187,23 @@ static struct winthread mainthread = {
static CRITICAL_SECTION winthread_cs;
static DWORD threadslot = TLS_OUT_OF_INDEXES;
+void
+dump_threads(void)
+{
+ EnterCriticalSection(&winthread_cs);
+ for (struct winthread *w = winthreads; w; w = w->next) {
+ fprintf(stderr, "%s, waiting for %s, working on %.200s\n",
+ w->threadname,
+ w->lockwait ? w->lockwait->name :
+ w->semawait ? w->semawait->name :
+ w->joinwait ? w->joinwait->threadname :
+ "nothing",
+ ATOMIC_GET(&w->exited) ? "exiting" :
+ w->working ? w->working : "nothing");
+ }
+ LeaveCriticalSection(&winthread_cs);
+}
+
bool
MT_thread_init(void)
{
@@ -250,6 +268,15 @@ MT_thread_setsemawait(MT_Sema *sema)
w->semawait = sema;
}
+void
+MT_thread_setworking(const char *work)
+{
+ struct winthread *w = TlsGetValue(threadslot);
+
+ if (w)
+ w->working = work;
+}
+
void *
MT_thread_getdata(void)
{
@@ -398,6 +425,7 @@ MT_exiting_thread(void)
if (w) {
ATOMIC_SET(&w->exited, 1);
+ w->working = NULL;
}
}
@@ -459,6 +487,7 @@ static struct posthread {
MT_Lock *lockwait; /* lock we're waiting for */
MT_Sema *semawait; /* semaphore we're waiting for */
struct posthread *joinwait; /* process we are joining with */
+ const char *working; /* what we're currently doing */
char threadname[16];
pthread_t tid;
MT_Id mtid;
@@ -475,6 +504,23 @@ static MT_Id MT_thread_id = 1;
static pthread_key_t threadkey;
+void
+dump_threads(void)
+{
+ pthread_mutex_lock(&posthread_lock);
+ for (struct posthread *p = posthreads; p; p = p->next) {
+ fprintf(stderr, "%s, waiting for %s, working on %.200s\n",
+ p->threadname,
+ p->lockwait ? p->lockwait->name :
+ p->semawait ? p->semawait->name :
+ p->joinwait ? p->joinwait->threadname :
+ "nothing",
+ ATOMIC_GET(&p->exited) ? "exiting" :
+ p->working ? p->working : "nothing");
+ }
+ pthread_mutex_unlock(&posthread_lock);
+}
+
bool
MT_thread_init(void)
{
@@ -551,6 +597,15 @@ MT_thread_setsemawait(MT_Sema *sema)
p->semawait = sema;
}
+void
+MT_thread_setworking(const char *work)
+{
+ struct posthread *p = pthread_getspecific(threadkey);
+
+ if (p)
+ p->working = work;
+}
+
#ifdef HAVE_PTHREAD_SIGMASK
static void
MT_thread_sigmask(sigset_t *new_mask, sigset_t *orig_mask)
@@ -732,6 +787,7 @@ MT_exiting_thread(void)
p = pthread_getspecific(threadkey);
if (p) {
ATOMIC_SET(&p->exited, 1);
+ p->working = NULL;
}
}
diff --git a/gdk/gdk_system.h b/gdk/gdk_system.h
--- a/gdk/gdk_system.h
+++ b/gdk/gdk_system.h
@@ -637,6 +637,7 @@ typedef struct {
gdk_export void MT_thread_setlockwait(MT_Lock *lock);
gdk_export void MT_thread_setsemawait(MT_Sema *sema);
+gdk_export void MT_thread_setworking(const char *work);
gdk_export int MT_check_nr_cores(void);
diff --git a/gdk/gdk_system_private.h b/gdk/gdk_system_private.h
--- a/gdk/gdk_system_private.h
+++ b/gdk/gdk_system_private.h
@@ -12,6 +12,8 @@
#error this file should not be included outside its source directory
#endif
+__hidden void dump_threads(void)
+ __attribute__((__visibility__("hidden")));
__hidden void join_detached_threads(void)
__attribute__((__visibility__("hidden")));
__hidden int MT_kill_thread(MT_Id t)
diff --git a/gdk/gdk_utils.c b/gdk/gdk_utils.c
--- a/gdk/gdk_utils.c
+++ b/gdk/gdk_utils.c
@@ -664,6 +664,7 @@ GDKprepareExit(void)
if (ATOMIC_ADD(&GDKstopped, 1) > 0)
return;
+ THRDDEBUG dump_threads();
MT_lock_set(&GDKthreadLock);
for (st = serverthread; st; st = serverthread) {
MT_lock_unset(&GDKthreadLock);
diff --git a/monetdb5/mal/mal_client.c b/monetdb5/mal/mal_client.c
--- a/monetdb5/mal/mal_client.c
+++ b/monetdb5/mal/mal_client.c
@@ -274,6 +274,7 @@ MCinitClientRecord(Client c, oid user, b
c->protocol = PROTOCOL_9;
c->filetrans = false;
+ c->query = NULL;
char name[16];
snprintf(name, sizeof(name), "Client%d->s", (int) (c - mal_clients));
diff --git a/monetdb5/mal/mal_client.h b/monetdb5/mal/mal_client.h
--- a/monetdb5/mal/mal_client.h
+++ b/monetdb5/mal/mal_client.h
@@ -191,6 +191,7 @@ typedef struct CLIENT {
size_t blocksize;
protocol_version protocol;
bool filetrans; /* whether the client can read
files for us */
+ const char *query; /* string, identify whatever
we're working on */
} *Client, ClientRec;
mal_export void MCinit(void);
diff --git a/monetdb5/mal/mal_dataflow.c b/monetdb5/mal/mal_dataflow.c
--- a/monetdb5/mal/mal_dataflow.c
+++ b/monetdb5/mal/mal_dataflow.c
@@ -345,6 +345,7 @@ DFLOWworker(void *T)
}
while (1) {
if (fnxt == 0) {
+ MT_thread_setworking(NULL);
MT_lock_set(&dataflowLock);
cntxt = t->cntxt;
MT_lock_unset(&dataflowLock);
@@ -363,6 +364,7 @@ DFLOWworker(void *T)
/* no more work to be done: exit */
break;
}
+ MT_thread_setworking(fe->flow->cntxt->query);
} else
fe = fnxt;
if (ATOMIC_GET(&exiting)) {
diff --git a/monetdb5/mal/mal_profiler.c b/monetdb5/mal/mal_profiler.c
--- a/monetdb5/mal/mal_profiler.c
+++ b/monetdb5/mal/mal_profiler.c
@@ -1047,6 +1047,7 @@ static void profilerHeartbeat(void *dumm
(void) dummy;
for (;;) {
/* wait until you need this info */
+ MT_thread_setworking("sleeping");
while (ATOMIC_GET(&hbdelay) == 0 || eventstream == NULL) {
if (GDKexiting() || !ATOMIC_GET(&hbrunning))
return;
@@ -1057,6 +1058,7 @@ static void profilerHeartbeat(void *dumm
return;
MT_sleep_ms(t > timeout ? timeout : t);
}
+ MT_thread_setworking("pinging");
profilerHeartbeatEvent("ping");
}
}
diff --git a/monetdb5/mal/mal_scenario.c b/monetdb5/mal/mal_scenario.c
--- a/monetdb5/mal/mal_scenario.c
+++ b/monetdb5/mal/mal_scenario.c
@@ -498,12 +498,24 @@ resetScenario(Client c)
* between speed and ability to analysis its behavior.
*
*/
+static const char *phases[] = {
+ [MAL_SCENARIO_CALLBACK] = "scenario callback",
+ [MAL_SCENARIO_ENGINE] = "scenario engine",
+ [MAL_SCENARIO_EXITCLIENT] = "scenario exitclient",
+ [MAL_SCENARIO_INITCLIENT] = "scenario initclient",
+ [MAL_SCENARIO_OPTIMIZE] = "scenario optimize",
+ [MAL_SCENARIO_PARSER] = "scenario parser",
+ [MAL_SCENARIO_READER] = "scenario reader",
+ [MAL_SCENARIO_SCHEDULER] = "scenario scheduler",
+};
static str
runPhase(Client c, int phase)
{
str msg = MAL_SUCCEED;
- if (c->phase[phase])
+ if (c->phase[phase]) {
+ MT_thread_setworking(phases[phase]);
return msg = (str) (*c->phase[phase])(c);
+ }
return msg;
}
@@ -535,8 +547,10 @@ runScenarioBody(Client c, int once)
goto wrapup;
wrapup:
if (msg != MAL_SUCCEED){
- if(c->phase[MAL_SCENARIO_CALLBACK])
+ if (c->phase[MAL_SCENARIO_CALLBACK]) {
+
MT_thread_setworking(phases[MAL_SCENARIO_CALLBACK]);
msg = (str)
(*c->phase[MAL_SCENARIO_CALLBACK])(c, msg);
+ }
if (msg) {
mnstr_printf(c->fdout,"!%s%s", msg,
(msg[strlen(msg)-1] == '\n'? "":"\n"));
freeException(msg);
@@ -550,8 +564,8 @@ runScenarioBody(Client c, int once)
if( once) break;
}
c->exception_buf_initialized = 0;
- if (once == 0 && c->phase[MAL_SCENARIO_EXITCLIENT])
- msg = (*c->phase[MAL_SCENARIO_EXITCLIENT]) (c);
+ if (once == 0)
+ msg = runPhase(c, MAL_SCENARIO_EXITCLIENT);
return msg;
}
diff --git a/monetdb5/mal/mal_session.c b/monetdb5/mal/mal_session.c
--- a/monetdb5/mal/mal_session.c
+++ b/monetdb5/mal/mal_session.c
@@ -521,6 +521,7 @@ MSserveClient(Client c)
} else {
do {
do {
+ MT_thread_setworking("running scenario");
msg = runScenario(c,0);
freeException(msg);
if (c->mode == FINISHCLIENT)
@@ -529,6 +530,7 @@ MSserveClient(Client c)
} while (c->scenario && !GDKexiting());
} while (c->scenario && c->mode != FINISHCLIENT &&
!GDKexiting());
}
+ MT_thread_setworking("exiting");
/* pre announce our exiting: cleaning up may take a while and we
* don't want to get killed during that time for fear of
* deadlocks */
diff --git a/monetdb5/modules/mal/mal_mapi.c b/monetdb5/modules/mal/mal_mapi.c
--- a/monetdb5/modules/mal/mal_mapi.c
+++ b/monetdb5/modules/mal/mal_mapi.c
@@ -141,6 +141,7 @@ doChallenge(void *data)
protocol_version protocol = PROTOCOL_9;
size_t buflen = BLOCK;
+ MT_thread_setworking("challenging client");
#ifdef _MSC_VER
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list