VOID CS_sampler(void) { CS_SCB *an_scb; i4 sleeptime, elapsed, seconds, event; i4 starttime, stoptime; i4 cs_thread_type; i4 cs_state; bool attached = FALSE; u_i4 bior, biow; u_i4 dior, diork, diow, diowk; u_i4 lior, liork, liow, liowk; /* ** This thread goes into a loop: ** 1. Lock the sampler block ** 2. Do sampling ** 3. Sleep for the specified interval ** The thread will exit normally when the sampler block pointer is NULL. ** The thread exits abnormally if it cannot lock the block. */ starttime = CS_checktime(); elapsed = 0; /* Prime the local I/O, Transaction rate counters */ bior = Cs_srv_block.cs_wtstatistics.cs_bior_done; biow = Cs_srv_block.cs_wtstatistics.cs_biow_done; dior = Cs_srv_block.cs_wtstatistics.cs_dior_done; diork = Cs_srv_block.cs_wtstatistics.cs_dior_kbytes; diow = Cs_srv_block.cs_wtstatistics.cs_diow_done; diowk = Cs_srv_block.cs_wtstatistics.cs_diow_kbytes; lior = Cs_srv_block.cs_wtstatistics.cs_lior_done; liork = Cs_srv_block.cs_wtstatistics.cs_lior_kbytes; liow = Cs_srv_block.cs_wtstatistics.cs_liow_done; liowk = Cs_srv_block.cs_wtstatistics.cs_liow_kbytes; /* Transaction rates cannot be determined */ CsSamplerBlkPtr->txn[CURR] = 0; CsSamplerBlkPtr->txn[PEAK] = 0; for (;;) { if (LockSamplerBlk(&hCsSamplerSem) != OK) { ExitThread((DWORD)-1); } if (CsSamplerBlkPtr->shutdown) { /* ** Detach the sampler block Managed Object */ if (attached) MOdetach(CSsamp_index_name, "CsSamplerBlkPtr"); MEfree((PTR)CsSamplerBlkPtr); CsSamplerBlkPtr = NULL; CSsamp_stopping = TRUE; UnlockSamplerBlk(hCsSamplerSem); CloseHandle(hCsSamplerSem); hCsSamplerSem = NULL; ExitThread(0); } if (!attached) { /* ** Attach the sampler block Managed Object */ MOattach(MO_INSTANCE_VAR, CSsamp_index_name, "CsSamplerBlkPtr", (PTR) CsSamplerBlkPtr); attached = TRUE; } ++CsSamplerBlkPtr->numsamples; /* Count the number of times we sample */ /* Loop thru all the SCBs in the server */ for (an_scb = Cs_srv_block.cs_known_list->cs_next; an_scb && an_scb != Cs_srv_block.cs_known_list; an_scb = an_scb->cs_next) { if (an_scb->cs_thread_type >= -1 && an_scb->cs_thread_type <= MAXSAMPTHREADS - 1) cs_thread_type = an_scb->cs_thread_type; else cs_thread_type = MAXSAMPTHREADS - 1; /* use the <invalid> thread */ /* If Factotum thread, try to isolate which kind */ if ( cs_thread_type == CS_FACTOTUM ) { if ( MEcmp((char *)&an_scb->cs_username, " <WriteBehind", 13) == 0 ) cs_thread_type = CS_WRITE_BEHIND; else if ( MEcmp((char *)&an_scb->cs_username, " <Sort", 6) == 0 ) cs_thread_type = CS_SORT; } if (an_scb->cs_state >= 0 && an_scb->cs_state <= MAXSTATES - 1) cs_state = an_scb->cs_state; else cs_state = MAXSTATES - 1; /* use the <invalid> state */ ++CsSamplerBlkPtr->Thread[cs_thread_type].numthreadsamples; if ( cs_thread_type == CS_NORMAL ) ++CsSamplerBlkPtr->totusersamples; else ++CsSamplerBlkPtr->totsyssamples; switch (cs_state) { case CS_COMPUTABLE: /* Count current facility */ { i4 facility; ++CsSamplerBlkPtr->Thread[cs_thread_type].state[cs_state]; facility = (*Cs_srv_block.cs_facility)(an_scb); if (facility >= MAXFACS || facility < 0) facility = MAXFACS - 1; ++CsSamplerBlkPtr->Thread[cs_thread_type].facility[facility]; break; } case CS_EVENT_WAIT: /* Count event types */ if ( an_scb->cs_memory & CS_BIO_MASK ) ++CsSamplerBlkPtr->Thread[cs_thread_type].evwait[EV_BIO]; else if ( an_scb->cs_memory & CS_DIO_MASK ) ++CsSamplerBlkPtr->Thread[cs_thread_type].evwait[EV_DIO]; else if ( an_scb->cs_memory & CS_LIO_MASK ) ++CsSamplerBlkPtr->Thread[cs_thread_type].evwait[EV_LIO]; else if ( an_scb->cs_memory & CS_LOG_MASK ) ++CsSamplerBlkPtr->Thread[cs_thread_type].evwait[EV_LOG]; else if (an_scb->cs_memory & CS_LOCK_MASK) { ++CsSamplerBlkPtr->Thread[cs_thread_type].evwait[EV_LOCK]; AddLock( an_scb->cs_sync_obj ? *((LK_LOCK_KEY *)an_scb->cs_sync_obj) : dummy_lock, cs_thread_type ); } else ++CsSamplerBlkPtr->Thread[cs_thread_type].state[cs_state]; event = (an_scb->cs_memory & CS_DIO_MASK ? an_scb->cs_memory & CS_IOR_MASK ? 0 : 1 : an_scb->cs_memory & CS_LIO_MASK ? an_scb->cs_memory & CS_IOR_MASK ? 2 : 3 : an_scb->cs_memory & CS_BIO_MASK ? an_scb->cs_memory & CS_IOR_MASK ? 4 : 5 : an_scb->cs_memory & CS_LOG_MASK ? 6 : an_scb->cs_memory & CS_LOCK_MASK ? 7 : an_scb->cs_memory & CS_LGEVENT_MASK ? 8 : an_scb->cs_memory & CS_LKEVENT_MASK ? 9 : /* else it is ... unknown */ 10); switch (cs_thread_type) { case CS_USER_THREAD: ++CsSamplerBlkPtr->numusereventsamples; ++CsSamplerBlkPtr->userevent[event]; /* count event type */ break; default: ++CsSamplerBlkPtr->numsyseventsamples; ++CsSamplerBlkPtr->sysevent[event]; /* count event type */ break; } /* switch (cs_thread_type) */ break; case CS_MUTEX: ++CsSamplerBlkPtr->Thread[cs_thread_type].state[cs_state]; AddMutex( ((CS_SEMAPHORE *)an_scb->cs_sync_obj), cs_thread_type ); break; /* Uninteresting states */ default: ++CsSamplerBlkPtr->Thread[cs_thread_type].state[cs_state]; break; } /* switch (cs_state) */ } /* for */ /* ** If a second or more worth of intervals appear to have elapsed, ** compute current and peak per-second I/O, Transaction rates. */ if ( (elapsed += CsSamplerBlkPtr->interval) >= 1000 ) { /* Get the current time; the interval is not reliable! */ stoptime = CS_checktime(); if ( (seconds = stoptime - starttime) ) { if ( (CsSamplerBlkPtr->bior[CURR] = (Cs_srv_block.cs_wtstatistics.cs_bior_done - bior) / seconds) > CsSamplerBlkPtr->bior[PEAK] ) CsSamplerBlkPtr->bior[PEAK] = CsSamplerBlkPtr->bior[CURR]; if ( (CsSamplerBlkPtr->biow[CURR] = (Cs_srv_block.cs_wtstatistics.cs_biow_done - biow) / seconds) > CsSamplerBlkPtr->biow[PEAK] ) CsSamplerBlkPtr->biow[PEAK] = CsSamplerBlkPtr->biow[CURR]; if ( (CsSamplerBlkPtr->dior[CURR] = (Cs_srv_block.cs_wtstatistics.cs_dior_done - dior) / seconds) > CsSamplerBlkPtr->dior[PEAK] ) CsSamplerBlkPtr->dior[PEAK] = CsSamplerBlkPtr->dior[CURR]; if ( (CsSamplerBlkPtr->diork[CURR] = (Cs_srv_block.cs_wtstatistics.cs_dior_kbytes - diork) / seconds) > CsSamplerBlkPtr->diork[PEAK] ) CsSamplerBlkPtr->diork[PEAK] = CsSamplerBlkPtr->diork[CURR]; if ( (CsSamplerBlkPtr->diow[CURR] = (Cs_srv_block.cs_wtstatistics.cs_diow_done - diow) / seconds) > CsSamplerBlkPtr->diow[PEAK] ) CsSamplerBlkPtr->diow[PEAK] = CsSamplerBlkPtr->diow[CURR]; if ( (CsSamplerBlkPtr->diowk[CURR] = (Cs_srv_block.cs_wtstatistics.cs_diow_kbytes - diowk) / seconds) > CsSamplerBlkPtr->diowk[PEAK] ) CsSamplerBlkPtr->diowk[PEAK] = CsSamplerBlkPtr->diowk[CURR]; if ( (CsSamplerBlkPtr->lior[CURR] = (Cs_srv_block.cs_wtstatistics.cs_lior_done - lior) / seconds) > CsSamplerBlkPtr->lior[PEAK] ) CsSamplerBlkPtr->lior[PEAK] = CsSamplerBlkPtr->lior[CURR]; if ( (CsSamplerBlkPtr->liork[CURR] = (Cs_srv_block.cs_wtstatistics.cs_lior_kbytes - liork) / seconds) > CsSamplerBlkPtr->liork[PEAK] ) CsSamplerBlkPtr->liork[PEAK] = CsSamplerBlkPtr->liork[CURR]; if ( (CsSamplerBlkPtr->liow[CURR] = (Cs_srv_block.cs_wtstatistics.cs_liow_done - liow) / seconds) > CsSamplerBlkPtr->liow[PEAK] ) CsSamplerBlkPtr->liow[PEAK] = CsSamplerBlkPtr->liow[CURR]; if ( (CsSamplerBlkPtr->liowk[CURR] = (Cs_srv_block.cs_wtstatistics.cs_liow_kbytes - liowk) / seconds) > CsSamplerBlkPtr->liowk[PEAK] ) CsSamplerBlkPtr->liowk[PEAK] = CsSamplerBlkPtr->liowk[CURR]; /* Transaction rate cannot be determined */ } starttime = CS_checktime(); elapsed = 0; bior = Cs_srv_block.cs_wtstatistics.cs_bior_done; biow = Cs_srv_block.cs_wtstatistics.cs_biow_done; dior = Cs_srv_block.cs_wtstatistics.cs_dior_done; diork = Cs_srv_block.cs_wtstatistics.cs_dior_kbytes; diow = Cs_srv_block.cs_wtstatistics.cs_diow_done; diowk = Cs_srv_block.cs_wtstatistics.cs_diow_kbytes; lior = Cs_srv_block.cs_wtstatistics.cs_lior_done; liork = Cs_srv_block.cs_wtstatistics.cs_lior_kbytes; liow = Cs_srv_block.cs_wtstatistics.cs_liow_done; liowk = Cs_srv_block.cs_wtstatistics.cs_liow_kbytes; } sleeptime = CsSamplerBlkPtr->interval; UnlockSamplerBlk(hCsSamplerSem); Sleep (sleeptime); } /* for (;;) */ } /* CS_sampler */
VOID CS_sampler(void) { CS_SCB *an_scb; i4 sleeptime; i4 cs_thread_type; i4 cs_state; /* ** This thread goes into a loop: ** 1. Lock the sampler block ** 2. Do sampling ** 3. Sleep for the specified interval ** The thread will exit normally when the sampler block pointer is NULL. ** The thread exits abnormally if it cannot lock the block. */ for (;;) { CSget_scb(&an_scb); if ( CsSamplerBlkPtr == NULL || (an_scb->cs_mask & CS_DEAD_MASK) || (an_scb->cs_mask & CS_IRPENDING_MASK)) { return; } ++CsSamplerBlkPtr->numsamples; /* Count the number of times we sample */ /* Loop thru all the SCBs in the server */ for (an_scb = Cs_srv_block.cs_known_list->cs_next; an_scb && an_scb != Cs_srv_block.cs_known_list; an_scb = an_scb->cs_next) { /* skip the sampler thread and the monitor thread */ if (an_scb == &samp_scb || (an_scb->cs_mask & CS_MNTR_MASK) ) continue; if (an_scb->cs_thread_type >= -1 && an_scb->cs_thread_type <= MAXSAMPTHREADS - 1) cs_thread_type = an_scb->cs_thread_type; else cs_thread_type = MAXSAMPTHREADS - 1; /* use the <invalid> type */ if (an_scb->cs_state >= 0 && an_scb->cs_state <= MAXSTATES - 1) cs_state = an_scb->cs_state; else cs_state = MAXSTATES - 1; switch (cs_state) { i4 facility; case CS_COMPUTABLE: if ( an_scb->cs_mask == CS_MUTEX_MASK ) { /* really waiting on a mutex */ ++CsSamplerBlkPtr-> Thread[cs_thread_type].numthreadsamples; ++CsSamplerBlkPtr-> /* count current state */ Thread[cs_thread_type].state[CS_MUTEX]; AddMutex( ((CS_SEMAPHORE *)an_scb->cs_sync_obj), cs_thread_type ); } else { ++CsSamplerBlkPtr-> Thread[cs_thread_type].numthreadsamples; ++CsSamplerBlkPtr-> /* count current state */ Thread[cs_thread_type].state[cs_state]; facility = (*Cs_srv_block.cs_facility)(an_scb); if (facility >= MAXFACS || facility < 0) facility = MAXFACS - 1; ++CsSamplerBlkPtr-> /* count current facility */ Thread[cs_thread_type].facility[facility]; } break; case CS_FREE: case CS_STACK_WAIT: case CS_UWAIT: ++CsSamplerBlkPtr-> Thread[cs_thread_type].numthreadsamples; ++CsSamplerBlkPtr-> /* count current state */ Thread[cs_thread_type].state[cs_state]; break; case CS_EVENT_WAIT: ++CsSamplerBlkPtr-> Thread[cs_thread_type].numthreadsamples; ++CsSamplerBlkPtr-> /* count current state */ Thread[cs_thread_type].state[cs_state]; switch (cs_thread_type) { case CS_USER_THREAD: ++CsSamplerBlkPtr->numusereventsamples; ++CsSamplerBlkPtr-> /* count event type */ userevent[(an_scb->cs_memory & CS_DIO_MASK ? 0 : an_scb->cs_memory & CS_BIO_MASK ? 1 : an_scb->cs_memory & CS_LOCK_MASK ? 2 : an_scb->cs_memory & CS_LOG_MASK ? 3 : an_scb->cs_memory & CS_LGEVENT_MASK ? 4 : an_scb->cs_memory & CS_LKEVENT_MASK ? 5 : /* else it is ... unknown */ 6)]; break; default: ++CsSamplerBlkPtr->numsyseventsamples; ++CsSamplerBlkPtr-> /* count event type */ sysevent[(an_scb->cs_memory & CS_DIO_MASK ? 0 : an_scb->cs_memory & CS_BIO_MASK ? 1 : an_scb->cs_memory & CS_LOCK_MASK ? 2 : an_scb->cs_memory & CS_LOG_MASK ? 3 : an_scb->cs_memory & CS_LGEVENT_MASK ? 4 : an_scb->cs_memory & CS_LKEVENT_MASK ? 5 : /* else it is ... unknown */ 6)]; break; } /* switch (cs_thread_type) */ break; case CS_MUTEX: ++CsSamplerBlkPtr-> Thread[cs_thread_type].numthreadsamples; ++CsSamplerBlkPtr-> /* count current state */ Thread[cs_thread_type].state[cs_state]; AddMutex( ((CS_SEMAPHORE *)an_scb->cs_sync_obj), cs_thread_type ); break; case CS_CNDWAIT: ++CsSamplerBlkPtr-> Thread[cs_thread_type].numthreadsamples; ++CsSamplerBlkPtr-> /* count current state */ Thread[cs_thread_type].state[cs_state]; break; default: ++CsSamplerBlkPtr-> Thread[cs_thread_type].numthreadsamples; ++CsSamplerBlkPtr-> /* count "invalid" state */ Thread[cs_thread_type].state[MAXSTATES - 1]; break; } /* switch (cs_state) */ } /* for */ sleeptime = CsSamplerBlkPtr->interval; CS_realtime_update_smclock(); CSms_thread_nap( sleeptime ); } /* for (;;) */ } /* CS_sampler */