STATUS TMhrnow(HRSYSTIME *stime) { #if defined(sqs_ptx) struct timespec cur_syst; #else SYSTIME cur_syst; #endif /* sqs_ptx */ #ifdef TMHRNOW_WRAPPED_CLOCKGETTIME return clock_gettime( CLOCK_REALTIME, stime ); #endif #ifndef WRAPPED if ( !initialized ) { initialized = TRUE; #ifdef OS_THREADS_USED CS_synch_init(&nanomutex); #endif /* OS_THREADS_USED */ } #ifdef sqs_ptx getclock(TIMEOFDAY, &cur_syst); stime->tv_sec = cur_syst.tv_sec; stime->tv_nsec = cur_syst.tv_nsec; #else TMet(&cur_syst); stime->tv_sec = cur_syst.TM_secs; stime->tv_nsec = cur_syst.TM_msecs * NANO_PER_MILLI; #endif /* sqs_ptx */ /* ** if we have been called twice within the same ** interval, increment the time by one nanosecond. */ #ifdef OS_THREADS_USED CS_synch_lock(&nanomutex); #endif /* OS_THREADS_USED */ if ( stime->tv_sec == lasttime.tv_sec && stime->tv_nsec <= lasttime.tv_nsec ) { stime->tv_nsec = lasttime.tv_nsec + 1; } lasttime.tv_sec = stime->tv_sec; lasttime.tv_nsec = stime->tv_nsec; #ifdef OS_THREADS_USED CS_synch_unlock(&nanomutex); #endif /* OS_THREADS_USED */ return OK; #endif /* WRAPPED */ }
/*{ ** Name: DIgather_write - GatherWrite external interface. ** ** Description: ** This routine is called by any thread that wants to write multiple pages ** The caller indicates via the op parameter whether the write request ** should be batched up or/and the batch list should be written to disc. ** ** Inputs: ** i4 op - indicates what operation to perform: ** DI_QUEUE_LISTIO - adds request to threads ** gatherwrite queue. ** DI_FORCE_LISTIO - causes do_writev() to be ** called for queued GIOs. ** DI_CHECK_LISTIO - checks if this thread has ** any outstanding I/O requests. ** DI_IO *f - Pointer to the DI file context needed to do I/O. ** i4 *n - Pointer to value indicating number of pages to ** write. ** i4 page - Value indicating page(s) to write. ** char *buf - Pointer to page(s) to write. ** (evcomp)() - Ptr to callers completion handler. ** PTR closure - Ptr to closure details used by evcomp. ** ** Outputs: ** f - Updates the file control block. ** n - Pointer to value indicating number of pages written. ** err_code - Pointer to a variable used to return operating system ** errors. ** ** Returns: ** OK Function completed normally. ** non-OK status Function completed abnormally ** with a DI error number. ** ** Exceptions: ** none ** ** Side Effects: ** The completion handler (evcomp) will do unspecified work. ** ** History: ** 19-May-1999 (jenjo02) ** Created. ** 20-jul-1999 (popri01) ** On Unixware (usl_us5), IOV MAX can only be determined ** at run-time, so use a hard-coded value of 16 (which ** guarantees portability). ** Also, add explicit cast for iov_base arithmetic. ** 03-Apr-2002 (bonro01) ** SGI is also missing IOV_MAX. Re-wrote the routine to ** determine IOV_MAX at run-time for SGI and Unixware. ** 26-Nov-2002 (inifa01) ** Crossed in and Ammended above change to fix compile ** problems. ** 09-Jan-2003 (bonro01) ** Unixware compiler could not generate variable size local ** structure for IOV_MAX. ** 25-Aug-2005 (schka24) ** Don't lru-open the file here, do it when we're going to ** really queue the request. ** 30-Sep-2005 (jenjo02) ** GWthreadsSem now a CS_SYNCH object. ** 15-Mar-2010 (smeke01) b119529 ** DM0P_BSTAT fields bs_gw_pages and bs_gw_io are now u_i8s. */ STATUS DIgather_write( i4 op, char *gio_p, DI_IO *f, i4 *n, i4 page, char *buf, VOID (*evcomp)(), PTR closure, i4 *uqueued, u_i8 *gw_pages, u_i8 *io_count, CL_ERR_DESC *err_code) { STATUS big_status = OK, small_status = OK; #ifdef OS_THREADS_USED DI_GIO *gio = (DI_GIO *)gio_p; i4 num_of_pages; i4 last_page_to_write; if ( GWSemsInit == FALSE ) { CS_synch_init( &GWthreadsSem ); GWSemsInit = TRUE; } /* default returns */ if (err_code) CL_CLEAR_ERR( err_code ); if ( op & DI_QUEUE_LISTIO ) { num_of_pages = *n; *n = 0; last_page_to_write = page + num_of_pages - 1; if (f->io_type != DI_IO_ASCII_ID) return(DI_BADFILE); if (f->io_mode != DI_IO_WRITE) return(DI_BADWRITE); /* ** now check for write within bounds of the file */ if ( last_page_to_write > f->io_alloc_eof ) { i4 real_eof; /* ** There may be pending writes which haven't been forced ** which would extend the file to a new eof. ** Before sensing, make sure they have been forced. */ if ( check_list() ) big_status = force_list( err_code ); /* ** DIsense updates f->io_alloc_eof with the protection ** of io_sem (OS_THREADS), so there's no need to ** duplicate that update here. */ if ( big_status == OK ) big_status = DIsense(f, &real_eof, err_code); if ( big_status == OK && last_page_to_write > f->io_alloc_eof ) { small_status = DI_ENDFILE; SETCLERR(err_code, 0, ER_write); /* ** The above sets errno as errno will be left over from ** a previous call zero it out to avoid confusion. */ err_code->errnum = 0; } } if ( big_status == OK && small_status == OK ) { /* Record another write */ f->io_stat.write++; gio->gio_evcomp = evcomp; gio->gio_data = closure; gio->gio_f = f; gio->gio_buf = buf; gio->gio_offset = (OFFSET_TYPE)f->io_bytes_per_page * (OFFSET_TYPE)page; gio->gio_len = f->io_bytes_per_page * num_of_pages; gio->gio_gw_pages = gw_pages; gio->gio_io_count = io_count; big_status = gather_list( gio, uqueued, err_code ); } if ( big_status == OK && small_status == OK ) *n = num_of_pages; } else if (op & DI_FORCE_LISTIO ) { return(force_list( err_code )); /* Won't return here until all requests have completed */ } else if (op & DI_CHECK_LISTIO ) { return(check_list()); } #endif /* OS_THREADS_USED */ return( big_status ? big_status : small_status ); }