示例#1
0
文件: tty.c 项目: SourcexRobin/Lenix
/*
 *  能否假设使用到交互功能的时候,实时性能已经不重要
 *  2012.12.12  
 */
static void Tty_copy_to_cook(tty_t * tty)
{
    byte_t                  c       = 0;
    CRITICAL_DECLARE(tty->tty_lock);

    CRITICAL_BEGIN();

    /*  输入缓冲区有数据才能对其进行加工  */
    while( !TQ_IS_EMPTY(tty->tty_read_queue)  )
    {
        TQ_GET_CHAR(tty->tty_read_queue,c);

        switch(c)
        {
        case CHAR_BACK:
            if( TQ_IS_EMPTY(tty->tty_second_queue) )
                continue;
            TQ_DEC(tty->tty_second_queue.tq_head);
            break;
        default:
            TQ_PUT_CHAR(tty->tty_second_queue,c);
            break;
        }
    }

    CRITICAL_END();
}
示例#2
0
文件: win.c 项目: jkkm/xfsdump
void
win_unmap( segix_t segix, void **pp )
{
	win_t *winp;

	CRITICAL_BEGIN();

	/* verify window mapped
	 */
	ASSERT( segix < tranp->t_segmaplen );
	winp = tranp->t_segmap[segix];
	ASSERT( winp );

	/* validate p
	 */
	ASSERT( pp );
	ASSERT( *pp );
	ASSERT( *pp >= winp->w_p );
	ASSERT( *pp < ( void * )( ( char * )( winp->w_p ) + tranp->t_segsz ));

	/* decrement the reference count. if zero, place at tail of LRU list.
	 */
	ASSERT( winp->w_refcnt > 0 );
	winp->w_refcnt--;
	ASSERT( ! winp->w_prevp );
	ASSERT( ! winp->w_nextp );
	if ( winp->w_refcnt == 0 ) {
		if ( tranp->t_lrutailp ) {
			ASSERT( tranp->t_lruheadp );
			winp->w_prevp = tranp->t_lrutailp;
			tranp->t_lrutailp->w_nextp = winp;
			tranp->t_lrutailp = winp;
		} else {
			ASSERT( ! tranp->t_lruheadp );
			ASSERT( ! winp->w_prevp );
			tranp->t_lruheadp = winp;
			tranp->t_lrutailp = winp;
		}
		ASSERT( ! winp->w_nextp );
	}

	/* zero the caller's pointer
	 */
	*pp = 0;

	CRITICAL_END();
}
示例#3
0
文件: tty.c 项目: SourcexRobin/Lenix
/* 2012.12.06*/
void *      Tty_echo_hook_set (int ttyid,void (* echo)(byte_t))
{
    tty_t               *   tty         = tty_pool + ttyid;
    void                *   handle      = NULL;
    CRITICAL_DECLARE(tty->tty_lock);

#ifdef _CFG_CHECK_PARAMETER_
    if( ttyid >= TTY_MAX )  return NULL;
    if( NULL == echo )      return NULL;
#endif  /*  _CFG_CHECK_PARAMETER_   */

    CRITICAL_BEGIN();
    handle = tty->tty_echo_hook;
    tty->tty_echo_hook = echo;
    CRITICAL_END();

    return handle;
}
示例#4
0
文件: tty.c 项目: SourcexRobin/Lenix
/*
//////////////////////////////////////////////////////////////////////////////////////////
//  名  称 : Tty_read
//
//  功  能 : 
//
//  参  数 : 
//      ttyid               : int
//      说明: tty编号
//
//      c                   : byte_t
//      说明: 需要放入tty的数据
//
//  返回值 : 
//      类型 :result_t 
//      说明 : 
//
//  注  意: 
//
//  变更记录:
//  时间        |    作  者     |  说  明
//========================================================================================
//  2013-12-05
//  2011-11-11  |               |
//////////////////////////////////////////////////////////////////////////////////////////
*/
int         Tty_read(int ttyid,void * buffer,size_t  size)
{
    tty_t               *   tty     = tty_pool + ttyid;
    byte_t              *   buf     = buffer;
    byte_t                  c       = 0;
    CRITICAL_DECLARE(tty->tty_lock);

#ifdef _CFG_CHECK_PARAMETER_
    if( ttyid >= TTY_MAX )	return -1;
    if( NULL == buffer )    return -1;
#endif  /*  _CFG_CHECK_PARAMETER_   */

    /*  终止条件是缓冲区满    */
    TTY_LOCK(tty);
    while( size )
    {
        CRITICAL_BEGIN();
        if( TQ_IS_EMPTY(tty->tty_second_queue) )
        {	/*  缓冲区空需要等待数据  */
            Proc_wait_on(&(tty->tty_wait));
            TTY_FREE(tty);  /*  */
            CRITICAL_END();
            Proc_sched(0);
            TTY_LOCK(tty);
        }
        else
        {
            TQ_GET_CHAR(tty->tty_second_queue,c);
            CRITICAL_END();
            *buf++ = c;
            if( CHAR_CR == c && ( tty->tty_termios.temo_type & TERMIOS_TYPE_TTY ) )
			{	/*  如果TTY是终端,遇到回车符需要返回。将回车符修改为0  */
				*--buf = 0;
                break;
			}
            --size;
        }
    }
    TTY_FREE(tty);
    return buf - (byte_t *)buffer;
}
示例#5
0
文件: win.c 项目: jkkm/xfsdump
void
win_map( segix_t segix, void **pp )
{
	off64_t segoff;
	win_t *winp;

	CRITICAL_BEGIN();

#ifdef TREE_DEBUG
	mlog(MLOG_DEBUG | MLOG_TREE | MLOG_NOLOCK,
	     "win_map(segix=%u,addr=%p)\n", segix, pp);
#endif
	/* resize the array if necessary */
	if ( segix >= tranp->t_segmaplen )
		win_segmap_resize( segix );

	/* see if segment already mapped. if ref cnt zero,
	 * remove from LRU list.
	 */
	winp = tranp->t_segmap[segix];
	if ( winp ) {
#ifdef TREE_DEBUG
		mlog(MLOG_DEBUG | MLOG_TREE | MLOG_NOLOCK,
		     "win_map(): requested segment already mapped\n");
#endif
		if ( winp->w_refcnt == 0 ) {
			ASSERT( tranp->t_lruheadp );
			ASSERT( tranp->t_lrutailp );
			if ( tranp->t_lruheadp == winp ) {
				if ( tranp->t_lrutailp == winp ) {
					tranp->t_lruheadp = 0;
					tranp->t_lrutailp = 0;
				} else {
					tranp->t_lruheadp = winp->w_nextp;
					tranp->t_lruheadp->w_prevp = 0;
				}
			} else {
				if ( tranp->t_lrutailp == winp ) {
					tranp->t_lrutailp = winp->w_prevp;
					tranp->t_lrutailp->w_nextp = 0;
				} else {
					winp->w_prevp->w_nextp = winp->w_nextp;
					winp->w_nextp->w_prevp = winp->w_prevp;
				}
			}
			winp->w_prevp = 0;
			winp->w_nextp = 0;
		} else {
			ASSERT( ! winp->w_prevp );
			ASSERT( ! winp->w_nextp );
		}
		winp->w_refcnt++;
		*pp = winp->w_p;
		CRITICAL_END();
		return;
	}

	/* Allocate a new descriptor if we haven't yet hit the maximum,
	 * otherwise reuse any descriptor on the LRU list.
	 */
	if ( tranp->t_wincnt < tranp->t_winmax ) {
#ifdef TREE_DEBUG
		mlog(MLOG_DEBUG | MLOG_TREE | MLOG_NOLOCK,
		     "win_map(): create a new window\n");
#endif
		winp = ( win_t * )calloc( 1, sizeof( win_t ));
		ASSERT( winp );
		tranp->t_wincnt++;
	} else if ( tranp->t_lruheadp ) {
		/* REFERENCED */
		intgen_t rval;
#ifdef TREE_DEBUG
		mlog(MLOG_DEBUG | MLOG_TREE | MLOG_NOLOCK,
		     "win_map(): get head from lru freelist & unmap\n");
#endif
		ASSERT( tranp->t_lrutailp );
		winp = tranp->t_lruheadp;
		tranp->t_lruheadp = winp->w_nextp;
		if ( tranp->t_lruheadp ) {
			tranp->t_lruheadp->w_prevp = 0;
		} else {
			tranp->t_lrutailp = 0;
		}
		tranp->t_segmap[winp->w_segix] = NULL;
		rval = munmap( winp->w_p, tranp->t_segsz );
		ASSERT( ! rval );
		memset( ( void * )winp, 0, sizeof( win_t ));
	} else {
		ASSERT( tranp->t_wincnt == tranp->t_winmax );
		*pp = NULL;
		CRITICAL_END();
		mlog( MLOG_NORMAL | MLOG_WARNING, _(
		      "all map windows in use. Check virtual memory limits\n"));
		return;
	}

	/* calculate offset of segment
	 */
	segoff = segix * ( off64_t )tranp->t_segsz;

	/* map the window
	 */
	ASSERT( tranp->t_segsz >= 1 );
	ASSERT( tranp->t_firstoff
		<=
		OFF64MAX - segoff - ( off64_t )tranp->t_segsz + 1ll );
	ASSERT( ! ( tranp->t_segsz % pgsz ));
	ASSERT( ! ( ( tranp->t_firstoff + segoff ) % ( off64_t )pgsz ));
#ifdef TREE_DEBUG
	mlog(MLOG_DEBUG | MLOG_TREE | MLOG_NOLOCK,
	     "win_map(): mmap segment at %lld, size = %llu\n",
	    ( off64_t )( tranp->t_firstoff + segoff ), tranp->t_segsz);
#endif
	tranp->t_winmmaps++;
	winp->w_p = mmap_autogrow(
			    tranp->t_segsz,
			    tranp->t_fd,
			    ( off64_t )( tranp->t_firstoff + segoff ));
	if ( winp->w_p == (void *)-1 ) {
		int	error = errno;
		mlog( MLOG_NORMAL | MLOG_ERROR, _(
		      "win_map(): unable to map a node segment of size %d at %d: %s\n"),
		      tranp->t_segsz, tranp->t_firstoff + segoff,
		      strerror( error ));

		tranp->t_wincnt--;
		tranp->t_winmax--;
		CRITICAL_END();
		free(winp);

		if (error == ENOMEM && tranp->t_lruheadp) {
			mlog( MLOG_NORMAL | MLOG_ERROR,
		      		_("win_map(): try to select a different win_t\n"));
			win_map(segix, pp);
			return;
		}
		*pp = NULL;
		return;
	}
	winp->w_segix  = segix;
	ASSERT( winp->w_refcnt == 0 );
	winp->w_refcnt++;
	tranp->t_segmap[winp->w_segix] = winp;

	*pp = winp->w_p;

	CRITICAL_END();
}
示例#6
0
文件: tty.c 项目: SourcexRobin/Lenix
/*
//////////////////////////////////////////////////////////////////////////////////////////
//  名  称 : Tty_put_char
//
//  功  能 : 
//
//  参  数 : 
//      ttyid               : int
//      说明: tty编号
//
//      c                   : byte_t
//      说明: 需要放入tty的数据
//
//  返回值 : 
//      类型 :result_t 
//      说明 : 
//
//  注  意: 在中断内调用
//
//  变更记录:
//  时间        |    作  者     |  说  明
//========================================================================================
//  2013-12-05
//  2011-11-11  |               |
//////////////////////////////////////////////////////////////////////////////////////////
*/
result_t    Tty_put_char(int ttyid,byte_t c)
{
    tty_t               *   tty     = tty_pool + ttyid;
    result_t                result  = RESULT_SUCCEED;
    CRITICAL_DECLARE(tty->tty_lock );

    if( ttyid >= TTY_MAX )
        return result;

    CRITICAL_BEGIN();
    /*
	 *  1、普通tty缓冲区满则丢弃数据,因为并不一定有等待数据的进程
	 *  2、如果是交互终端,则需要留下回车符和退格符的空间  
	 */
	if( TQ_LEFT(tty->tty_second_queue) == 0 ||
		( tty->tty_termios.temo_type == TERMIOS_TYPE_TTY && 
		!( TQ_LEFT(tty->tty_second_queue) > 4 || CHAR_BACK == c || CHAR_CR == c ) ) )
	{
        CRITICAL_END();
		return RESULT_FAILED;
	}
    TQ_PUT_CHAR( tty->tty_read_queue,c);
    CRITICAL_END();
    /*  定义了数据加工标志,则要对数据进行加工。  */
    if( tty->tty_termios.temo_iflags & TERMIOS_IFLAG_NEED_COOK )
        Tty_copy_to_cook(tty);
    else
    {
		TQ_INC((tty->tty_read_queue).tq_tail);
		TQ_PUT_CHAR(tty->tty_second_queue,c);
    }

    /*  如果终端定义了回显,也就是实时输出,则需要立即输出获得的数据  */
    if( tty->tty_termios.temo_oflags & TERMIOS_OFLAG_ECHO )
    {
        /*
         *  如果进入密码模式,一般的字符显示改为*号
         *  控制字符不改变显示
         */
        if( tty->tty_termios.temo_oflags & TERMIOS_OFLAG_PSW )
        {
            switch(c)
            {
            case CHAR_CR:
            case CHAR_BACK:
                break;
            default:
                c = '*';
                break;
            }
        }
        tty->tty_echo_hook(c);
    }

	switch(tty->tty_termios.temo_type)
	{
	case TERMIOS_TYPE_TTY:
		/*  交互终端对于回车符需要唤醒等待输入的进程 */
		if( CHAR_CR == c )
			TTY_WAKEUP(tty);
		break;
	default:
		/*  一般的tty在缓冲区满的时候,需要唤醒等待的进程  */
		if( TQ_LEFT(tty->tty_second_queue) == 0 )
			TTY_WAKEUP(tty);
		break;
	}

    return RESULT_SUCCEED;
}