/* * _evnt_get_tracker * * Get pointer to tracker structure to use * * Input: * evnt_info - structure containing event information (timings, etc) * stat - pointer to status return word * mode - mode of tracker structure (READA, etc, or FREE) * nbytes - number of bytes to transfer * * Output: * this_tracker - pointer to tracker structure to use for async I/O * info * */ struct evnt_async_tracker * _evnt_get_tracker(struct evnt_f *evnt_info, struct ffsw *stat, char mode, size_t nbytes) { struct evnt_async_tracker *this_tracker; struct evnt_async_tracker *last_tracker; this_tracker = evnt_info->async_tracker; while (this_tracker != NULL) { if (this_tracker->stat == stat) { evnt_info->async_tracker_overwrites++; return (this_tracker); } last_tracker = this_tracker; this_tracker = this_tracker->next_tracker; } this_tracker = evnt_info->async_tracker; last_tracker = this_tracker; while (this_tracker != NULL) { if (this_tracker->mode == TRACKER_FREE) break; last_tracker = this_tracker; this_tracker = this_tracker->next_tracker; } if (this_tracker == NULL && (evnt_info->extend_trackers_failed == FALSE)) { if ((this_tracker = _evnt_add_trackers(NUM_TRACKERS)) == NULL) { evnt_info->extend_trackers_failed = TRUE; } else { last_tracker->next_tracker = this_tracker; this_tracker = this_tracker; evnt_info->num_async_trackers += NUM_TRACKERS; } } if (this_tracker) { this_tracker->mode = mode; this_tracker->stat = stat; this_tracker->requested = nbytes; if (mode == TRACKER_WRITEA) evnt_info->writea.current++; else if (mode == TRACKER_READA) evnt_info->reada.current++; } else { evnt_info->async_untracked_req++; } return (this_tracker); }
/* * _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); }