static void smbd_sig_handler(int sigval) { if (smbd.s_sigval == 0) (void) atomic_swap_uint(&smbd.s_sigval, sigval); if (sigval == SIGHUP) { atomic_inc_uint(&smbd.s_refreshes); (void) pthread_cond_signal(&refresh_cond); } if (sigval == SIGINT || sigval == SIGTERM) { smbd.s_shutting_down = B_TRUE; (void) pthread_cond_signal(&refresh_cond); } }
/*ARGSUSED*/ static void * smbd_refresh_monitor(void *arg) { smbd_online_wait("smbd_refresh_monitor"); while (!smbd.s_shutting_down) { (void) sleep(SMBD_REFRESH_INTERVAL); (void) pthread_mutex_lock(&refresh_mutex); while ((atomic_swap_uint(&smbd.s_refreshes, 0) == 0) && (!smbd.s_shutting_down)) (void) pthread_cond_wait(&refresh_cond, &refresh_mutex); (void) pthread_mutex_unlock(&refresh_mutex); if (smbd.s_shutting_down) { smbd_service_fini(); /*NOTREACHED*/ } (void) mutex_lock(&smbd_service_mutex); smbd_dc_monitor_refresh(); smb_ccache_remove(SMB_CCACHE_PATH); /* * Clear the DNS zones for the existing interfaces * before updating the NIC interface list. */ dyndns_clear_zones(); if (smbd_nicmon_refresh() != 0) smbd_report("NIC monitor refresh failed"); smb_netbios_name_reconfig(); smb_browser_reconfig(); dyndns_update_zones(); (void) smbd_kernel_bind(); smbd_load_shares(); smbd_load_printers(); (void) mutex_unlock(&smbd_service_mutex); } smbd.s_refresh_tid = 0; return (NULL); }
/* * Shutdown smbd and smbsrv kernel services. * * Shutdown will not begin until initialization has completed. * Only one thread is allowed to perform the shutdown. Other * threads will be blocked on fini_in_progress until the process * has exited. */ static void smbd_service_fini(void) { static uint_t fini_in_progress; (void) mutex_lock(&smbd_service_mutex); while (!smbd.s_initialized) (void) cond_wait(&smbd_service_cv, &smbd_service_mutex); if (atomic_swap_uint(&fini_in_progress, 1) != 0) { while (fini_in_progress) (void) cond_wait(&smbd_service_cv, &smbd_service_mutex); /*NOTREACHED*/ } smbd.s_shutting_down = B_TRUE; smbd_report("service shutting down"); smb_kmod_stop(); smb_logon_abort(); smb_lgrp_stop(); smbd_opipe_stop(); smbd_door_stop(); smbd_refresh_fini(); smbd_kernel_unbind(); smbd_share_stop(); smb_shr_stop(); dyndns_stop(); smbd_nicmon_stop(); smb_ccache_remove(SMB_CCACHE_PATH); smb_pwd_fini(); smb_domain_fini(); mlsvc_fini(); smb_netbios_stop(); smbd_cups_fini(); smbd.s_initialized = B_FALSE; smbd_report("service terminated"); (void) mutex_unlock(&smbd_service_mutex); exit((smbd.s_fatal_error) ? SMF_EXIT_ERR_FATAL : SMF_EXIT_OK); }
/* * Process IPIs for a CPU. */ int mips64_ipi_intr(void *arg) { unsigned int pending_ipis, bit; unsigned int cpuid = (unsigned int)(unsigned long)arg; KASSERT (cpuid == cpu_number()); /* clear ipi interrupt */ hw_ipi_intr_clear(cpuid); /* get and clear pending ipis */ pending_ipis = atomic_swap_uint(&ipi_mailbox[cpuid], 0); if (pending_ipis > 0) { for (bit = 0; bit < MIPS64_NIPIS; bit++) if (pending_ipis & (1UL << bit)) (*ipifuncs[bit])(); } return 1; }
void vnet_send_dring_data(struct vnet_softc *sc, uint32_t start_idx) { struct vio_dring_msg dm; u_int peer_state; peer_state = atomic_swap_uint(&sc->sc_peer_state, VIO_DP_ACTIVE); if (peer_state == VIO_DP_ACTIVE) return; bzero(&dm, sizeof(dm)); dm.tag.type = VIO_TYPE_DATA; dm.tag.stype = VIO_SUBTYPE_INFO; dm.tag.stype_env = VIO_DRING_DATA; dm.tag.sid = sc->sc_local_sid; dm.seq_no = sc->sc_seq_no++; dm.dring_ident = sc->sc_dring_ident; dm.start_idx = start_idx; dm.end_idx = -1; vnet_sendmsg(sc, &dm, sizeof(dm)); }
void *measure_thread(void *arg) { int c, i; int throughput; for (c = 1 ;; c++) { sleep(2); throughput = 0; for (i = 0; i < nthreads; i++) { #if defined(__sun) throughput += atomic_swap_uint(&counters[i], 0); #endif #if defined(linux) throughput += __sync_lock_test_and_set(&counters[i], 0); #endif } //printf("%d\t%d\n", c, throughput); printf("%d\n", throughput); fflush(stdout); } }
void x86_ipi_handler(void) { extern struct evcount ipi_count; struct cpu_info *ci = curcpu(); u_int32_t pending; int bit; int floor; floor = ci->ci_handled_intr_level; ci->ci_handled_intr_level = ci->ci_ilevel; pending = atomic_swap_uint(&ci->ci_ipis, 0); for (bit = 0; bit < X86_NIPI && pending; bit++) { if (pending & (1<<bit)) { pending &= ~(1<<bit); (*ipifunc[bit])(ci); ipi_count.ec_count++; } } ci->ci_handled_intr_level = floor; }
/* * Use SMF error codes only on return or exit. */ int main(int argc, char *argv[]) { struct sigaction act; sigset_t set; uid_t uid; int pfd = -1; uint_t sigval; struct rlimit rl; int orig_limit; smbd.s_pname = basename(argv[0]); openlog(smbd.s_pname, LOG_PID | LOG_NOWAIT, LOG_DAEMON); if (smbd_setup_options(argc, argv) != 0) return (SMF_EXIT_ERR_FATAL); if ((uid = getuid()) != smbd.s_uid) { smbd_report("user %d: %s", uid, strerror(EPERM)); return (SMF_EXIT_ERR_FATAL); } if (getzoneid() != GLOBAL_ZONEID) { smbd_report("non-global zones are not supported"); return (SMF_EXIT_ERR_FATAL); } if (is_system_labeled()) { smbd_report("Trusted Extensions not supported"); return (SMF_EXIT_ERR_FATAL); } if (smbd_already_running()) return (SMF_EXIT_OK); /* * Raise the file descriptor limit to accommodate simultaneous user * authentications/file access. */ if ((getrlimit(RLIMIT_NOFILE, &rl) == 0) && (rl.rlim_cur < rl.rlim_max)) { orig_limit = rl.rlim_cur; rl.rlim_cur = rl.rlim_max; if (setrlimit(RLIMIT_NOFILE, &rl) != 0) smbd_report("Failed to raise file descriptor limit" " from %d to %d", orig_limit, rl.rlim_cur); } (void) sigfillset(&set); (void) sigdelset(&set, SIGABRT); (void) sigfillset(&act.sa_mask); act.sa_handler = smbd_sig_handler; act.sa_flags = 0; (void) sigaction(SIGABRT, &act, NULL); (void) sigaction(SIGTERM, &act, NULL); (void) sigaction(SIGHUP, &act, NULL); (void) sigaction(SIGINT, &act, NULL); (void) sigaction(SIGPIPE, &act, NULL); (void) sigaction(SIGUSR1, &act, NULL); (void) sigdelset(&set, SIGTERM); (void) sigdelset(&set, SIGHUP); (void) sigdelset(&set, SIGINT); (void) sigdelset(&set, SIGPIPE); (void) sigdelset(&set, SIGUSR1); if (smbd.s_fg) { (void) sigdelset(&set, SIGTSTP); (void) sigdelset(&set, SIGTTIN); (void) sigdelset(&set, SIGTTOU); if (smbd_service_init() != 0) { smbd_report("service initialization failed"); exit(SMF_EXIT_ERR_FATAL); } } else { /* * "pfd" is a pipe descriptor -- any fatal errors * during subsequent initialization of the child * process should be written to this pipe and the * parent will report this error as the exit status. */ pfd = smbd_daemonize_init(); if (smbd_service_init() != 0) { smbd_report("daemon initialization failed"); exit(SMF_EXIT_ERR_FATAL); } smbd_daemonize_fini(pfd, SMF_EXIT_OK); } (void) atexit(smb_kmod_stop); while (!smbd.s_shutting_down) { if (smbd.s_sigval == 0 && smbd.s_refreshes == 0) (void) sigsuspend(&set); sigval = atomic_swap_uint(&smbd.s_sigval, 0); switch (sigval) { case 0: case SIGPIPE: case SIGABRT: break; case SIGHUP: syslog(LOG_DEBUG, "refresh requested"); (void) pthread_cond_signal(&refresh_cond); break; case SIGUSR1: smb_log_dumpall(); break; default: /* * Typically SIGINT or SIGTERM. */ smbd.s_shutting_down = B_TRUE; break; } } smbd_service_fini(); closelog(); return ((smbd.s_fatal_error) ? SMF_EXIT_ERR_FATAL : SMF_EXIT_OK); }