/* * Helper function that actually kicks off the command on the libpq connection. */ static void dispatchCommand(CdbDispatchResult * dispatchResult, const char *query_text, int query_text_len) { SegmentDatabaseDescriptor *segdbDesc = dispatchResult->segdbDesc; TimestampTz beforeSend = 0; long secs; int usecs; if (DEBUG1 >= log_min_messages) beforeSend = GetCurrentTimestamp(); if (PQisBusy(segdbDesc->conn)) elog(LOG, "Trying to send to busy connection %s: asyncStatus %d", segdbDesc->whoami, segdbDesc->conn->asyncStatus); if (cdbconn_isBadConnection(segdbDesc)) { char *msg = PQerrorMessage(dispatchResult->segdbDesc->conn); dispatchResult->stillRunning = false; ereport(ERROR, (errcode(ERRCODE_GP_INTERCONNECTION_ERROR), errmsg("Connection lost before dispatch to segment %s: %s", dispatchResult->segdbDesc->whoami, msg ? msg : "unknown error"))); } /* * Submit the command asynchronously. */ if (PQsendGpQuery_shared(dispatchResult->segdbDesc->conn, (char *) query_text, query_text_len) == 0) { char *msg = PQerrorMessage(dispatchResult->segdbDesc->conn); dispatchResult->stillRunning = false; ereport(ERROR, (errcode(ERRCODE_GP_INTERCONNECTION_ERROR), errmsg("Command could not be dispatch to segment %s: %s", dispatchResult->segdbDesc->whoami, msg ? msg : "unknown error"))); } if (DEBUG1 >= log_min_messages) { TimestampDifference(beforeSend, GetCurrentTimestamp(), &secs, &usecs); if (secs != 0 || usecs > 1000) /* Time > 1ms? */ elog(LOG, "time for PQsendGpQuery_shared %ld.%06d", secs, usecs); } /* * We'll keep monitoring this QE -- whether or not the command * was dispatched -- in order to check for a lost connection * or any other errors that libpq might have in store for us. */ dispatchResult->stillRunning = true; dispatchResult->hasDispatched = true; ELOG_DISPATCHER_DEBUG("Command dispatched to QE (%s)", dispatchResult->segdbDesc->whoami); }
void RunTerminals(int numTerminals) { int i, j; int terminalWarehouseID, terminalDistrictID; int usedTerminal[configWhseCount][10]; pthread_t tid[numTerminals]; pthread_barrier_t barrier; TransState* StateInfo=(TransState*)malloc(sizeof(TransState)*numTerminals); i=pthread_barrier_init(&barrier, NULL, numTerminals); if(i != 0) { printf("[ERROR]Coundn't create the barrier\n"); exit(-1); } int cycle; for(i=0;i<configWhseCount;i++) for(j=0;j<10;j++) usedTerminal[i][j]=0; sessionStartTimestamp=GetCurrentTimestamp(); for(i=0;i<numTerminals;i++) { cycle=0; do { terminalWarehouseID=(int)GlobalRandomNumber(1, configWhseCount); terminalDistrictID=(int)GlobalRandomNumber(1, 10); cycle++; }while(usedTerminal[terminalWarehouseID-1][terminalDistrictID-1]); usedTerminal[terminalWarehouseID-1][terminalDistrictID-1]=1; printf("terminal %d is running, w_id=%d, d_id=%d\n",i,terminalWarehouseID,terminalDistrictID); runTerminal(terminalWarehouseID, terminalDistrictID, &tid[i], &barrier, &StateInfo[i]); sleep(SleepTime); } for(i=0;i<numTerminals;i++) { pthread_join(tid[i], NULL); } sessionEndTimestamp=GetCurrentTimestamp(); pthread_barrier_destroy(&barrier); EndReport(StateInfo, numTerminals); }
/* * Helper function to thread_DispatchCommand that actually kicks off the * command on the libpq connection. * * NOTE: since this is called via a thread, the same rules apply as to * thread_DispatchCommand absolutely no elog'ing. */ static void dispatchCommand(CdbDispatchResult * dispatchResult, const char *query_text, int query_text_len) { SegmentDatabaseDescriptor *segdbDesc = dispatchResult->segdbDesc; PGconn *conn = segdbDesc->conn; TimestampTz beforeSend = 0; long secs; int usecs; if (DEBUG1 >= log_min_messages) beforeSend = GetCurrentTimestamp(); /* * Submit the command asynchronously. */ if (PQsendGpQuery_shared(conn, (char *) query_text, query_text_len) == 0) { char *msg = PQerrorMessage(segdbDesc->conn); if (DEBUG3 >= log_min_messages) write_log("PQsendMPPQuery_shared error %s %s", segdbDesc->whoami, msg ? msg : ""); /* * Note the error. */ cdbdisp_appendMessage(dispatchResult, LOG, ERRCODE_GP_INTERCONNECTION_ERROR, "Command could not be sent to segment db %s; %s", segdbDesc->whoami, msg ? msg : ""); PQfinish(conn); segdbDesc->conn = NULL; dispatchResult->stillRunning = false; } if (DEBUG1 >= log_min_messages) { TimestampDifference(beforeSend, GetCurrentTimestamp(), &secs, &usecs); if (secs != 0 || usecs > 1000) /* Time > 1ms? */ write_log("time for PQsendGpQuery_shared %ld.%06d", secs, usecs); } dispatchResult->hasDispatched = true; /* * We'll keep monitoring this QE -- whether or not the command * was dispatched -- in order to check for a lost connection * or any other errors that libpq might have in store for us. */ }
/* * Cancel the specified timeout. * * The timeout's I've-been-fired indicator is reset, * unless keep_indicator is true. * * When a timeout is canceled, any other active timeout remains in force. * It's not an error to disable a timeout that is not enabled. */ void disable_timeout(TimeoutId id, bool keep_indicator) { int i; /* Assert request is sane */ Assert(all_timeouts_initialized); Assert(all_timeouts[id].timeout_handler != NULL); /* Disable timeout interrupts for safety. */ disable_alarm(); /* Find the timeout and remove it from the active list. */ i = find_active_timeout(id); if (i >= 0) remove_timeout_index(i); /* Mark it inactive, whether it was active or not. */ if (!keep_indicator) all_timeouts[id].indicator = false; /* Reschedule the interrupt, if any timeouts remain active. */ if (num_active_timeouts > 0) schedule_alarm(GetCurrentTimestamp()); }
/* * Returns the replication apply delay in ms */ int GetReplicationApplyDelay(void) { /* use volatile pointer to prevent code rearrangement */ volatile WalRcvData *walrcv = WalRcv; XLogRecPtr receivePtr; XLogRecPtr replayPtr; long secs; int usecs; SpinLockAcquire(&walrcv->mutex); receivePtr = walrcv->receivedUpto; SpinLockRelease(&walrcv->mutex); replayPtr = GetXLogReplayRecPtr(NULL); if (XLByteLE(receivePtr, replayPtr)) return 0; TimestampDifference(GetCurrentChunkReplayStartTime(), GetCurrentTimestamp(), &secs, &usecs); return (((int) secs * 1000) + (usecs / 1000)); }
/* * Create a new file set * type is the WorkFileType for the files: BUFFILE or BFZ * can_be_reused: if set to false, then we don't insert this set into the cache, * since the caller is telling us there is no point. This can happen for * example when spilling during index creation. * ps is the PlanState for the subtree rooted at the operator * snapshot contains snapshot information for the current transaction * */ workfile_set * workfile_mgr_create_set(enum ExecWorkFileType type, bool can_be_reused, PlanState *ps) { Assert(NULL != workfile_mgr_cache); Plan *plan = NULL; if (ps != NULL) { plan = ps->plan; } AssertImply(can_be_reused, plan != NULL); NodeTag node_type = T_Invalid; if (ps != NULL) { node_type = ps->type; } char *dir_path = create_workset_directory(node_type, currentSliceId); if (!workfile_sets_resowner_callback_registered) { RegisterResourceReleaseCallback(workfile_set_free_callback, NULL); workfile_sets_resowner_callback_registered = true; } /* Create parameter info for the populate function */ workset_info set_info; set_info.file_type = type; set_info.nodeType = node_type; set_info.dir_path = dir_path; set_info.session_start_time = GetCurrentTimestamp(); set_info.operator_work_mem = get_operator_work_mem(ps); CacheEntry *newEntry = Cache_AcquireEntry(workfile_mgr_cache, &set_info); if (NULL == newEntry) { /* Clean up the directory we created. */ workfile_mgr_delete_set_directory(dir_path); /* Could not acquire another entry from the cache - we filled it up */ ereport(ERROR, (errmsg("could not create workfile manager entry: exceeded number of concurrent spilling queries"))); } /* Path has now been copied to the workfile_set. We can free it */ pfree(dir_path); /* Complete initialization of the entry with post-acquire actions */ Assert(NULL != newEntry); workfile_set *work_set = CACHE_ENTRY_PAYLOAD(newEntry); Assert(work_set != NULL); elog(gp_workfile_caching_loglevel, "new spill file set. key=0x%x prefix=%s opMemKB=" INT64_FORMAT, work_set->key, work_set->path, work_set->metadata.operator_work_mem); return work_set; }
/* * Cancel multiple timeouts at once. * * The timeouts' I've-been-fired indicators are reset, * unless timeouts[i].keep_indicator is true. * * This works like calling disable_timeout() multiple times. * Use this to reduce the number of GetCurrentTimestamp() * and setitimer() calls needed to cancel multiple timeouts. */ void disable_timeouts(const DisableTimeoutParams *timeouts, int count) { int i; Assert(all_timeouts_initialized); /* Disable timeout interrupts for safety. */ disable_alarm(); /* Cancel the timeout(s). */ for (i = 0; i < count; i++) { TimeoutId id = timeouts[i].id; int idx; Assert(all_timeouts[id].timeout_handler != NULL); idx = find_active_timeout(id); if (idx >= 0) remove_timeout_index(idx); if (!timeouts[i].keep_indicator) all_timeouts[id].indicator = false; } /* Reschedule the interrupt, if any timeouts remain active. */ if (num_active_timeouts > 0) schedule_alarm(GetCurrentTimestamp()); }
/* * UpdateTimeAtomically * * Updates a OOMTimeType variable atomically, using compare_and_swap_* */ void UpdateTimeAtomically(volatile OOMTimeType* time_var) { bool updateCompleted = false; OOMTimeType newOOMTime; while (!updateCompleted) { #if defined(__x86_64__) newOOMTime = GetCurrentTimestamp(); #else struct timeval curTime; gettimeofday(&curTime, NULL); newOOMTime = (uint32)curTime.tv_sec; #endif OOMTimeType oldOOMTime = *time_var; #if defined(__x86_64__) updateCompleted = compare_and_swap_64((uint64*)time_var, (uint64)oldOOMTime, (uint64)newOOMTime); #else updateCompleted = compare_and_swap_32((uint32*)time_var, (uint32)oldOOMTime, (uint32)newOOMTime); #endif } }
/* * Returns the replication apply delay in ms or -1 * if the apply delay info is not available */ int GetReplicationApplyDelay(void) { WalRcvData *walrcv = WalRcv; XLogRecPtr receivePtr; XLogRecPtr replayPtr; long secs; int usecs; TimestampTz chunkReplayStartTime; SpinLockAcquire(&walrcv->mutex); receivePtr = walrcv->receivedUpto; SpinLockRelease(&walrcv->mutex); replayPtr = GetXLogReplayRecPtr(NULL); if (receivePtr == replayPtr) return 0; chunkReplayStartTime = GetCurrentChunkReplayStartTime(); if (chunkReplayStartTime == 0) return -1; TimestampDifference(chunkReplayStartTime, GetCurrentTimestamp(), &secs, &usecs); return (((int) secs * 1000) + (usecs / 1000)); }
/* * Standby wait logic for ResolveRecoveryConflictWithVirtualXIDs. * We wait here for a while then return. If we decide we can't wait any * more then we return true, if we can wait some more return false. */ static bool WaitExceedsMaxStandbyDelay(void) { TimestampTz ltime; /* Are we past the limit time? */ ltime = GetStandbyLimitTime(); if (ltime && GetCurrentTimestamp() >= ltime) return true; /* * Sleep a bit (this is essential to avoid busy-waiting). */ pg_usleep(standbyWait_us); /* * Progressively increase the sleep times, but not to more than 1s, since * pg_usleep isn't interruptable on some platforms. */ standbyWait_us *= 2; if (standbyWait_us > 1000000) standbyWait_us = 1000000; return false; }
/* * Marks the current process as idle; i.e., it is no longer able to respond * to a runaway cleanup. However, before it returns from this method, it * would trigger one last runaway cleanup for a pre-dactivation era runaway * event, if necessary. */ void IdleTracker_DeactivateProcess() { if (NULL != MySessionState) { /* * Verify that deactivation during proc_exit_inprogress is protected in * critical section or the interrupt is disabled so that we don't attempt * any runaway cleanup */ AssertImply(proc_exit_inprogress, CritSectionCount > 0 || InterruptHoldoffCount > 0); /* * When an idle process receives a SIGTERM process, the signal handler * die() calls the cleanup directly, so we get here for an idle process. * Instead of re-activating it forcefully, just special case it * and don't do anything during process exit for already inactive processes. */ if (proc_exit_inprogress && ! isProcessActive) { Assert(deactivationVersion >= activationVersion); return; } Assert(isProcessActive); Assert(deactivationVersion <= activationVersion); /* No new runaway event can come in */ SpinLockAcquire(&MySessionState->spinLock); Assert(MySessionState->activeProcessCount <= MySessionState->pinCount); /* No atomic update necessary as the update is protected by spin lock */ MySessionState->activeProcessCount -= 1; Assert(0 <= MySessionState->activeProcessCount); MySessionState->idle_start = GetCurrentTimestamp(); isProcessActive = false; /* Save the point where we reduced the activeProcessCount */ deactivationVersion = *CurrentVersion; /* * Release spinLock as we no longer contend for isRunaway. */ SpinLockRelease(&MySessionState->spinLock); /* * We are still deactivated (i.e., activeProcessCount is decremented). If an ERROR is indeed thrown * from the VmemTracker_StartCleanupIfRunaway, the VmemTracker_RunawayCleanupDoneForProcess() * method would reactivate this process. */ RunawayCleaner_StartCleanup(); /* At this point the process must be clean, unless we don't have a runaway event before deactivation */ Assert(*latestRunawayVersion > deactivationVersion || !RunawayCleaner_IsCleanupInProgress()); } /* At this point the process is ready to be blocked in ReadCommand() */ }
/* * Check if the remote end has closed the connection. */ static void ProcessRepliesIfAny(void) { unsigned char firstchar; int r; bool received = false; for (;;) { r = pq_getbyte_if_available(&firstchar); if (r < 0) { /* unexpected error or EOF */ ereport(COMMERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("unexpected EOF on standby connection"))); proc_exit(0); } if (r == 0) { /* no data available without blocking */ break; } /* Handle the very limited subset of commands expected in this phase */ switch (firstchar) { /* * 'd' means a standby reply wrapped in a CopyData packet. */ case 'd': ProcessStandbyMessage(); received = true; break; /* * 'X' means that the standby is closing down the socket. */ case 'X': proc_exit(0); default: ereport(FATAL, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("invalid standby message type \"%c\"", firstchar))); } } /* * Save the last reply timestamp if we've received at least one reply. */ if (received) last_reply_timestamp = GetCurrentTimestamp(); }
/* * Check for statement timeout. If the timeout time has come, * trigger a query-cancel interrupt; if not, reschedule the SIGALRM * interrupt to occur at the right time. * * Returns true if okay, false if failed to set the interrupt. */ static bool CheckStatementTimeout(void) { TimestampTz now; if (!statement_timeout_active) return true; /* do nothing if not active */ /* QD takes care of timeouts for QE. */ if (Gp_role == GP_ROLE_EXECUTE) return true; now = GetCurrentTimestamp(); if (now >= statement_fin_time) { /* Time to die */ statement_timeout_active = false; cancel_from_timeout = true; elog(LOG,"Issuing cancel signal (SIGINT) to my self (pid = %d) for statement timeout.", MyProcPid); #ifdef HAVE_SETSID /* try to signal whole process group */ kill(-MyProcPid, SIGINT); #endif kill(MyProcPid, SIGINT); } else { /* Not time yet, so (re)schedule the interrupt */ long secs; int usecs; struct itimerval timeval; TimestampDifference(now, statement_fin_time, &secs, &usecs); /* * It's possible that the difference is less than a microsecond; * ensure we don't cancel, rather than set, the interrupt. */ if (secs == 0 && usecs == 0) usecs = 1; MemSet(&timeval, 0, sizeof(struct itimerval)); timeval.it_value.tv_sec = secs; timeval.it_value.tv_usec = usecs; if (setitimer(ITIMER_REAL, &timeval, NULL)) return false; } return true; }
/* * ResolveRecoveryConflictWithBufferPin is called from LockBufferForCleanup() * to resolve conflicts with other backends holding buffer pins. * * We either resolve conflicts immediately or set a SIGALRM to wake us at * the limit of our patience. The sleep in LockBufferForCleanup() is * performed here, for code clarity. * * Resolve conflicts by sending a PROCSIG signal to all backends to check if * they hold one of the buffer pins that is blocking Startup process. If so, * backends will take an appropriate error action, ERROR or FATAL. * * We also must check for deadlocks. Deadlocks occur because if queries * wait on a lock, that must be behind an AccessExclusiveLock, which can only * be cleared if the Startup process replays a transaction completion record. * If Startup process is also waiting then that is a deadlock. The deadlock * can occur if the query is waiting and then the Startup sleeps, or if * Startup is sleeping and the query waits on a lock. We protect against * only the former sequence here, the latter sequence is checked prior to * the query sleeping, in CheckRecoveryConflictDeadlock(). * * Deadlocks are extremely rare, and relatively expensive to check for, * so we don't do a deadlock check right away ... only if we have had to wait * at least deadlock_timeout. Most of the logic about that is in proc.c. */ void ResolveRecoveryConflictWithBufferPin(void) { bool sig_alarm_enabled = false; TimestampTz ltime; TimestampTz now; Assert(InHotStandby); ltime = GetStandbyLimitTime(); now = GetCurrentTimestamp(); if (!ltime) { /* * We're willing to wait forever for conflicts, so set timeout for * deadlock check (only) */ if (enable_standby_sig_alarm(now, now, true)) sig_alarm_enabled = true; else elog(FATAL, "could not set timer for process wakeup"); } else if (now >= ltime) { /* * We're already behind, so clear a path as quickly as possible. */ SendRecoveryConflictWithBufferPin(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN); } else { /* * Wake up at ltime, and check for deadlocks as well if we will be * waiting longer than deadlock_timeout */ if (enable_standby_sig_alarm(now, ltime, false)) sig_alarm_enabled = true; else elog(FATAL, "could not set timer for process wakeup"); } /* Wait to be signaled by UnpinBuffer() */ ProcWaitForSignal(); if (sig_alarm_enabled) { if (!disable_standby_sig_alarm()) elog(FATAL, "could not disable timer for process wakeup"); } }
/* * Reschedule any pending SIGALRM interrupt. * * This can be used during error recovery in case query cancel resulted in loss * of a SIGALRM event (due to longjmp'ing out of handle_sig_alarm before it * could do anything). But note it's not necessary if any of the public * enable_ or disable_timeout functions are called in the same area, since * those all do schedule_alarm() internally if needed. */ void reschedule_timeouts(void) { /* For flexibility, allow this to be called before we're initialized. */ if (!all_timeouts_initialized) return; /* Disable timeout interrupts for safety. */ disable_alarm(); /* Reschedule the interrupt, if any timeouts remain active. */ if (num_active_timeouts > 0) schedule_alarm(GetCurrentTimestamp()); }
/* * Enable the specified timeout to fire at the specified time. * * This is provided to support cases where there's a reason to calculate * the timeout by reference to some point other than "now". If there isn't, * use enable_timeout_after(), to avoid calling GetCurrentTimestamp() twice. */ void enable_timeout_at(TimeoutId id, TimestampTz fin_time) { TimestampTz now; /* Disable timeout interrupts for safety. */ disable_alarm(); /* Queue the timeout at the appropriate time. */ now = GetCurrentTimestamp(); enable_timeout(id, now, fin_time); /* Set the timer interrupt. */ schedule_alarm(now); }
/* * InitPerProcessOOMTracking * * Initializes per-process OOM tracking data structures. */ void InitPerProcessOOMTracking() { Assert(NULL != segmentOOMTime); alreadyReportedOOMTime = 0; #if defined(__x86_64__) oomTrackerStartTime = GetCurrentTimestamp(); #else struct timeval curTime; gettimeofday(&curTime, NULL); oomTrackerStartTime = (uint32)curTime.tv_sec; #endif }
/* update and return last updated with current timestamp */ Datum repmgr_update_last_updated(PG_FUNCTION_ARGS) { TimestampTz last_updated = GetCurrentTimestamp(); /* Safety check... */ if (!shared_state) PG_RETURN_NULL(); LWLockAcquire(shared_state->lock, LW_SHARED); shared_state->last_updated = last_updated; LWLockRelease(shared_state->lock); PG_RETURN_TIMESTAMPTZ(last_updated); }
/* * Fetch stored password for a user, for authentication. * * On error, returns NULL, and stores a palloc'd string describing the reason, * for the postmaster log, in *logdetail. The error reason should *not* be * sent to the client, to avoid giving away user information! */ char * get_role_password(const char *role, char **logdetail) { TimestampTz vuntil = 0; HeapTuple roleTup; Datum datum; bool isnull; char *shadow_pass; /* Get role info from pg_authid */ roleTup = SearchSysCache1(AUTHNAME, PointerGetDatum(role)); if (!HeapTupleIsValid(roleTup)) { *logdetail = psprintf(_("Role \"%s\" does not exist."), role); return NULL; /* no such user */ } datum = SysCacheGetAttr(AUTHNAME, roleTup, Anum_pg_authid_rolpassword, &isnull); if (isnull) { ReleaseSysCache(roleTup); *logdetail = psprintf(_("User \"%s\" has no password assigned."), role); return NULL; /* user has no password */ } shadow_pass = TextDatumGetCString(datum); datum = SysCacheGetAttr(AUTHNAME, roleTup, Anum_pg_authid_rolvaliduntil, &isnull); if (!isnull) vuntil = DatumGetTimestampTz(datum); ReleaseSysCache(roleTup); /* * Password OK, but check to be sure we are not past rolvaliduntil */ if (!isnull && vuntil < GetCurrentTimestamp()) { *logdetail = psprintf(_("User \"%s\" has an expired password."), role); return NULL; } return shadow_pass; }
static void WalSndKeepalive(char *msgbuf) { PrimaryKeepaliveMessage keepalive_message; /* Construct a new message */ keepalive_message.walEnd = sentPtr; keepalive_message.sendTime = GetCurrentTimestamp(); elog(DEBUG2, "sending replication keepalive"); /* Prepend with the message type and send it. */ msgbuf[0] = 'k'; memcpy(msgbuf + 1, &keepalive_message, sizeof(PrimaryKeepaliveMessage)); pq_putmessage_noblock('d', msgbuf, sizeof(PrimaryKeepaliveMessage) + 1); }
/* * Send reply message to primary, indicating our current XLOG positions and * the current time. */ static void XLogWalRcvSendReply(void) { char buf[sizeof(StandbyReplyMessage) + 1]; TimestampTz now; /* * If the user doesn't want status to be reported to the master, be sure * to exit before doing anything at all. */ if (wal_receiver_status_interval <= 0) return; /* Get current timestamp. */ now = GetCurrentTimestamp(); /* * We can compare the write and flush positions to the last message we * sent without taking any lock, but the apply position requires a spin * lock, so we don't check that unless something else has changed or 10 * seconds have passed. This means that the apply log position will * appear, from the master's point of view, to lag slightly, but since * this is only for reporting purposes and only on idle systems, that's * probably OK. */ if (XLByteEQ(reply_message.write, LogstreamResult.Write) && XLByteEQ(reply_message.flush, LogstreamResult.Flush) && !TimestampDifferenceExceeds(reply_message.sendTime, now, wal_receiver_status_interval * 1000)) return; /* Construct a new message. */ reply_message.write = LogstreamResult.Write; reply_message.flush = LogstreamResult.Flush; reply_message.apply = GetXLogReplayRecPtr(); reply_message.sendTime = now; elog(DEBUG2, "sending write %X/%X flush %X/%X apply %X/%X", reply_message.write.xlogid, reply_message.write.xrecoff, reply_message.flush.xlogid, reply_message.flush.xrecoff, reply_message.apply.xlogid, reply_message.apply.xrecoff); /* Prepend with the message type and send it. */ buf[0] = 'r'; memcpy(&buf[1], &reply_message, sizeof(StandbyReplyMessage)); walrcv_send(buf, sizeof(StandbyReplyMessage) + 1); }
/* * Enable the specified timeout to fire after the specified delay. * * Delay is given in milliseconds. */ void enable_timeout_after(TimeoutId id, int delay_ms) { TimestampTz now; TimestampTz fin_time; /* Disable timeout interrupts for safety. */ disable_alarm(); /* Queue the timeout at the appropriate time. */ now = GetCurrentTimestamp(); fin_time = TimestampTzPlusMilliseconds(now, delay_ms); enable_timeout(id, now, fin_time); /* Set the timer interrupt. */ schedule_alarm(now); }
/* * Resets the shared dictionary memory, i.e. removes all the dictionaries. This * is the only way to remove dictionaries from the memory - either when when * a dictionary is no longer needed or needs to be reloaded (e.g. to update * list of words / affixes). */ Datum dispell_reset(PG_FUNCTION_ARGS) { LWLockAcquire(segment_info->lock, LW_EXCLUSIVE); segment_info->dict = NULL; segment_info->stop = NULL; segment_info->lastReset = GetCurrentTimestamp(); segment_info->firstfree = ((char*)segment_info) + MAXALIGN(sizeof(SegmentInfo)); segment_info->available = max_ispell_mem_size - (int)(segment_info->firstfree - (char*)segment_info); memset(segment_info->firstfree, 0, segment_info->available); LWLockRelease(segment_info->lock); PG_RETURN_VOID(); }
/* * Get next block number or InvalidBlockNumber when we're done. * * Uses linear probing algorithm for picking next block. */ Datum tsm_system_time_nextblock(PG_FUNCTION_ARGS) { TableSampleDesc *tsdesc = (TableSampleDesc *) PG_GETARG_POINTER(0); SystemSamplerData *sampler = (SystemSamplerData *) tsdesc->tsmdata; sampler->lb = (sampler->lb + sampler->step) % sampler->nblocks; sampler->doneblocks++; /* All blocks have been read, we're done */ if (sampler->doneblocks > sampler->nblocks) PG_RETURN_UINT32(InvalidBlockNumber); /* * Update the estimations for time limit at least 10 times per estimated * number of returned blocks to handle variations in block read speed. */ if (sampler->doneblocks % Max(sampler->estblocks/10, 1) == 0) { TimestampTz now = GetCurrentTimestamp(); long secs; int usecs; int usecs_remaining; int time_per_block; TimestampDifference(sampler->start_time, now, &secs, &usecs); usecs += (int) secs * 1000000; time_per_block = usecs / sampler->doneblocks; /* No time left, end. */ TimestampDifference(now, sampler->end_time, &secs, &usecs); if (secs <= 0 && usecs <= 0) PG_RETURN_UINT32(InvalidBlockNumber); /* Remaining microseconds */ usecs_remaining = usecs + (int) secs * 1000000; /* Recalculate estimated returned number of blocks */ if (time_per_block < usecs_remaining && time_per_block > 0) sampler->estblocks = sampler->time * time_per_block; } PG_RETURN_UINT32(sampler->lb); }
/* * Reset state (called by ReScan). */ Datum tsm_system_time_reset(PG_FUNCTION_ARGS) { TableSampleDesc *tsdesc = (TableSampleDesc *) PG_GETARG_POINTER(0); SystemSamplerData *sampler = (SystemSamplerData *) tsdesc->tsmdata; sampler->lt = InvalidOffsetNumber; sampler->start_time = GetCurrentTimestamp(); sampler->end_time = TimestampTzPlusMilliseconds(sampler->start_time, sampler->time); sampler->estblocks = 2; sampler->doneblocks = 0; sampler_random_init_state(sampler->seed, sampler->randstate); sampler->step = random_relative_prime(sampler->nblocks, sampler->randstate); sampler->lb = sampler_random_fract(sampler->randstate) * (sampler->nblocks / sampler->step); PG_RETURN_VOID(); }
/* * Initializes the state. */ Datum tsm_system_time_init(PG_FUNCTION_ARGS) { TableSampleDesc *tsdesc = (TableSampleDesc *) PG_GETARG_POINTER(0); uint32 seed = PG_GETARG_UINT32(1); int32 time = PG_ARGISNULL(2) ? -1 : PG_GETARG_INT32(2); HeapScanDesc scan = tsdesc->heapScan; SystemSamplerData *sampler; if (time < 1) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("invalid time limit"), errhint("Time limit must be positive integer value."))); sampler = palloc0(sizeof(SystemSamplerData)); /* Remember initial values for reinit */ sampler->seed = seed; sampler->nblocks = scan->rs_nblocks; sampler->lt = InvalidOffsetNumber; sampler->estblocks = 2; sampler->doneblocks = 0; sampler->time = time; sampler->start_time = GetCurrentTimestamp(); sampler->end_time = TimestampTzPlusMilliseconds(sampler->start_time, sampler->time); sampler_random_init_state(sampler->seed, sampler->randstate); /* Find relative prime as step size for linear probing. */ sampler->step = random_relative_prime(sampler->nblocks, sampler->randstate); /* * Randomize start position so that blocks close to step size don't have * higher probability of being chosen on very short scan. */ sampler->lb = sampler_random_fract(sampler->randstate) * (sampler->nblocks / sampler->step); tsdesc->tsmdata = (void *) sampler; PG_RETURN_VOID(); }
/* * Keep track of important messages from primary. */ static void ProcessWalSndrMessage(XLogRecPtr walEnd, TimestampTz sendTime) { /* use volatile pointer to prevent code rearrangement */ volatile WalRcvData *walrcv = WalRcv; TimestampTz lastMsgReceiptTime = GetCurrentTimestamp(); /* Update shared-memory status */ SpinLockAcquire(&walrcv->mutex); walrcv->lastMsgSendTime = sendTime; walrcv->lastMsgReceiptTime = lastMsgReceiptTime; SpinLockRelease(&walrcv->mutex); elog(DEBUG2, "sendtime %s receipttime %s replication apply delay %d transfer latency %d", timestamptz_to_str(sendTime), timestamptz_to_str(lastMsgReceiptTime), GetReplicationApplyDelay(), GetReplicationTransferLatency()); }
/* * Probably the most important part of the startup - initializes the * memory in shared memory segment (creates and initializes the * SegmentInfo data structure). * * This is called from a shmem_startup_hook (see _PG_init). */ static void ispell_shmem_startup() { bool found = FALSE; char * segment; if (prev_shmem_startup_hook) prev_shmem_startup_hook(); elog(DEBUG1, "initializing shared ispell segment (size: %d B)", max_ispell_mem_size); /* * Create or attach to the shared memory state, including hash table */ LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE); segment = ShmemInitStruct(SEGMENT_NAME, max_ispell_mem_size, &found); /* Was the shared memory segment already initialized? */ if (! found) { memset(segment, 0, max_ispell_mem_size); segment_info = (SegmentInfo*)segment; segment_info->lock = LWLockAssign(); segment_info->firstfree = segment + MAXALIGN(sizeof(SegmentInfo)); segment_info->available = max_ispell_mem_size - (int)(segment_info->firstfree - segment); segment_info->lastReset = GetCurrentTimestamp(); elog(DEBUG1, "shared memory segment (shared ispell) successfully created"); } LWLockRelease(AddinShmemInitLock); }
HRESULT CWASAPIRenderFilter::AudioClock(ULONGLONG& pTimestamp, ULONGLONG& pQpc) { CAutoLock cAutoLock(&m_csClockLock); if (m_dClockPosIn == m_dClockPosOut || m_dClockDataCollectionCount < CLOCK_DATA_SIZE) return S_FALSE; //Log("m_dClockPosIn: %d m_dClockPosOut: %d diff: %I64u",m_dClockPosIn, m_dClockPosOut, m_ullHwClock[m_dClockPosIn] - m_ullHwClock[m_dClockPosOut] ); UINT64 clock = m_ullHwClock[m_dClockPosIn] - m_ullHwClock[m_dClockPosOut]; UINT64 qpc = m_ullHwQpc[m_dClockPosIn] - m_ullHwQpc[m_dClockPosOut]; if (qpc == 0) return S_FALSE; UINT64 qpcNow = GetCurrentTimestamp() - m_ullHwQpc[m_dClockPosOut]; pTimestamp = cMulDiv64(clock, qpcNow, qpc) + m_ullHwClock[m_dClockPosOut]; pQpc = qpcNow + m_ullHwQpc[m_dClockPosOut]; return S_OK; }
/* * Enable multiple timeouts at once. * * This works like calling enable_timeout_after() and/or enable_timeout_at() * multiple times. Use this to reduce the number of GetCurrentTimestamp() * and setitimer() calls needed to establish multiple timeouts. */ void enable_timeouts(const EnableTimeoutParams *timeouts, int count) { TimestampTz now; int i; /* Disable timeout interrupts for safety. */ disable_alarm(); /* Queue the timeout(s) at the appropriate times. */ now = GetCurrentTimestamp(); for (i = 0; i < count; i++) { TimeoutId id = timeouts[i].id; TimestampTz fin_time; switch (timeouts[i].type) { case TMPARAM_AFTER: fin_time = TimestampTzPlusMilliseconds(now, timeouts[i].delay_ms); enable_timeout(id, now, fin_time); break; case TMPARAM_AT: enable_timeout(id, now, timeouts[i].fin_time); break; default: elog(ERROR, "unrecognized timeout type %d", (int) timeouts[i].type); break; } } /* Set the timer interrupt. */ schedule_alarm(now); }