Exemple #1
0
/*
 * _evnt_weod
 *
 * Log an EOD write operation
 *
 * Input:
 *      fio             - ffio file descriptor
 *      stat            - pointer to status return word
 *
 * Output:
 *	ret		- return value from weodrtn
 *
 */
int
_evnt_weod(struct fdinfo *fio, struct ffsw *stat)
{
	struct fdinfo 	*llfio;
	struct evnt_f 	*evnt_info;
	int     	status;
	rtc_t     	start_rtc, finish_rtc;
	struct ffsw 	log_stat;
	int     	log_ubc = 0;
	int     	ret;

	evnt_info = (struct evnt_f *) fio->lyr_info;
	llfio = fio->fioptr;

	start_rtc = RTC();
	ret = XRCALL(llfio, weodrtn) llfio, stat);
	finish_rtc = RTC();

#ifdef __mips
	if (!(evnt_info->odirect) ||
	 (evnt_info->cur_pos % evnt_info->diskalign != 0))
#else
	if (evnt_info->cur_pos & evnt_info->sector_mask)
#endif
		evnt_info->ill_formed_weod++;

#if	!defined(__mips) && !defined(_LITTLE_ENDIAN)
	if (evnt_info->optflags.trace) {
		int     record[4];

		EVNT_LOCK_ON;
		record[0] = _evnt_WEOD | evnt_info->fd;
		record[1] = start_rtc;
		record[2] = finish_rtc;
		record[3] = ret;
		status = EVNT_XR_WRITE(record, sizeof(int), 4);
		INC_GLOBAL_LOG_COUNT(weod);
		EVNT_LOCK_OFF;
	}
#endif
	_GL_evnt_trc_file[evnt_info->trc_file_number].cur_usage -=
			(evnt_info->cur_size - evnt_info->cur_pos);

	evnt_info->cur_size = evnt_info->cur_pos;
	EVNT_TRACE_SIZE;

	evnt_info->counts.weod++;
	evnt_info->counts.total++;

	return (ret);
}
Exemple #2
0
/*
 * _evnt_write
 *
 * Log a write request
 *
 * Input:
 *      fio             - ffio file descriptor
 *      bufptr          - bit pointer to where data is to go
 *      nbytes          - number of bytes to be written
 *      stat            - pointer to status return word
 *      fulp            - full or partial write mode flag
 *      ubcp            - pointer to unused bit count.  On return,
 *                        *ubcp is updated to contain the unused bit
 *                        count in the data returned.
 *
 * Output:
 * 	The number of bytes transferred is returned upon successful completion.
 *	if an error occurs, -1 is returned.
 *
 *	The stat->sw_stat field is set to FFCNT upon normal return.
 *
 */
ssize_t
_evnt_write(struct fdinfo *fio, bitptr bufptr, size_t nbytes, 
	    struct ffsw *stat, int fulp, int *ubcp)
{
	struct fdinfo 	*llfio;
	struct evnt_f 	*evnt_info;
	int     	status;
	rtc_t     	start_rtc, finish_rtc;
	ssize_t     	ret;
	struct ffsw 	log_stat;
	int     	log_ubc = 0;

	evnt_info = (struct evnt_f *) fio->lyr_info;
	llfio = fio->fioptr;

	EVNT_UPDATE(write);

	start_rtc = RTC();
	ret = XRCALL(llfio, writertn) llfio, bufptr, nbytes, stat, fulp, ubcp);
	finish_rtc = RTC();

	evnt_info->cur_pos += nbytes;
	EVNT_CHECK_SIZE;

#if	!defined(__mips) && !defined(_LITTLE_ENDIAN)
	if (evnt_info->optflags.trace) {
		int     record[4];

		EVNT_LOCK_ON;
		record[0] = (_evnt_WRITE | evnt_info->fd) | nbytes;
		record[1] = start_rtc;
		record[2] = finish_rtc;
		record[3] = ret;
		status = EVNT_XR_WRITE(record, sizeof(int), 4);
		INC_GLOBAL_LOG_COUNT(write);
		EVNT_LOCK_OFF;
	}
#endif
	evnt_info->counts.total++;
	evnt_info->counts.write++;
	evnt_info->write.delivered += ret;
	evnt_info->write.time += (finish_rtc - start_rtc);

	return (ret);
}
Exemple #3
0
/*
 * _evnt_bksp
 *
 * Time backspace request
 *
 * Input:
 *      fio             - ffio file descriptor
 *	stat		- pointer to status return word
 *
 * Output:
 *	ret		- return value from backrtn
 *
 */
int
_evnt_bksp(struct fdinfo *fio, struct ffsw *stat)
{
	struct fdinfo *llfio;
	struct evnt_f *evnt_info;
	int     status;
	rtc_t     start_rtc, finish_rtc;
	struct ffsw log_stat;
	int     log_ubc = 0;
	int     ret;

	evnt_info = (struct evnt_f *) fio->lyr_info;
	llfio = fio->fioptr;

	start_rtc = RTC();
	ret = XRCALL(llfio, backrtn) llfio, stat);
	finish_rtc = RTC();

#if	!defined(__mips) && !defined(_LITTLE_ENDIAN)
	if (evnt_info->optflags.trace) {
		int     record[4];

		EVNT_LOCK_ON;
		record[0] = (_evnt_BKSP | evnt_info->fd);
		record[1] = start_rtc;
		record[2] = finish_rtc;
		record[3] = ret;
		status = EVNT_XR_WRITE(record, sizeof(int), 4);
		INC_GLOBAL_LOG_COUNT(bksp);
		EVNT_LOCK_OFF;
	}
#endif
	evnt_info->counts.bksp++;
	evnt_info->counts.total++;

	return (ret);
}
Exemple #4
0
/*
 * _evnt_open
 *
 * Open routine for "event" layer.
 *
 * Input:
 *	name	- name of file to open
 *	oflags
 *	mode
 *	fio	- ffio file descriptor
 *	spec
 *	stat	- pointer to status return word
 *	cbits
 *	cblks
 *	oinf
 *
 * Output:
 *	Returns: pointer to fdinfo block from next lower layer on success.
 *		 -1 if an error occurred.
 */
_ffopen_t
_evnt_open(const char *name, int oflags, mode_t mode, struct fdinfo *fio,
	  union spec_u *spec, struct ffsw *stat, long cbits, int cblks,
	  struct gl_o_inf *oinf)
{
	_ffopen_t     	nextfio;
	int     	ret;
	union spec_u 	*nspec;
	int     	status;
	struct evnt_f 	*evnt_info;
	struct stat 	fstat;
	int     	trc_file_number = 0;
	rtc_t     	start_rtc, finish_rtc;
	struct ffsw 	log_stat;
	int         	log_ubc = 0;
#if	!defined(__mips) && !defined(_LITTLE_ENDIAN)
	int     	end_open_link = _evnt_OPEN_LINK;
#elif	defined(__mips)
	struct dioattr	dio;
#endif
	int		isvalid;
	static int 	evnt_atexit_called = FALSE;
	struct EVNT_FILE_TRACE *trace_file;


	/*
	 * post atexit so we can call it to close our 
	 * diagnostic and trace files
	 */
	if (evnt_atexit_called == FALSE) {
		evnt_atexit_called = TRUE;
		atexit(_evnt_atexit);
	}

	fio->lyr_info = NULL;  /* set to NULL for the benefit of _evnt_clfree */

	evnt_info = (struct evnt_f *) calloc(1, sizeof(struct evnt_f));
	if (evnt_info == NULL)
		goto nomem;

	fio->lyr_info = (char *) evnt_info;

	/*
	 * set default layer options in envt_info
	 */
	evnt_info->optflags.diag	= TRUE;	/* default is full diagnostics*/
	evnt_info->optflags.full_diag	= TRUE;	/* default is full diagnostics*/
	evnt_info->optflags.summary	= FALSE;
	evnt_info->optflags.brief	= FALSE;
	evnt_info->optflags.trace	= FALSE;
	evnt_info->optflags.rtc		= RTC_MODE;/* use rtc by default */
	evnt_info->optflags.k		= FALSE;
	evnt_info->optflags.m		= FALSE;
	evnt_info->optflags.g		= FALSE;

	evnt_info->optflags.bytes	= TRUE; /* default units */
	evnt_info->optflags.words	= FALSE; 
	evnt_info->optflags.blocks	= FALSE; 

	evnt_info->do_zeros = TRUE;	/* zero fill diag fields by default */


	evnt_info->extend_trackers_failed = FALSE;

	/*
	 * malloc space for async tracker structures
	 */
	if ((evnt_info->async_tracker = _evnt_add_trackers(NUM_TRACKERS))
	    == NULL)
		goto nomem;
	evnt_info->num_async_trackers = NUM_TRACKERS;

	/*
	 * pick up user requested options - 
	 * get values from the FFIO spec
	 */
	_evnt_getopts(evnt_info, spec);

	/*
	 * open diagnostics file
	 */
	if (evnt_info->optflags.diag == TRUE) {
		if(_evnt_open_log_file(evnt_info) == ERR) {
			goto badret;
		} else {
			if (_GL_ffio_logptr != NULL)
				_GL_evnt_logptr = _GL_ffio_logptr;
			else
				_GL_evnt_logptr = stderr;
		}
	}

	/*
	 * open trace file if we're tracing 
	 */
#if	!defined(__mips) && !defined(_LITTLE_ENDIAN)
	if (evnt_info->optflags.trace == TRUE) {
		trc_file_number = _ff_nparm_getv(spec, 1, &isvalid);

		/*
		 * check for valid file number - issue message to stats file
		 */
		if (evnt_info->optflags.diag == TRUE &&
		    trc_file_number < 0 || trc_file_number > 9) {
			fprintf(_GL_evnt_logptr,
				"Invalid trace file number specified: %d.  Valid numbers are 0-9.\n     ffio.trace will be used\n", trc_file_number);
			trc_file_number = 0;
		}

		evnt_info->trc_file_number = trc_file_number;
		trace_file = &(_GL_evnt_trc_file[trc_file_number]);

		if (_evnt_open_trace_file(fio, name, evnt_info) == ERR)
			goto badret;
	}
#endif
#ifdef EVNT_DEBUG
	fprintf(stderr,"event layer options:\n");
	fprintf(stderr,
	   "diagnostics: diag = %d, full_diag = %d, summary = %d, brief = %d\n",
			evnt_info->optflags.diag,
			evnt_info->optflags.full_diag, 
			evnt_info->optflags.summary,
			evnt_info->optflags.brief);
	fprintf(stderr,"tracing:  trace = %d\n", evnt_info->optflags.trace);
	fprintf(stderr,"trc_file_number = %d\n", trc_file_number);
	fprintf(stderr,"clock:  rtc = %d\n", evnt_info->optflags.rtc);
	fprintf(stderr,"units:  bytes = %d, words = %d, blocks = %d\n", 
			evnt_info->optflags.bytes,
			evnt_info->optflags.words,
			evnt_info->optflags.blocks);
	fprintf(stderr,"size:  k = %d, m = %d, g = %d\n", 
			evnt_info->optflags.k,
			evnt_info->optflags.m,
			evnt_info->optflags.g);
#endif

	/*
	 * initialize minimums to large values for diagnostics
	 */
	if (evnt_info->optflags.diag) {
		long bigmin;
		if (sizeof(size_t) == sizeof(long)){
			bigmin = LONG_MAX;
		}
		else {
			bigmin = INT_MAX;	
		}
		evnt_info->listio_write.min = bigmin;
		evnt_info->listio_writea.min = bigmin;
		evnt_info->listio_read.min = bigmin;
		evnt_info->listio_reada.min = bigmin;
		evnt_info->write.min = bigmin;
		evnt_info->writea.min = bigmin;
		evnt_info->read.min = bigmin;
		evnt_info->reada.min = bigmin;
		strncpy(evnt_info->name, name, NAMLEN);
	}

	/*
	 * Get the FFIO spec for the next lower layer.
	 */
	nspec = spec;
	NEXT_SPEC(nspec);

	/*
	 * Open the layers below this one.
	 */
#if	!defined(__mips) && !defined(_LITTLE_ENDIAN)
	if (evnt_info->optflags.trace == TRUE)
		trace_file->open_level_count++;
#endif

	start_rtc = RTC();
	nextfio = _ffopen(name, oflags, mode, nspec, stat, cbits, cblks, 
			  NULL, oinf);
	finish_rtc = RTC();

#if	!defined(__mips) && !defined(_LITTLE_ENDIAN)
	if (evnt_info->optflags.trace == TRUE)
		trace_file->open_level_count--;
#endif
	evnt_info->open_time = finish_rtc - start_rtc;

	if (nextfio == _FFOPEN_ERR)
		goto badret;

	if (1) {
		struct fdinfo *nfioptr;

		nfioptr = (struct fdinfo *) nextfio;

		ret = XRCALL(nfioptr, fcntlrtn) nfioptr, FC_STAT, &fstat, stat);

		if (oflags & O_TRUNC)
			evnt_info->cur_size = 0;
		else
			evnt_info->cur_size = fstat.st_size;

		if (oflags & O_APPEND)
			evnt_info->cur_pos = evnt_info->cur_size;
		else
			evnt_info->cur_pos = 0;

#ifdef __mips
		ret = XRCALL(nfioptr, fcntlrtn) nfioptr, FC_DIOINFO, &dio, stat);
		if (ret == ERR)evnt_info->odirect = 0;
		else {
			evnt_info->odirect = 1;
			evnt_info->miniosize = dio.d_miniosz;
			evnt_info->chunksize = dio.d_miniosz;
			evnt_info->diskalign = dio.d_miniosz;
			evnt_info->maxiosize = dio.d_maxiosz;
			evnt_info->memalign = dio.d_mem;
		}
#endif
		evnt_info->max_size = evnt_info->cur_size;

		evnt_info->oflags = oflags;

		evnt_info->cbits = cbits;
		evnt_info->cblks = cblks;

#ifdef DO_WE_WANT_FAKE_SDS
		if (get out of * oinf) {
			evnt_info->fake_sds = TRUE;
			evnt_info->sector_mask = 4095;
		} else {
			evnt_info->fake_sds = FALSE;
			evnt_info->sector_mask = fstat.st_blksize - 1;
		}
#endif
		/* we're not monitoring ssreads yet */
		evnt_info->fake_sds = FALSE;  
		evnt_info->sector_mask = fstat.st_blksize - 1;
	}

	/*
	 * write some initial information to the trace file
	 */
#if	!defined(__mips) && !defined(_LITTLE_ENDIAN)
	if (evnt_info->optflags.trace) {
	    if (trace_file->ptr) {
		struct evnt_open_info *open_info;
		int     next_open_link;

		open_info = &(evnt_info->open_info);

		evnt_info->fd = (trace_file->file_info.open_count) << 48;

		open_info->fd = _evnt_OPEN | evnt_info->fd;
		open_info->oflags = oflags;
		open_info->mode = mode;
		strncpy(open_info->name, name, 80);
		open_info->name[79] = 0;
		open_info->open_size = evnt_info->cur_size;
		open_info->rtc_14 = RTC();
		open_info->rtc_15 = RTC();
		open_info->nextfio = nextfio;
		strcpy(open_info->parent_child, "??? <-> ???");
		open_info->next_open_pos = 'UNUSED';
		open_info->max_size = evnt_info->max_size;
		open_info->close_rtc = 0;
		open_info->event_count = 0;
		open_info->start_rtc = start_rtc;
		open_info->finish_rtc = finish_rtc;
		open_info->d_nextfio = nextfio;

		next_open_link = EVNT_XR_TELL();
		evnt_info->open_pos = next_open_link + 8;

		if (trace_file->program_info.open_count == 0)
		    trace_file->program_info.first_open_pos = next_open_link;

		if (trace_file->file_info.open_count == 0) {
		    trace_file->file_info.first_open_pos = next_open_link;
		} else {
		    long    link_word;

		    status = EVNT_XR_SEEK(trace_file->file_info.last_open_link, 
				       SEEK_SET);
		    link_word = _evnt_OPEN_LINK | next_open_link;
		    status = EVNT_XR_WRITE(&link_word, 8, 1);
		    status = EVNT_XR_SEEK(0, SEEK_END);
		}

		trace_file->file_info.last_open_link = next_open_link;

		status = EVNT_XR_WRITE(&end_open_link, 1, sizeof(int));
		status = EVNT_XR_WRITE(open_info, 1, 
				       sizeof(struct evnt_open_info));
	    }

	    evnt_info->logged_count =
		&(_GL_evnt_trc_file[evnt_info->trc_file_number].program_info.event_count);
	    trace_file->file_info.open_count++;
	    trace_file->program_info.open_count++;

	    EVNT_TRACE_SIZE;
	    INC_GLOBAL_LOG_COUNT(open);
	    _evnt_trace_flush(fio, evnt_info);
	    evnt_info->need_parent_child = TRUE;
	}
#endif
	evnt_info->counts.size_changes = 0;
	evnt_info->counts.open = 1;
	evnt_info->counts.total = 1;

	return (nextfio);

nomem:
badret:
	_evnt_clfree(fio);
	return (_FFOPEN_ERR);

}
Exemple #5
0
/*
 * _evnt_open_trace_file
 *
 * Open file that we'll put tracing info in
 *
 * Input:
 *	fio		- ffio file descriptor
 *	name		- name of file we're monitoring
 *	evnt_info	- structure containing event information (timings, etc)
 *
 * Output:
 *	Returns:	ERR if open unsuccessful
 *			0 if successful
 */
_evnt_open_trace_file(
struct fdinfo *fio,
const char *name,
struct evnt_f *evnt_info)
{
	char    	file_name[128];
	char   		*name_ptr;
	int     	trc_file_number;
	struct ffsw	open_ffsw;
	int     	status;
	int     	append;
	int     	oflags;
	long    	program_keyword;
	struct ffsw	log_stat;
	int		log_ubc = 0;
	struct EVNT_FILE_TRACE *trace_file;

	trc_file_number = evnt_info->trc_file_number;
	trace_file = &(_GL_evnt_trc_file[trc_file_number]);

#if	!defined(__mips) && !defined(_LITTLE_ENDIAN)
	if (evnt_info->optflags.trace) {
	    if (trace_file->ptr == NULL) {
		long    start_rtc;
		double   rtc_factor;

		file_name[0] = 0;
		if (trace_file->being_opened) {
		    if (_GL_evnt_logptr) {
			fprintf(_GL_evnt_logptr,
				"Attempting to use same event.fil_num=%d for events file %s\n",
				trc_file_number,
				name);
		    }

		    return (ERR);

		}

		if ((name_ptr = getenv("FF_IO_TRACE_FILE")) != NULL) {
		    strcpy(file_name, name_ptr);
		} else {
		    strcpy(file_name, "ffio.trace");
		}

		if (trc_file_number > 0) {
		    char    digits[8];

		    sprintf(digits, ".%d", trc_file_number);
		    strcat(file_name, digits);
		}

		name_ptr = file_name;
		append = FALSE;
		if (*name_ptr == '+') {
		    append = TRUE;
		    name_ptr++;
		}

		start_rtc = RTC();

		rtc_factor = RTC_FACTOR;

		trace_file->cur_usage = 0;
		trace_file->max_usage = 0;
		strncpy(trace_file->file_info.magic, EVNT_MAGIC_STRING, 7);
		strncpy(trace_file->file_info.version, "7.1BF2", 7);
		trace_file->file_info.start_rtc = start_rtc;
		trace_file->file_info.rtc_factor = rtc_factor;
		trace_file->file_info.event_count = 0;
		trace_file->file_info.open_count = 0;
		trace_file->file_info.program_count = 0;
		trace_file->file_info.reserve_1 = 'f_rsv_1';
		trace_file->file_info.reserve_2 = 'f_rsv_2';
		trace_file->file_info.reserve_3 = 'f_rsv_3';
		trace_file->file_info.reserve_4 = 'f_rsv_4';

		/* 
		 * set program_keyword so we can tell if we have valid
		 * trace file or not when running iox
		 */
		program_keyword =
		 ((_evnt_PROGRAM_START) | (sizeof(struct EVNT_PROGRAM_INFO) - 8));
		trace_file->program_info.keyword = program_keyword;
		trace_file->program_info.next_program_info_pos = 0;
		trace_file->program_info.start_rtc = start_rtc;
		trace_file->program_info.exit_rtc = start_rtc;
		trace_file->program_info.event_count = 0;
		trace_file->program_info.open_count = 0;
		trace_file->program_info.reserve_1 = 'p_rsv_1';
		trace_file->program_info.reserve_2 = 'p_rsv_2';
		trace_file->program_info.reserve_3 = 'p_rsv_3';
		trace_file->program_info.reserve_4 = 'p_rsv_4';
		strcpy(trace_file->program_info.name, _argv[0]);

try_again:
		if (append) {
		    oflags = O_RDWR;
		    trace_file->being_opened = TRUE;
		    evnt_info->file_ptr = EVNT_XR_OPEN(name_ptr);
		    trace_file->being_opened = FALSE;
		    if (evnt_info->file_ptr <= NULL) {
			/*
			 * file did not exist, lets just open
			 * it non-append
			 */
			evnt_info->file_ptr = NULL;
			append = FALSE;
			goto try_again;
		    }

		    trace_file->ptr = evnt_info->file_ptr;

		    /*
		     * check for valid trace file to
		     * append to (close if not valid)
		     */
		    if (_evnt_restart_trace_file(evnt_info->file_ptr,
			 		  trc_file_number, name_ptr) == FALSE) {
			status = EVNT_XR_CLOSE();
			trace_file->ptr = NULL;
			evnt_info->file_ptr = NULL;
		    }
		} else {
		    oflags = O_RDWR | O_CREAT | O_TRUNC;
		    trace_file->being_opened = TRUE;
		    evnt_info->file_ptr = EVNT_XR_OPEN(name_ptr);
		    trace_file->being_opened = FALSE;
		}

		trace_file->ptr = evnt_info->file_ptr;

		if ((int) evnt_info->file_ptr <= 0) {
		    evnt_info->file_ptr = NULL;
		    evnt_info->optflags.trace = FALSE;
		    if (_GL_evnt_logptr) {
			fprintf(_GL_evnt_logptr,
			      "Unable to open event trace file %s\n", name_ptr);
		    }
		}

		trace_file->ptr = evnt_info->file_ptr;
		trace_file->file_info.program_count++;
		trace_file->file_info_pos = 0;
		EVNT_WRITE_FILE_INFO(trc_file_number);

		trace_file->program_info_pos = EVNT_XR_SEEK(0, SEEK_END);

		if (trace_file->file_info.program_count == 1) {
		    /* update the first word in file_info */
		    trace_file->file_info.first_program_pos = 
				trace_file->program_info_pos;
		} else {
		    /* update the link word in the last program_info */
		    status = EVNT_XR_SEEK(trace_file->file_info.last_program_link, SEEK_SET);
		    status = EVNT_XR_WRITE(&(trace_file->program_info_pos), 
					   sizeof(int), 1);
		}

		trace_file->file_info.last_program_link = 
				trace_file->program_info_pos + 8;

		EVNT_WRITE_PROGRAM_INFO(trc_file_number);

	    } else {
		evnt_info->file_ptr = trace_file->ptr;
	    }

	}
#endif
	return (0);
}
static void rtc_write (short reg, uchar val)
{
	out8(RTC(reg),val);
}
static uchar rtc_read (short reg)
{
	return in8(RTC(reg));
}
Exemple #8
0
/*
 * _evnt_reada
 *
 * Log a reada request
 *
 * Input:
 *      fio             - ffio file descriptor
 *      bufptr          - bit pointer to where data is to go
 *      nbytes          - number of bytes to be read
 *      stat            - pointer to status return word
 *      fulp            - full or partial read mode flag
 *      ubcp            - pointer to unused bit count.  On return,
 *                        *ubcp is updated to contain the unused bit
 *                        count in the data returned.
 *
 * Output:
 *      ret             - return value from readartn
 *
 */
ssize_t
_evnt_reada(struct fdinfo *fio, bitptr bufptr, size_t nbytes, 
	    struct ffsw *stat, int fulp, int *ubcp)
{
	struct fdinfo 	*llfio;
	struct evnt_f 	*evnt_info;
	int     	status;
	rtc_t     	start_rtc, finish_rtc;
	struct ffsw 	log_stat;
	int     	log_ubc = 0;
	ssize_t     	ret;
	ssize_t     	orig_ret;
	struct evnt_async_tracker *this_tracker;

	evnt_info = (struct evnt_f *) fio->lyr_info;
	llfio = fio->fioptr;

	EVNT_UPDATE(reada);
	if (evnt_info->optflags.diag || evnt_info->optflags.trace)
		this_tracker =
		     _evnt_get_tracker(evnt_info, stat, TRACKER_READA, nbytes);

	start_rtc = RTC();
	orig_ret = XRCALL(llfio, readartn) llfio, bufptr, nbytes, stat, 
			  fulp, ubcp);
	finish_rtc = RTC();

	if (stat->sw_stat != 0 && stat->sw_flag != 0)
		ret = stat->sw_count;
	else
		ret = 0;

	evnt_info->cur_pos += nbytes;
	if (evnt_info->cur_pos > evnt_info->cur_size)
		evnt_info->cur_pos = evnt_info->cur_size;
	EVNT_CHECK_SIZE;

	if (evnt_info->optflags.diag)
		evnt_info->reada.time += (finish_rtc - start_rtc);

#if	!defined(__mips) && !defined(_LITTLE_ENDIAN)
	if (evnt_info->optflags.trace) {
		int     record[8];

		EVNT_LOCK_ON;
		record[0] = (_evnt_READA | evnt_info->fd) | nbytes;
		record[1] = (int) stat;
		record[2] = start_rtc;
		record[3] = finish_rtc;
		record[4] = ret;
		record[5] = record[6] = record[7] = 0;
		status = EVNT_XR_WRITE(record, sizeof(int), 8);
		if (this_tracker)
			this_tracker->logpos = EVNT_XR_TELL() - sizeof(int)*3;
		INC_GLOBAL_LOG_COUNT(reada);
		EVNT_LOCK_OFF;
	}
#endif
	evnt_info->counts.total++;
	evnt_info->counts.reada++;

	if (this_tracker && (stat->sw_stat != 0 && stat->sw_flag != 0)) {
		evnt_info->reada.sync++;
		evnt_info->reada.delivered += stat->sw_count;
		evnt_info->reada.current--;
		this_tracker->mode = TRACKER_FREE;
		this_tracker->stat = NULL;
		this_tracker->logpos = 0;
	}
	return (orig_ret);
}