int AO_compare_double_and_swap_double_emulation(volatile AO_double_t *addr, AO_t old_val1, AO_t old_val2, AO_t new_val1, AO_t new_val2) { AO_TS_t *my_lock = AO_locks + AO_HASH(addr); int result; # ifndef AO_USE_NO_SIGNALS sigset_t old_sigs; block_all_signals(&old_sigs); # endif lock(my_lock); if (addr -> AO_val1 == old_val1 && addr -> AO_val2 == old_val2) { addr -> AO_val1 = new_val1; addr -> AO_val2 = new_val2; result = 1; } else result = 0; unlock(my_lock); # ifndef AO_USE_NO_SIGNALS sigprocmask(SIG_SETMASK, &old_sigs, NULL); # endif return result; }
int main(int argc, char **argv) { char *command_name; rlwrap_command_line = unsplit_with(argc, argv, " "); init_completer(); /* Harvest options and leave optind pointing to first non-option argument: */ command_name = read_options_and_command_name(argc, argv); /* by now, optind points to slave <command>, and &argv[optind] is <command>'s argv. Remember slave command line: */ command_line = unsplit_with(argc - optind, argv, " "); /* if stdin is not a tty, just execute <command>: */ if (!isatty(STDIN_FILENO) && execvp(argv[optind], &argv[optind]) < 0) myerror(FATAL|USE_ERRNO, "Cannot execute %s", argv[optind]); init_rlwrap(rlwrap_command_line); install_signal_handlers(); block_all_signals(); fork_child(command_name, argv); /* this will unblock most signals most of the time */ if (filter_command) spawn_filter(filter_command); main_loop(); return 42; /* The Answer, but, sadly, we'll never get there.... */ }
int thr_sigsetmask(int how, const sigset_t *set, sigset_t *oset) { ulwp_t *self = curthread; sigset_t saveset; if (set == NULL) { enter_critical(self); if (oset != NULL) *oset = self->ul_sigmask; exit_critical(self); } else { switch (how) { case SIG_BLOCK: case SIG_UNBLOCK: case SIG_SETMASK: break; default: return (EINVAL); } /* * The assignments to self->ul_sigmask must be protected from * signals. The nuances of this code are subtle. Be careful. */ block_all_signals(self); if (oset != NULL) saveset = self->ul_sigmask; switch (how) { case SIG_BLOCK: self->ul_sigmask.__sigbits[0] |= set->__sigbits[0]; self->ul_sigmask.__sigbits[1] |= set->__sigbits[1]; self->ul_sigmask.__sigbits[2] |= set->__sigbits[2]; self->ul_sigmask.__sigbits[3] |= set->__sigbits[3]; break; case SIG_UNBLOCK: self->ul_sigmask.__sigbits[0] &= ~set->__sigbits[0]; self->ul_sigmask.__sigbits[1] &= ~set->__sigbits[1]; self->ul_sigmask.__sigbits[2] &= ~set->__sigbits[2]; self->ul_sigmask.__sigbits[3] &= ~set->__sigbits[3]; break; case SIG_SETMASK: self->ul_sigmask.__sigbits[0] = set->__sigbits[0]; self->ul_sigmask.__sigbits[1] = set->__sigbits[1]; self->ul_sigmask.__sigbits[2] = set->__sigbits[2]; self->ul_sigmask.__sigbits[3] = set->__sigbits[3]; break; } delete_reserved_signals(&self->ul_sigmask); if (oset != NULL) *oset = saveset; restore_signals(self); } return (0); }
int tdbio_end_transaction() { int rc; if( !in_transaction ) log_bug("tdbio: no active transaction\n"); take_write_lock (); block_all_signals(); in_transaction = 0; rc = tdbio_sync(); unblock_all_signals(); release_write_lock (); return rc; }
/* bg_man_pthreads_threadfunc: * Thread function for the background thread. */ static void *bg_man_pthreads_threadfunc(void *arg) { struct timeval old_time, new_time; struct timeval delay; unsigned long interval; int n; block_all_signals(); interval = 0; gettimeofday(&old_time, 0); while (thread_alive) { gettimeofday(&new_time, 0); /* add the new time difference to the remainder of the old difference */ interval += ((new_time.tv_sec - old_time.tv_sec) * 1000000L + (new_time.tv_usec - old_time.tv_usec)); old_time = new_time; /* run the callbacks for each 10ms elapsed, but limit to 18ms */ if (interval > 18000) interval = 18000; while (interval > 10000) { interval -= 10000; pthread_mutex_lock(&cli_mutex); /* wait until interrupts are enabled */ while (cli_count > 0) pthread_cond_wait(&cli_cond, &cli_mutex); /* call all the callbacks */ for (n = 0; n < max_func; n++) { if (funcs[n]) funcs[n](1); } pthread_mutex_unlock(&cli_mutex); } /* rest a little bit before checking again */ delay.tv_sec = 0; delay.tv_usec = 1000; select(0, NULL, NULL, NULL, &delay); } return NULL; }
void exit_program_code(int s) { block_all_signals(); log(L_INFO, "Exit program with value %d...\n", s); modem_close_port(); streamio_close(setup.vboxrc); lock_type_unlock(LCK_PID); lock_type_unlock(LCK_MODEM); log(L_INFO, "------------------------[End session]-----------------------\n"); log_exit(); exit(s); }
AO_t AO_fetch_compare_and_swap_emulation(volatile AO_t *addr, AO_t old_val, AO_t new_val) { AO_TS_t *my_lock = AO_locks + AO_HASH(addr); AO_t fetched_val; # ifndef AO_USE_NO_SIGNALS sigset_t old_sigs; block_all_signals(&old_sigs); # endif lock(my_lock); fetched_val = *addr; if (fetched_val == old_val) *addr = new_val; unlock(my_lock); # ifndef AO_USE_NO_SIGNALS sigprocmask(SIG_SETMASK, &old_sigs, NULL); # endif return fetched_val; }
int main(int argc, char **argv) { char *command_name; init_completer(); command_name = read_options_and_command_name(argc, argv); /* by now, optind points to <command>, and &argv[optind] is <command>'s argv */ if (!isatty(STDIN_FILENO) && execvp(argv[optind], &argv[optind]) < 0) /* if stdin is not a tty, just execute <command> */ myerror("Cannot execute %s", argv[optind]); init_rlwrap(); install_signal_handlers(); block_all_signals(); fork_child(command_name, argv); if (filter_command) spawn_filter(filter_command); main_loop(); return 42; /* not reached, but some compilers are unhappy without this ... */ }
int tdbio_end_transaction() { int rc; if( !in_transaction ) log_bug("tdbio: no active transaction\n"); if( !is_locked ) { if( make_dotlock( lockhandle, -1 ) ) log_fatal("can't acquire lock - giving up\n"); else is_locked = 1; } block_all_signals(); in_transaction = 0; rc = tdbio_sync(); unblock_all_signals(); if( !opt.lock_once ) { if( !release_dotlock( lockhandle ) ) is_locked = 0; } return rc; }
/* ptimer_thread_func: * The timer thread. */ static void *ptimer_thread_func(void *unused) { struct timeval old_time; struct timeval new_time; struct timeval delay; long interval = 0x8000; #ifdef ALLEGRO_HAVE_POSIX_MONOTONIC_CLOCK struct timespec old_time_ns; struct timespec new_time_ns; int clock_monotonic; #endif block_all_signals(); #ifdef ALLEGRO_LINUX_VGA /* privileges hack for Linux: * One of the jobs of the timer thread is to update the mouse pointer * on screen. When using the Mode-X driver under Linux console, this * involves selecting different planes (in modexgfx.s), which requires * special priviledges. */ if ((system_driver == &system_linux) && (__al_linux_have_ioperms)) { seteuid(0); iopl(3); seteuid(getuid()); } #endif #ifdef ALLEGRO_QNX /* thread priority adjustment for QNX: * The timer thread is set to the highest relative priority. * (see the comment in src/qnx/qsystem.c about the scheduling policy) */ { struct sched_param sparam; int spolicy; if (pthread_getschedparam(pthread_self(), &spolicy, &sparam) == EOK) { sparam.sched_priority += 4; pthread_setschedparam(pthread_self(), spolicy, &sparam); } } #endif #ifdef ALLEGRO_HAVE_POSIX_MONOTONIC_CLOCK /* clock_gettime(CLOCK_MONOTONIC, ...) is preferable to gettimeofday() in * case the system time is changed while the program is running. * CLOCK_MONOTONIC is not available on all systems. */ clock_monotonic = (clock_gettime(CLOCK_MONOTONIC, &old_time_ns) == 0); #endif gettimeofday(&old_time, 0); while (thread_alive) { /* `select' is more accurate than `usleep' on my system. */ delay.tv_sec = interval / TIMERS_PER_SECOND; delay.tv_usec = TIMER_TO_USEC(interval) % 1000000L; select(0, NULL, NULL, NULL, &delay); /* Calculate actual time elapsed. */ #ifdef ALLEGRO_HAVE_POSIX_MONOTONIC_CLOCK if (clock_monotonic) { clock_gettime(CLOCK_MONOTONIC, &new_time_ns); interval = USEC_TO_TIMER( (new_time_ns.tv_sec - old_time_ns.tv_sec) * 1000000L + (new_time_ns.tv_nsec - old_time_ns.tv_nsec) / 1000); old_time_ns = new_time_ns; } else #endif { gettimeofday(&new_time, 0); interval = USEC_TO_TIMER( (new_time.tv_sec - old_time.tv_sec) * 1000000L + (new_time.tv_usec - old_time.tv_usec)); old_time = new_time; } /* Handle a tick. */ interval = _handle_timer_tick(interval); } return NULL; }
int tdfx_lock(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; DECLARE_WAITQUEUE(entry, current); int ret = 0; drm_lock_t lock; #if DRM_DMA_HISTOGRAM cycles_t start; dev->lck_start = start = get_cycles(); #endif if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock))) return -EFAULT; if (lock.context == DRM_KERNEL_CONTEXT) { DRM_ERROR("Process %d using kernel context %d\n", current->pid, lock.context); return -EINVAL; } DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n", lock.context, current->pid, dev->lock.hw_lock->lock, lock.flags); #if 0 /* dev->queue_count == 0 right now for tdfx. FIXME? */ if (lock.context < 0 || lock.context >= dev->queue_count) return -EINVAL; #endif if (!ret) { #if 0 if (_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock) != lock.context) { long j = jiffies - dev->lock.lock_time; if (lock.context == tdfx_res_ctx.handle && j >= 0 && j < DRM_LOCK_SLICE) { /* Can't take lock if we just had it and there is contention. */ DRM_DEBUG("%d (pid %d) delayed j=%d dev=%d jiffies=%d\n", lock.context, current->pid, j, dev->lock.lock_time, jiffies); current->state = TASK_INTERRUPTIBLE; schedule_timeout(DRM_LOCK_SLICE-j); DRM_DEBUG("jiffies=%d\n", jiffies); } } #endif add_wait_queue(&dev->lock.lock_queue, &entry); for (;;) { current->state = TASK_INTERRUPTIBLE; if (!dev->lock.hw_lock) { /* Device has been unregistered */ ret = -EINTR; break; } if (drm_lock_take(&dev->lock.hw_lock->lock, lock.context)) { dev->lock.pid = current->pid; dev->lock.lock_time = jiffies; atomic_inc(&dev->total_locks); break; /* Got lock */ } /* Contention */ atomic_inc(&dev->total_sleeps); yield(); if (signal_pending(current)) { ret = -ERESTARTSYS; break; } } current->state = TASK_RUNNING; remove_wait_queue(&dev->lock.lock_queue, &entry); } #if 0 if (!ret && dev->last_context != lock.context && lock.context != tdfx_res_ctx.handle && dev->last_context != tdfx_res_ctx.handle) { add_wait_queue(&dev->context_wait, &entry); current->state = TASK_INTERRUPTIBLE; /* PRE: dev->last_context != lock.context */ tdfx_context_switch(dev, dev->last_context, lock.context); /* POST: we will wait for the context switch and will dispatch on a later call when dev->last_context == lock.context NOTE WE HOLD THE LOCK THROUGHOUT THIS TIME! */ yield(); current->state = TASK_RUNNING; remove_wait_queue(&dev->context_wait, &entry); if (signal_pending(current)) { ret = -EINTR; } else if (dev->last_context != lock.context) { DRM_ERROR("Context mismatch: %d %d\n", dev->last_context, lock.context); } } #endif if (!ret) { sigemptyset(&dev->sigmask); sigaddset(&dev->sigmask, SIGSTOP); sigaddset(&dev->sigmask, SIGTSTP); sigaddset(&dev->sigmask, SIGTTIN); sigaddset(&dev->sigmask, SIGTTOU); dev->sigdata.context = lock.context; dev->sigdata.lock = dev->lock.hw_lock; block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); if (lock.flags & _DRM_LOCK_READY) { /* Wait for space in DMA/FIFO */ } if (lock.flags & _DRM_LOCK_QUIESCENT) { /* Make hardware quiescent */ #if 0 tdfx_quiescent(dev); #endif } } #if LINUX_VERSION_CODE < 0x020400 if (lock.context != tdfx_res_ctx.handle) { current->counter = 5; current->priority = DEF_PRIORITY/4; } #endif DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock"); #if DRM_DMA_HISTOGRAM atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]); #endif return ret; }
void timer_tick_thread() { int tmpi; unsigned long delay_clock; // 延迟的tick数,每秒钟会有1193181L个tick数 unsigned long used_clock; #ifdef WIN32 DWORD prev_time; // 毫秒 DWORD curr_time; DWORD diff_time; LARGE_INTEGER curr_counter; LARGE_INTEGER prev_counter; LARGE_INTEGER diff_counter; DWORD result; DWORD dwDelayMilliseceonds; if( s_is_high_timer ) QueryPerformanceCounter(&prev_counter); else prev_time = timeGetTime(); //1,193,181L #else struct timeval prev_time; struct timeval curr_time; struct timeval diff_time; struct timeval delay; block_all_signals(); gettimeofday(&prev_time, 0); #endif delay_clock = used_clock = 0x8000; while( 1 ) { #ifdef WIN32 dwDelayMilliseceonds = CLOCK_TO_MSEC(delay_clock); if ( dwDelayMilliseceonds < 15 ) dwDelayMilliseceonds = 15; result = WaitForSingleObject( s_timer_stop_event, dwDelayMilliseceonds ); if (result != WAIT_TIMEOUT) return; if( s_is_high_timer ) { QueryPerformanceCounter(&curr_counter); diff_counter.QuadPart = curr_counter.QuadPart - prev_counter.QuadPart; prev_counter.QuadPart = curr_counter.QuadPart; used_clock = COUNTER_TO_CLOCK( diff_counter.QuadPart ); } else { curr_time = timeGetTime(); //1,193,181L diff_time = curr_time - prev_time; prev_time = curr_time; used_clock = MSEC_TO_CLOCK( diff_time ); } #else if( s_timer_stop_event ) return; delay.tv_sec = delay_clock / CLOCK_PER_SECOND; delay.tv_usec = CLOCK_TO_USEC(delay_clock) % 1000000L; select(0, NULL, NULL, NULL, &delay); gettimeofday(&curr_time, 0); diff_time.tv_sec = curr_time.tv_sec - prev_time.tv_sec; diff_time.tv_usec = curr_time.tv_usec - prev_time.tv_usec; prev_time = curr_time; used_clock = USEC_TO_CLOCK(diff_time.tv_sec * 1000000L + diff_time.tv_usec); #endif delay_clock = 0x8000; for( tmpi = 0; tmpi<MAX_TIMER; tmpi++ ) { if ( (s_timer[tmpi].m_processfunc) && (s_timer[tmpi].m_speed > 0) ) { s_timer[tmpi].m_counter -= used_clock; while( s_timer[tmpi].m_counter <= 0 ) { s_timer[tmpi].m_counter += s_timer[tmpi].m_speed; s_timer[tmpi].m_processfunc( s_timer[tmpi].m_parameter ); } if ( (unsigned long)s_timer[tmpi].m_counter < delay_clock ) { delay_clock = s_timer[tmpi].m_counter; } } } } }
int setcontext(const ucontext_t *ucp) { ulwp_t *self = curthread; int ret; ucontext_t uc; /* * Returning from the main context (uc_link == NULL) causes * the thread to exit. See setcontext(2) and makecontext(3C). */ if (ucp == NULL) thr_exit(NULL); (void) memcpy(&uc, ucp, sizeof (uc)); /* * Restore previous signal mask and context link. */ if (uc.uc_flags & UC_SIGMASK) { block_all_signals(self); delete_reserved_signals(&uc.uc_sigmask); self->ul_sigmask = uc.uc_sigmask; if (self->ul_cursig) { /* * We have a deferred signal present. * The signal mask will be set when the * signal is taken in take_deferred_signal(). */ ASSERT(self->ul_critical + self->ul_sigdefer != 0); uc.uc_flags &= ~UC_SIGMASK; } } self->ul_siglink = uc.uc_link; /* * We don't know where this context structure has been. * Preserve the curthread pointer, at least. * * Allow this feature to be disabled if a particular process * requests it. */ if (setcontext_enforcement) { #if defined(__sparc) uc.uc_mcontext.gregs[REG_G7] = (greg_t)self; #elif defined(__amd64) uc.uc_mcontext.gregs[REG_FS] = (greg_t)0; /* null for fsbase */ #elif defined(__i386) uc.uc_mcontext.gregs[GS] = (greg_t)LWPGS_SEL; #else #error "none of __sparc, __amd64, __i386 defined" #endif } /* * Make sure that if we return to a call to __lwp_park() * or ___lwp_cond_wait() that it returns right away * (giving us a spurious wakeup but not a deadlock). */ set_parking_flag(self, 0); self->ul_sp = 0; ret = __setcontext(&uc); /* * It is OK for setcontext() to return if the user has not specified * UC_CPU. */ if (uc.uc_flags & UC_CPU) thr_panic("setcontext(): __setcontext() returned"); return (ret); }