void kill_worker_thread() { exit_worker_thread = 1; signal_thread(); pthread_join(thread, NULL); pthread_cond_destroy(&cond); pthread_mutex_destroy(&lock); close(mypipe[0]); close(mypipe[1]); }
static void *watchdog_thread(void *arg) { S64 savecount[MAX_CPU_ENGINES]; int i; UNREFERENCED(arg); /* Set watchdog priority just below cpu priority such that it will not invalidly detect an inoperable cpu */ if(sysblk.cpuprio >= 0) set_thread_priority(0, sysblk.cpuprio+1); for (i = 0; i < sysblk.maxcpu; i ++) savecount[i] = -1; while(!sysblk.shutdown) { for (i = 0; i < sysblk.maxcpu; i++) { // obtain_lock (&sysblk.cpulock[i]); if (IS_CPU_ONLINE(i) && sysblk.regs[i]->cpustate == CPUSTATE_STARTED && (!WAITSTATE(&sysblk.regs[i]->psw) #if defined(_FEATURE_WAITSTATE_ASSIST) && !(sysblk.regs[i]->sie_active && WAITSTATE(&sysblk.regs[i]->guestregs->psw)) #endif )) { /* If the cpu is running but not executing instructions then it must be malfunctioning */ if((INSTCOUNT(sysblk.regs[i]) == (U64)savecount[i]) && !HDC1(debug_watchdog_signal, sysblk.regs[i]) ) { /* Send signal to looping CPU */ signal_thread(sysblk.cputid[i], SIGUSR1); savecount[i] = -1; } else /* Save current instcount */ savecount[i] = INSTCOUNT(sysblk.regs[i]); } else /* mark savecount invalid as CPU not in running state */ savecount[i] = -1; // release_lock (&sysblk.cpulock[i]); } /* Sleep for 20 seconds */ SLEEP(20); } return NULL; }
int CTCI_Close( DEVBLK* pDEVBLK ) { /* DEVBLK* pDEVBLK2; */ PCTCBLK pCTCBLK = (PCTCBLK)pDEVBLK->dev_data; // Close the device file (if not already closed) if( pCTCBLK->fd >= 0 ) { // PROGRAMMING NOTE: there's currently no way to interrupt // the "CTCI_ReadThread"s TUNTAP_Read of the adapter. Thus // we must simply wait for CTCI_ReadThread to eventually // notice that we're doing a close (via our setting of the // fCloseInProgress flag). Its TUNTAP_Read will eventually // timeout after a few seconds (currently 5, which is dif- // ferent than the CTC_READ_TIMEOUT_SECS timeout value the // CTCI_Read function uses) and will then do the close of // the adapter for us (TUNTAP_Close) so we don't have to. // All we need to do is ask it to exit (via our setting of // the fCloseInProgress flag) and then wait for it to exit // (which, as stated, could take up to a max of 5 seconds). // All of this is simply because it's poor form to close a // device from one thread while another thread is reading // from it. Attempting to do so could trip a race condition // wherein the internal i/o buffers used to process the // read request could have been freed (by the close call) // by the time the read request eventually gets serviced. TID tid = pCTCBLK->tid; pCTCBLK->fCloseInProgress = 1; // (ask read thread to exit) signal_thread( tid, SIGUSR2 ); // (for non-Win32 platforms) //FIXME signal_thread not working for non-MSVC platforms #if defined(_MSVC_) join_thread( tid, NULL ); // (wait for thread to end) #endif detach_thread( tid ); // (wait for thread to end) } pDEVBLK->fd = -1; // indicate we're now closed return 0; }
/*-------------------------------------------------------------------*/ static int ARCH_DEP(scedio_request)(U32 sclp_command, SCCB_EVD_HDR *evd_hdr) { SCCB_SCEDIO_BK *scedio_bk = (SCCB_SCEDIO_BK*)(evd_hdr + 1); SCCB_SCEDIOV_BK *scediov_bk; SCCB_SCEDIOR_BK *scedior_bk; int rc; static struct { SCCB_SCEDIO_BK scedio_bk; union { SCCB_SCEDIOV_BK v; SCCB_SCEDIOR_BK r; } io; } static_scedio_bk ; static int scedio_pending; if(sclp_command == SCLP_READ_EVENT_DATA) { int pending_req = scedio_pending; U16 evd_len; /* Return no data if the scedio thread is still active */ if(scedio_tid) return 0; /* Update the scedio_bk copy in the SCCB */ if(scedio_pending) { /* Zero all fields */ memset (evd_hdr, 0, sizeof(SCCB_EVD_HDR)); /* Set type in event header */ evd_hdr->type = SCCB_EVD_TYPE_SCEDIO; /* Store scedio header */ *scedio_bk = static_scedio_bk.scedio_bk; /* Calculate event response length */ evd_len = sizeof(SCCB_EVD_HDR) + sizeof(SCCB_SCEDIO_BK); switch(scedio_bk->flag1) { case SCCB_SCEDIO_FLG1_IOR: scedior_bk = (SCCB_SCEDIOR_BK*)(scedio_bk + 1); *scedior_bk = static_scedio_bk.io.r; evd_len += sizeof(SCCB_SCEDIOR_BK); break; case SCCB_SCEDIO_FLG1_IOV: scediov_bk = (SCCB_SCEDIOV_BK*)(scedio_bk + 1); *scediov_bk = static_scedio_bk.io.v ; evd_len += sizeof(SCCB_SCEDIOV_BK); break; default: PTT(PTT_CL_ERR,"*SERVC",(U32)evd_hdr->type,(U32)scedio_bk->flag1,scedio_bk->flag3); } /* Set length in event header */ STORE_HW(evd_hdr->totlen, evd_len); } /* Reset the pending flag */ scedio_pending = 0; /* Return true if a request was pending */ return pending_req; } else { #if !defined(NO_SIGABEND_HANDLER) switch(scedio_bk->flag1) { case SCCB_SCEDIO_FLG1_IOV: scediov_bk = (SCCB_SCEDIOV_BK*)(scedio_bk + 1); switch(scediov_bk->type) { case SCCB_SCEDIOV_TYPE_INIT: /* Kill the scedio thread if it is active */ if( scedio_tid ) { OBTAIN_INTLOCK(NULL); signal_thread(scedio_tid, SIGKILL); scedio_tid = 0; scedio_pending = 0; RELEASE_INTLOCK(NULL); } break; } break; } #endif /* Take a copy of the scedio_bk in the SCCB */ static_scedio_bk.scedio_bk = *scedio_bk; switch(scedio_bk->flag1) { case SCCB_SCEDIO_FLG1_IOR: scedior_bk = (SCCB_SCEDIOR_BK*)(scedio_bk + 1); static_scedio_bk.io.r = *scedior_bk; break; case SCCB_SCEDIO_FLG1_IOV: scediov_bk = (SCCB_SCEDIOV_BK*)(scedio_bk + 1); static_scedio_bk.io.v = *scediov_bk; break; default: PTT(PTT_CL_ERR,"*SERVC",(U32)evd_hdr->type,(U32)scedio_bk->flag1,scedio_bk->flag3); } /* Create the scedio thread */ rc = create_thread(&scedio_tid, &sysblk.detattr, ARCH_DEP(scedio_thread), &static_scedio_bk, "scedio_thread"); if (rc) { WRMSG(HHC00102, "E", strerror(rc)); return -1; } scedio_pending = 1; } return 0; }
void call_start() { signal_thread(); }