Beispiel #1
0
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 */

}
Beispiel #2
0
/*{
** 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 );
}