亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? ctask.cxx

?? c-smile 一個語法類似與JS 又有點像C++的 編譯器
?? CXX
字號:
//-< CTASK.CXX >-----------------------------------------------------*--------*
// SAL                       Version 1.0         (c) 1997  GARRET    *     ?  *
// (System Abstraction Layer)                                        *   /\|  *
//                                                                   *  /  \  *
//                          Created:      7-Jan-97    K.A. Knizhnik  * / [] \ *
//                          Last update: 21-Nov-98    K.A. Knizhnik  * GARRET *
//-------------------------------------------------------------------*--------*
// Algorithm of portable multitasking is taken from Stig Kofoed article in
// DDJ of Novemeber 1995.
//-------------------------------------------------------------------*--------*

#include "task.h"
#include "async.h"

//
// Append protected page to task stack area. 
//
//#define CHECK_STACK_OVERFLOW 1

namespace sal
{

#ifdef CHECK_STACK_OVERFLOW
#include <unistd.h>
#include <sys/mman.h>
static int page_size;
#endif

//
// Defining this name adds very little overhead to program but make
// it possible to use normal C debugger for debugging multitasking application.
//
#define CTASK_DEBUGGING_SUPPORT 1

static int stack_guard;

#if defined(__osf__) || defined(__FreeBSD__)
#define longjmp(b,s) _longjmp(b,s) // do not restore signal context
#define setjmp(b)  _setjmp(b)
#endif

//
// Task prioritized queue
//

inline void task_queue::insert(task_internals* tp)
{
    task_internals **tpp;
    for (tpp = &queue; 
	 *tpp != NULL && (*tpp)->pri >= tp->pri; 
	 tpp = &(*tpp)->chain); 
    tp->chain = *tpp;
    *tpp = tp;
}

inline void task_queue::remove(task_internals* tp)
{
    task_internals **tpp;
    for (tpp = &queue; *tpp != tp; tpp = &(*tpp)->chain); 
    *tpp = tp->chain; 
}

inline task_internals* task_queue::first() 
{ 
    task_internals* t = queue; 
    if (t != NULL) { 
	queue = t->chain; 
    }
    return t; 
}

//
// Timer 
//


void ctimer::expired() 
{
    stop_timer();
    (*f)(arg);
}

void ctimer::start_timer(ctimer_callback_t cb, void* cb_arg, timeout_t msec)
{
    start = time(NULL); 
    timeout = msec;
    f = cb;
    arg = cb_arg;
    async_event_manager::add_timer(this);
} 

//
// Task 
//

task_queue      task_internals::ready_queue;
task_internals* task_internals::curr;
task_internals  task_internals::main;
jmp_buf         task_internals::creator_ctx;


#define    GUARD_VALUE   0xDEADDEED 

void task_internals::switch_context()
{
    assert(curr->himem_guard == GUARD_VALUE &&
	   curr->lomem_guard == GUARD_VALUE); 

    if (setjmp(ctx) == 0) { 
        curr = ready_queue.first();
	assert(curr != NULL /* deadlock*/);
	curr->state = tsk_run;

	// Check stack overflow
	assert(curr->himem_guard == GUARD_VALUE &&
	       curr->lomem_guard == GUARD_VALUE); 

	assert(curr->used);

	longjmp(curr->ctx, 1);
    } 
#ifdef CTASK_DEBUGGING_SUPPORT
    else debug_catch_task_activation();
#endif
}

inline size_t distance(task_internals* from, task_internals* to) 
{
    return (char*)from >= (char*)to
	? (char*)from - (char*)to    // stack grows up
	: (char*)to - (char*)from;   // stack grows down
} 
    

void task_internals::allocate(size_t requested_stack_size) 
{
    task   t;
    size_t d = distance(this, &t);

    if (d < requested_stack_size) {
	allocate(requested_stack_size); // never returns
    }
    
    t.lomem_guard = t.himem_guard = GUARD_VALUE; 
    t.size = size - d; 
    size = d;
    t.used = False;
    t.next_block = next_block; 
    next_block = &t; 

    if (setjmp(t.ctx) == 0) { // wait stack allocation request (from create)
	longjmp(ctx, 1);      // return to requester
    }
    while(True) { 
	if (t.stack_size + task::min_stack <= t.size) {
	    // split frame 
	    if (setjmp(t.ctx) == 0) { // previouse 'longjmp' will jump here
		t.allocate(t.stack_size); 
	    }
	}
	t.used = True;

	if (setjmp(t.ctx) == 0) { // wait untill task be activated by scheduler
	    longjmp(creator_ctx, 1); // return control to creator
	}

#ifdef CHECK_STACK_OVERFLOW
	long stack_base;
	if ((char*)this > (char*)&t) { // stack grows down
	    stack_base = ((long)(&t+1) - t.stack_size + page_size - 1)
		         & ~(page_size-1);
	} else { // stack grows up
	    stack_base = ((long)&t + t.stack_size - page_size)
		         & ~(page_size-1);
	}
	mprotect((void*)stack_base, page_size, PROT_NONE); 
#endif
	if (setjmp(t.exit_ctx) == 0) { 
	    (*t.f)(t.arg);
	    while (t.hold_mutexes != NULL) { 
		t.hold_mutexes->release();
	    }
	}
#ifdef CHECK_STACK_OVERFLOW
	mprotect((void*)stack_base, page_size, PROT_READ|PROT_WRITE); 
#endif

	t.used = False;
	if (t.next_block != NULL && !t.next_block->used) { 
	    t.size += t.next_block->size; // merge with the following frame
	    t.next_block = t.next_block->next_block; 
	}
	// locate previouse frame
	task_internals* tp;
	for (tp = &main; tp->next_block != &t; tp = tp->next_block); 
	if (tp != &main && !tp->used) { 
	    tp->size += t.size;
	    tp->next_block = t.next_block; 
	}

	t.switch_context();
    }
}    
	    
void task_proc task_internals::select_loop(void*)
{
    while(True) { 
        async_event_manager::select(ready_queue.is_empty());
	task::reschedule();
    }
}

void task::initialize(size_t main_stack_size) 
{ 
    task_internals t; 
#ifdef CHECK_STACK_OVERFLOW
    page_size = getpagesize();
    stack_guard = page_size*2;
    main_stack_size += stack_guard;
#endif
    
    t.size = LONG_MAX; // total stack area is not limited 
    t.next_block = NULL; 
    t.lomem_guard = t.himem_guard = GUARD_VALUE; 
    if (setjmp(t.ctx) == 0) { 
	t.allocate(main_stack_size);
    }
#ifdef CHECK_STACK_OVERFLOW
    long stack_base;
    if ((char*)t.next_block < (char*)&t) { // stack grows down
	stack_base = ((long)(t.next_block+1) + page_size-1) & ~(page_size-1);
    } else { 
	stack_base = ((long)t.next_block - page_size) & ~(page_size-1);
    }
    mprotect((void*)stack_base, page_size, PROT_NONE); 
#endif
    
    main = t;
    main.used = True;
    main.pri = pri_normal;
    main.state = tsk_run;
    main.wait_sem = NULL;
    main.hold_mutexes = NULL;
    curr = &main;
    create(select_loop, NULL, pri_background);
} 

task* task::create(fptr f, void* arg, priority pri, size_t stack_size)
{ 
    stack_size += stack_guard;
    assert(stack_size >= size_t(min_stack));

    for (task_internals* tp = main.next_block; tp != NULL; tp = tp->next_block)
    { 
	if (!tp->used && tp->size >= stack_size) { 
	    tp->f = f; 
	    tp->arg = arg; 
	    tp->stack_size = stack_size;
	    tp->pri = pri;
	    tp->wait_sem = NULL;
	    tp->hold_mutexes = NULL;
	    
	    if (setjmp(creator_ctx) == 0) { 
		longjmp(tp->ctx, 1);
	    }
	    tp->state = tsk_ready;
            ready_queue.insert(tp);
	    return (task*)tp;
	} 
    }
    return NULL;
}

void task::reschedule()
{
    if (!ready_queue.is_empty() && curr->pri <= ready_queue.queue->pri) {
	curr->state = tsk_ready;
	ready_queue.insert(curr);
	curr->switch_context();
    }
}

task* task::current() 
{
    return (task*)task_internals::curr;
}

void task_internals::kill()
{
    if (this == &main) { 
	::exit(EXIT_SUCCESS);
    }
    if (state == tsk_wait) {
	tmr.stop_timer();
	wait_sem->wait_queue.remove(this);
	wait_sem = NULL; 
    }
    while (hold_mutexes != NULL) { 
	hold_mutexes->release();
    }
    if (state == tsk_run) { 
	state = tsk_zombie;
	longjmp(exit_ctx, 1);
    } 
    memcpy(ctx, exit_ctx, sizeof ctx); 
    state = tsk_zombie;
}

void  task::exit() 
{
    task_internals::curr->kill(); 
} 

void  task::sleep(timeout_t msec) 
{
    static event never_happened;
    never_happened.wait_with_timeout(msec);
}

inline void task_internals::wakeup()
{ 
    assert(state == tsk_wait);
    wait_sem->wait_queue.remove(this);
    state = tsk_ready; 
    ready_queue.insert(this);
    timeout_expired = True;
} 

inline boolean task_internals::wait(semaphore_internals* sem, timeout_t msec)
{
     tmr.start_timer(timeout_expired_callback, this, msec);
     wait_sem = sem; 
     sem->wait_queue.insert(this);
     timeout_expired = False;
     state = tsk_wait;
     switch_context(); 
     return !timeout_expired;
}

inline void task_internals::wait(semaphore_internals* sem) 
{
    tmr.reset();
    wait_sem = sem; 
    sem->wait_queue.insert(this);
    curr->state = tsk_wait;
    switch_context(); 
}

inline void task_internals::signal()
{ 
    tmr.stop_timer();
    wait_sem = NULL;
    state = tsk_ready;
    ready_queue.insert(this);
}

void task_internals::timeout_expired_callback(void* arg)
{
    ((task_internals*)arg)->wakeup();
}

//
// Semaphore implementaion
//

void semaphore_internals::wait()
{
    if (count > 0) { 
	count -= 1;
    } else {
	task_internals::curr->wait(this);
    }
}    

boolean semaphore_internals::wait_with_timeout(timeout_t msec)
{
    if (count > 0) { 
	count -= 1;
	return True; 
    }
    if (msec == 0) { 
	return False; 
    } else { 
	return task_internals::curr->wait(this, msec);
    }
}

void semaphore_internals::signal() 
{
    task_internals* t = wait_queue.first();
    if (t != NULL) {
        t->signal();
    } else { 
	count += 1;
    }
}

//
// Events
//

void event_internals::signal() 
{
    while (!wait_queue.is_empty()) { 
	wait_queue.first()->signal();
    }
    count = 1;
}

void event_internals::wait()
{
    if (count == 0) { 
	task_internals::curr->wait(this);
    }
}    

boolean event_internals::wait_with_timeout(timeout_t msec)
{
    if (msec == 0) { 
	return count != 0;
    } else { 
	if (count != 0) { 
	    return True;
	} else { 
	    return task_internals::curr->wait(this, msec);
	}
    }
}

//
// Mutex
//

void mutex_internals::enter()
{
    if (task_internals::curr != owner) { 
	while (owner != NULL) { 
	    wait();
	}
	owner = task_internals::curr; 
	next_hold = owner->hold_mutexes;
	owner->hold_mutexes = this; 
    }	
    nest += 1;
}

void mutex_internals::release()
{
    mutex_internals** mpp;

    if ( owner == NULL ) return;

    for (mpp = &owner->hold_mutexes; *mpp != this; mpp = &(*mpp)->next_hold);
    *mpp = next_hold;
    owner = NULL;
    nest = 0;
    if (!wait_queue.is_empty()) { 
	signal();
    }
}     

void mutex_internals::leave()
{
    assert(owner == task_internals::curr); 
    if (--nest == 0) { 
	release();
	task::reschedule();
    }
}



#ifdef CTASK_DEBUGGING_SUPPORT

//
// Set breakpoint to this function and call debug_select_task(int) function to 
// see task backtrace (call stack). 
//
void debug_catch_task_activation() {}

int debug_get_number_of_tasks()
{
    int n = 0;
    for (task_internals* tp = &task_internals::main; 
	 tp != NULL; 
	 tp = tp->next_block)
    { 
	if (tp->used) { 
	    n += 1;
	}
    }
    return n;
}

//
// Switch context to specified task. Total number of active tasks in process
// can be obtained by debug_get_number_of_tasks() function. Index of task 
// passed as parameter to this function should be positive number less than
// value returned by debug_get_number_of_tasks(). Task with index 0 refers
// to currently active task. This task can't be activated with this function.
// After specified task is activated, control is passed to function 
// debug_catch_task_activation() and then execution of task is continued. 
// If task index doesn't belong to valid range -1 is returned. 
// Otherwise control from this function will not returned (longjmp). 
// 
int debug_select_task(int i) 
{
    for (task_internals* tp = &task_internals::main; 
	 tp != NULL; 
	 tp = tp->next_block)
    { 
	if (tp->used && tp->state != task_internals::tsk_run && --i == 0) { 
	    task_internals::curr = tp;
	    longjmp(tp->ctx, 2);
	}
    }
    return -1;
} 

};
#endif


?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日韩精品乱码免费| 中文字幕第一区第二区| 亚洲18女电影在线观看| 欧美午夜精品久久久久久孕妇 | 日韩视频免费观看高清完整版| 无码av中文一区二区三区桃花岛| 3d动漫精品啪啪1区2区免费| 日本人妖一区二区| 久久久亚洲精品一区二区三区| 成人免费视频视频| 亚洲综合图片区| 欧美一区二区三区电影| 国产成人综合亚洲网站| 日韩理论片一区二区| 欧美性极品少妇| 国产综合久久久久影院| 国产精品久久久久久久午夜片| 欧美午夜宅男影院| 狠狠色丁香婷婷综合| 亚洲欧洲精品一区二区三区| 欧美日韩一区视频| 国产大陆a不卡| 亚洲成人三级小说| 久久精品亚洲麻豆av一区二区| 99re视频精品| 久久精品99国产精品日本| 国产女主播在线一区二区| 色婷婷亚洲综合| 狠狠色狠狠色合久久伊人| 亚洲乱码国产乱码精品精的特点 | 亚洲一区视频在线观看视频| 日韩欧美国产一二三区| 99re视频精品| 精品写真视频在线观看| 亚洲精品写真福利| 欧美激情综合五月色丁香| 欧美另类高清zo欧美| 成人国产一区二区三区精品| 免费美女久久99| 亚洲精品福利视频网站| 中文字幕精品三区| 欧美videos中文字幕| 欧美午夜在线观看| 成人app在线| 国产精品香蕉一区二区三区| 亚洲高清视频的网址| 成人欧美一区二区三区| 久久久久免费观看| 日韩一区二区三区观看| 色综合久久久网| 丁香激情综合五月| 青青草原综合久久大伊人精品优势| 亚洲视频在线观看一区| 久久精品欧美一区二区三区不卡| 欧美日韩精品二区第二页| 色综合天天综合网天天看片| 国产成人精品一区二| 国产一区二区在线看| 麻豆精品视频在线观看| 亚洲va国产天堂va久久en| 亚洲美女免费在线| 日韩一区欧美一区| 18成人在线视频| 中文字幕精品一区二区三区精品| 久久综合中文字幕| 欧美大尺度电影在线| 欧美一级爆毛片| 在线成人免费视频| 欧美丰满一区二区免费视频| 91国产精品成人| 在线观看亚洲a| 欧美色综合天天久久综合精品| 91久久精品网| 欧美日韩亚洲高清一区二区| 欧美天堂亚洲电影院在线播放| 在线亚洲精品福利网址导航| 日本高清免费不卡视频| 在线观看视频欧美| 欧美私模裸体表演在线观看| 欧美性受极品xxxx喷水| 欧美日韩高清一区| 日韩一区国产二区欧美三区| 日韩女同互慰一区二区| 精品成a人在线观看| 国产欧美一区二区在线观看| 中文字幕在线不卡视频| 亚洲精品乱码久久久久久黑人| 亚洲人精品午夜| 亚洲国产精品欧美一二99| 日韩精品久久理论片| 久久黄色级2电影| 国产裸体歌舞团一区二区| 国产精品中文字幕日韩精品| 岛国一区二区三区| 色噜噜久久综合| 91精品国产91久久综合桃花| 欧美va亚洲va香蕉在线| 国产精品私人影院| 亚洲综合在线观看视频| 美日韩一区二区三区| 福利一区福利二区| 在线观看成人小视频| 这里是久久伊人| 久久亚洲精品国产精品紫薇| 中文字幕国产一区| 亚洲成va人在线观看| 国产美女娇喘av呻吟久久| 99精品视频中文字幕| 91精品在线观看入口| 国产欧美精品区一区二区三区| 亚洲精选免费视频| 精品中文字幕一区二区小辣椒 | 国产一区二区视频在线播放| 不卡的av电影| 777欧美精品| 国产精品家庭影院| 麻豆精品在线观看| 91麻豆国产自产在线观看| 日韩写真欧美这视频| 国产精品国产三级国产aⅴ无密码| 天堂成人国产精品一区| 99天天综合性| 26uuu精品一区二区三区四区在线| 亚洲免费视频成人| 国产一区二区h| 欧美理论电影在线| 亚洲天堂免费看| 国产在线国偷精品免费看| 欧美无乱码久久久免费午夜一区| 国产日韩欧美精品一区| 偷拍自拍另类欧美| www.欧美色图| 2020国产精品久久精品美国| 亚洲成a人片在线观看中文| 成人精品鲁一区一区二区| 日韩欧美中文一区二区| 亚洲午夜激情网页| 成人免费视频app| 久久伊人蜜桃av一区二区| 日本欧美在线观看| 欧美色图在线观看| 亚洲精选视频在线| 成人国产一区二区三区精品| 欧美成人一区二区三区在线观看| 亚洲成人动漫一区| 欧美在线|欧美| 一区二区免费看| 色88888久久久久久影院野外| 国产欧美日本一区视频| 久久97超碰色| 精品免费99久久| 美美哒免费高清在线观看视频一区二区 | 国产成人在线观看| 精品va天堂亚洲国产| 久久97超碰国产精品超碰| 91精品国产入口| 奇米精品一区二区三区在线观看一| 欧美性生活久久| 亚洲第一av色| 777奇米四色成人影色区| 亚洲aⅴ怡春院| 欧美日韩第一区日日骚| 一区二区欧美精品| 欧美日韩亚洲综合在线| 天天综合色天天| 337p亚洲精品色噜噜狠狠| 午夜视频在线观看一区二区| 欧美亚洲国产怡红院影院| 亚洲精品国产一区二区精华液 | 不卡一二三区首页| 国产精品色呦呦| 一本久道中文字幕精品亚洲嫩 | 日本欧美在线看| 欧美va亚洲va香蕉在线| 国产乱子伦视频一区二区三区| 久久久99久久| 成人av资源网站| 一区二区三区四区av| 欧美日韩精品一区二区| 日韩av电影免费观看高清完整版| 欧美一二区视频| 国产麻豆成人精品| 日韩一区在线播放| 欧美日韩精品一区二区三区蜜桃| 日本免费在线视频不卡一不卡二| 精品欧美乱码久久久久久 | 亚洲日本电影在线| 欧美日韩精品专区| 激情图片小说一区| 国产精品传媒视频| 欧美男男青年gay1069videost| 婷婷久久综合九色国产成人| 日韩精品一区二区三区在线| 丁香婷婷综合五月| 亚洲国产精品久久久久婷婷884 | 日本v片在线高清不卡在线观看| 精品日韩欧美在线| a在线播放不卡| 日本中文字幕一区二区有限公司| 国产亚洲欧洲一区高清在线观看|