wmb(); 
smp_wmb(); 
void ppc_adjtimex(void){	unsigned long den, new_tb_ticks_per_sec, tb_ticks, old_xsec, new_tb_to_xs, new_xsec, new_stamp_xsec;	unsigned long tb_ticks_per_sec_delta;	long delta_freq, ltemp;	struct div_result divres; 	unsigned long flags;	struct gettimeofday_vars * temp_varp;	unsigned temp_idx;	long singleshot_ppm = 0;	/* Compute parts per million frequency adjustment to accomplish the time adjustment	   implied by time_offset to be applied over the elapsed time indicated by time_constant.	   Use SHIFT_USEC to get it into the same units as time_freq. */	if ( time_offset < 0 ) {		ltemp = -time_offset;		ltemp <<= SHIFT_USEC - SHIFT_UPDATE;		ltemp >>= SHIFT_KG + time_constant;		ltemp = -ltemp;	}	else {		ltemp = time_offset;		ltemp <<= SHIFT_USEC - SHIFT_UPDATE;		ltemp >>= SHIFT_KG + time_constant;	}		/* If there is a single shot time adjustment in progress */	if ( time_adjust ) {#ifdef DEBUG_PPC_ADJTIMEX		printk("ppc_adjtimex: ");		if ( adjusting_time == 0 )			printk("starting ");		printk("single shot time_adjust = %ld\n", time_adjust);#endif				adjusting_time = 1;				/* Compute parts per million frequency adjustment to match time_adjust */		singleshot_ppm = tickadj * HZ;			/*		 * The adjustment should be tickadj*HZ to match the code in		 * linux/kernel/timer.c, but experiments show that this is too		 * large. 3/4 of tickadj*HZ seems about right		 */		singleshot_ppm -= singleshot_ppm / 4;		/* Use SHIFT_USEC to get it into the same units as time_freq */			singleshot_ppm <<= SHIFT_USEC;		if ( time_adjust < 0 )			singleshot_ppm = -singleshot_ppm;	}	else {#ifdef DEBUG_PPC_ADJTIMEX		if ( adjusting_time )			printk("ppc_adjtimex: ending single shot time_adjust\n");#endif		adjusting_time = 0;	}		/* Add up all of the frequency adjustments */	delta_freq = time_freq + ltemp + singleshot_ppm;		/* Compute a new value for tb_ticks_per_sec based on the frequency adjustment */	den = 1000000 * (1 << (SHIFT_USEC - 8));	if ( delta_freq < 0 ) {		tb_ticks_per_sec_delta = ( tb_ticks_per_sec * ( (-delta_freq) >> (SHIFT_USEC - 8))) / den;		new_tb_ticks_per_sec = tb_ticks_per_sec + tb_ticks_per_sec_delta;	}	else {		tb_ticks_per_sec_delta = ( tb_ticks_per_sec * ( delta_freq >> (SHIFT_USEC - 8))) / den;		new_tb_ticks_per_sec = tb_ticks_per_sec - tb_ticks_per_sec_delta;	}	#ifdef DEBUG_PPC_ADJTIMEX	printk("ppc_adjtimex: ltemp = %ld, time_freq = %ld, singleshot_ppm = %ld\n", ltemp, time_freq, singleshot_ppm);	printk("ppc_adjtimex: tb_ticks_per_sec - base = %ld  new = %ld\n", tb_ticks_per_sec, new_tb_ticks_per_sec);#endif					/* Compute a new value of tb_to_xs (used to convert tb to microseconds and a new value of 	   stamp_xsec which is the time (in 1/2^20 second units) corresponding to tb_orig_stamp.  This 	   new value of stamp_xsec compensates for the change in frequency (implied by the new tb_to_xs)	   which guarantees that the current time remains the same */ 	write_seqlock_irqsave( &xtime_lock, flags );	tb_ticks = get_tb() - do_gtod.varp->tb_orig_stamp;	div128_by_32( 1024*1024, 0, new_tb_ticks_per_sec, &divres );	new_tb_to_xs = divres.result_low;	new_xsec = mulhdu( tb_ticks, new_tb_to_xs );	old_xsec = mulhdu( tb_ticks, do_gtod.varp->tb_to_xs );	new_stamp_xsec = do_gtod.varp->stamp_xsec + old_xsec - new_xsec;	/* There are two copies of tb_to_xs and stamp_xsec so that no lock is needed to access and use these	   values in do_gettimeofday.  We alternate the copies and as long as a reasonable time elapses between	   changes, there will never be inconsistent values.  ntpd has a minimum of one minute between updates */	temp_idx = (do_gtod.var_idx == 0);	temp_varp = &do_gtod.vars[temp_idx];	temp_varp->tb_to_xs = new_tb_to_xs;	temp_varp->stamp_xsec = new_stamp_xsec;	temp_varp->tb_orig_stamp = do_gtod.varp->tb_orig_stamp;	mb();	do_gtod.varp = temp_varp;	do_gtod.var_idx = temp_idx;	/*	 * tb_update_count is used to allow the problem state gettimeofday code	 * to assure itself that it sees a consistent view of the tb_to_xs and	 * stamp_xsec variables.  It reads the tb_update_count, then reads	 * tb_to_xs and stamp_xsec and then reads tb_update_count again.  If	 * the two values of tb_update_count match and are even then the	 * tb_to_xs and stamp_xsec values are consistent.  If not, then it	 * loops back and reads them again until this criteria is met.	 */	++(systemcfg->tb_update_count);	wmb();	systemcfg->tb_to_xs = new_tb_to_xs;	systemcfg->stamp_xsec = new_stamp_xsec;	wmb();	++(systemcfg->tb_update_count);	write_sequnlock_irqrestore( &xtime_lock, flags );}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/0d8d4d42f2d00eb65262b49f4edd4cf7ef4eb6fc/time.c/clean/arch/ppc64/kernel/time.c