int u_green_init() { static int i; if (!ug.ugreen) { return 0; } ug.u_stack_size = UGREEN_DEFAULT_STACKSIZE; if (ug.stackpages > 0) { ug.u_stack_size = ug.stackpages * uwsgi.page_size; } uwsgi_log("initializing %d uGreen threads with stack size of %lu (%lu KB)\n", uwsgi.async, (unsigned long) ug.u_stack_size, (unsigned long) ug.u_stack_size/1024); ug.contexts = uwsgi_malloc( sizeof(ucontext_t) * uwsgi.async); for(i=0;i<uwsgi.async;i++) { getcontext(&ug.contexts[i]); ug.contexts[i].uc_stack.ss_sp = mmap(NULL, ug.u_stack_size + (uwsgi.page_size*2) , PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0) + uwsgi.page_size; if (!ug.contexts[i].uc_stack.ss_sp) { uwsgi_error("mmap()"); exit(1); } // set guard pages for stack if (mprotect(ug.contexts[i].uc_stack.ss_sp - uwsgi.page_size, uwsgi.page_size, PROT_NONE)) { uwsgi_error("mprotect()"); exit(1); } if (mprotect(ug.contexts[i].uc_stack.ss_sp + ug.u_stack_size, uwsgi.page_size, PROT_NONE)) { uwsgi_error("mprotect()"); exit(1); } ug.contexts[i].uc_stack.ss_size = ug.u_stack_size; } uwsgi.schedule_to_main = u_green_schedule_to_main; uwsgi.schedule_to_req = u_green_schedule_to_req; return 0; }
int create_client(int ls, int s, CLI *arg, void *(*cli)(void *)) { CONTEXT *context; (void)ls; /* this parameter is only used with USE_FORK */ s_log(LOG_DEBUG, "Creating a new context"); context=new_context(); if(!context) { if(arg) str_free(arg); if(s>=0) closesocket(s); return -1; } /* initialize context_t structure */ if(getcontext(&context->context)<0) { str_free(context); if(arg) str_free(arg); if(s>=0) closesocket(s); ioerror("getcontext"); return -1; } context->context.uc_link=NULL; /* stunnel does not use uc_link */ /* create stack */ context->stack=str_alloc(arg->opt->stack_size); if(!context->stack) { str_free(context); if(arg) str_free(arg); if(s>=0) closesocket(s); s_log(LOG_ERR, "Unable to allocate stack"); return -1; } str_detach(context->stack); #if defined(__sgi) || ARGC==2 /* obsolete ss_sp semantics */ context->context.uc_stack.ss_sp=context->stack+arg->opt->stack_size-8; #else context->context.uc_stack.ss_sp=context->stack; #endif context->context.uc_stack.ss_size=arg->opt->stack_size; context->context.uc_stack.ss_flags=0; makecontext(&context->context, (void(*)(void))cli, ARGC, arg); s_log(LOG_DEBUG, "New context created"); return 0; }
int main() { getcontext(&uctx_main); //AMJAD: Added uctx_main int thread_num = 10; int j; char* thread_names[] = { "thread 0", "thread 1", "thread 2", "thread 3", "thread 4", "thread 5", "thread 6", "thread 7", "thread 8", "thread 9" }; /* Initialize MyThreads library. */ mythread_init(); /* 250 ms */ set_quantum_size(250); counter_mutex = create_semaphore(1); for(j=0; j<thread_num; j++) { mythread_create(thread_names[j], (void *) &handler, 6004); } /* Print threads informations before run */ mythread_state(); /* When this function returns, all threads should have exited. */ runthreads(); destroy_semaphore(counter_mutex); /* Print threads informations after run */ mythread_state(); printf("The counter is %d\n", counter); printf("The result is %f\n", result); if (counter == 50 && (result - 151402.656521) < 0.000001) printf(">>> Thread library PASSED the Test 1\n"); exit(0); }
bool Cothread::resume(CothreadId id) { auto schedule = getScheduleBlock(); CothreadBlock *block = getCothreadBlock(id); bool ret = true; if(block == NULL || block->status == RunningStatus::Shutdown) return (ret = false); // switch(block->status) { case RunningStatus::Ready: getcontext(&block->ctx); // block->stack = new char[COTHREAD_STACK_SIZE]; if(block->stack == NULL) { ret = false; break; } //init stack block->ctx.uc_stack.ss_sp = block->stack; block->ctx.uc_stack.ss_size = COTHREAD_STACK_SIZE; block->ctx.uc_stack.ss_flags = 0; block->ctx.uc_link = &schedule->ctx; //create a new running environment //a 64bit os may cause problem here? makecontext(&block->ctx, (void (*)())Cothread::schedule, 1, this ); case RunningStatus::Suspend: schedule->runningId = block->id; #ifdef DEBUG cout << "Cothread begin to start/resume" << endl; #endif swapcontext(&schedule->ctx, &block->ctx); //after swap back, it is necessary to check if the thread exited if(block->status == RunningStatus::Shutdown) { freeCothreadBlock(id); ret = false; } break; default: ;//do nothing } return ret; }
G* __go_go(void (*fn)(void*), void* arg) { byte *sp; size_t spsize; G * volatile newg; // volatile to avoid longjmp warning schedlock(); if((newg = gfget()) != nil){ #ifdef USING_SPLIT_STACK sp = __splitstack_resetcontext(&newg->stack_context[0], &spsize); #else sp = newg->gcinitial_sp; spsize = newg->gcstack_size; newg->gcnext_sp = sp; #endif } else { newg = runtime_malg(StackMin, &sp, &spsize); if(runtime_lastg == nil) runtime_allg = newg; else runtime_lastg->alllink = newg; runtime_lastg = newg; } newg->status = Gwaiting; newg->waitreason = "new goroutine"; newg->entry = (byte*)fn; newg->param = arg; newg->gopc = (uintptr)__builtin_return_address(0); runtime_sched.gcount++; runtime_sched.goidgen++; newg->goid = runtime_sched.goidgen; if(sp == nil) runtime_throw("nil g->stack0"); getcontext(&newg->context); newg->context.uc_stack.ss_sp = sp; newg->context.uc_stack.ss_size = spsize; makecontext(&newg->context, kickoff, 0); newprocreadylocked(newg); schedunlock(); return newg; //printf(" goid=%d\n", newg->goid); }
ucontext_thread_group(int num_threads, Function f) : thread_group() { if(num_threads) { // make a copy of the parameters for each thread // for arguments to makecontext typedef std::pair<ucontext_thread_group*,Function> exec_parms_t; void (*exec)(exec_parms_t *) = exec_thread<Function>; std::vector<exec_parms_t> exec_parms(num_threads, std::make_pair(this,f)); // save the return state state join_state; getcontext(&join_state); if(thread_state.empty()) { thread_state.resize(num_threads); for(int i = 0; i < thread_state.size(); ++i) { getcontext(&thread_state[i]); thread_state[i].uc_link = &join_state; thread_state[i].uc_stack.ss_sp = thread_state[i].stack; thread_state[i].uc_stack.ss_size = sizeof(thread_state[i].stack); makecontext(&thread_state[i], (void(*)())exec, 1, &exec_parms[i]); } // start thread 0 set_current_thread_id(0); setcontext(&thread_state[0]); } // when we've reached this point, all the threads in the group have terminated } // end if // null the current thread_group this_thread_group::__singleton = 0; }
/* The gtthread_init() function does not have a corresponding pthread equivalent. It must be called from the main thread before any other GTThreads functions are called. It allows the caller to specify the scheduling period (quantum in micro second), and may also perform any other necessary initialization. If period is zero, then thread switching should occur only on calls to gtthread_yield(). Recall that the initial thread of the program (i.e. the one running main() ) is a thread like any other. It should have a gtthread_t that clients can retrieve by calling gtthread_self() from the initial thread, and they should be able to specify it as an argument to other GTThreads functions. The only difference in the initial thread is how it behaves when it executes a return instruction. You can find details on this difference in the man page for pthread_create. */ void gtthread_init(long period){ gtthread_int_t *mainthread; /* Malloc for this thread */ if ((mainthread = malloc(sizeof(gtthread_int_t))) != NULL){ /* Initialize queues */ steque_init(&threads); steque_init(&run_queue); /* Set up mainthread */ mainthread->id = next_id++; mainthread->cancelreq = 0; mainthread->completed = 0; steque_init(&mainthread->join_queue); /* Set up the context */ getcontext(&mainthread->context); mainthread->context.uc_stack.ss_sp = (char *) malloc(SIGSTKSZ); mainthread->context.uc_stack.ss_size = SIGSTKSZ; steque_enqueue(&threads, mainthread); steque_enqueue(&run_queue, mainthread); /* Initialize the scheduling quantum */ quantum = period; if (quantum != 0) { /* Setting up the signal mask */ sigemptyset(&vtalrm); sigaddset(&vtalrm, SIGVTALRM); /* Setting up the alarm */ timer = (struct itimerval*) malloc(sizeof(struct itimerval)); timer->it_value.tv_sec = timer->it_interval.tv_sec = 0; timer->it_value.tv_usec = timer->it_interval.tv_usec = quantum; /* Setting up the handler */ memset(&act, '\0', sizeof(act)); act.sa_handler = &alrm_handler; if (sigaction(SIGVTALRM, &act, NULL) < 0) { printf("sigaction"); } setitimer(ITIMER_VIRTUAL, timer, NULL); sigprocmask(SIG_UNBLOCK, &vtalrm, NULL); } } // FIXME: what about the error case? }
void mythread_init() { tcb *thread = new tcb(next_id); next_id++; thread_list[thread->id] = thread; ucontext_t main; getcontext(&thread->context); thread->context.uc_stack.ss_sp = thread->stack; thread->context.uc_stack.ss_size = stackSize; thread->context.uc_link = NULL; this_th_th=thread->id; }
void __sigcleanup(struct sigcontext *scp) { ucontext_t uc, *ucp; int sig; /* * If there's a pointer to a ucontext_t hiding in the sigcontext, * we *must* use that to return, since it contains important data * such as the original "out" registers when the signal occurred. */ if (scp->sc_wbcnt == sizeof (*ucp)) { sig = (int)(uintptr_t)scp->sc_spbuf[0]; ucp = (ucontext_t *)scp->sc_spbuf[1]; } else { /* * Otherwise, use a local ucontext_t and * initialize it with getcontext. */ sig = 0; ucp = &uc; (void) getcontext(ucp); } if (scp->sc_onstack) { ucp->uc_stack.ss_flags |= SS_ONSTACK; } else ucp->uc_stack.ss_flags &= ~SS_ONSTACK; mask2set(scp->sc_mask, &ucp->uc_sigmask); ucp->uc_mcontext.gregs[REG_SP] = scp->sc_sp; ucp->uc_mcontext.gregs[REG_PC] = scp->sc_pc; ucp->uc_mcontext.gregs[REG_nPC] = scp->sc_npc; #if defined(__sparcv9) ucp->uc_mcontext.gregs[REG_CCR] = scp->sc_psr; #else ucp->uc_mcontext.gregs[REG_PSR] = scp->sc_psr; #endif ucp->uc_mcontext.gregs[REG_G1] = scp->sc_g1; ucp->uc_mcontext.gregs[REG_O0] = scp->sc_o0; if (sig == SIGFPE) { if (ucp->uc_mcontext.fpregs.fpu_qcnt > 0) { ucp->uc_mcontext.fpregs.fpu_qcnt--; ucp->uc_mcontext.fpregs.fpu_q++; } } (void) setcontext(ucp); /* NOTREACHED */ }
/* The gtthread_create() function mirrors the pthread_create() function, only default attributes are always assumed. */ int gtthread_create(gtthread_t *thread, void *(*start_routine)(void *), void *arg){ ucontext_t uctx; gtthread_blk_t *th_blk; DEBUG_MSG("gtthread_create\n"); //sigprocmask(SIG_BLOCK, &vtalrm, NULL); // disable alarm signal /************************* Initialize the context *************************************/ if(getcontext(&uctx) == -1) return FAIL; uctx.uc_stack.ss_sp = (char*) malloc(SIGSTKSZ); uctx.uc_stack.ss_size = SIGSTKSZ; uctx.uc_link = NULL; makecontext(&uctx, (void (*) (void))(thread_handler), 2, start_routine, arg); // modify the context /************************** Initialize the thread block *************************************/ th_blk = (gtthread_blk_t *)malloc(sizeof(gtthread_blk_t)); if(th_blk == NULL) return FAIL; th_blk->tID = thread_ID++; th_blk->state = READY; th_blk->uctx = uctx; if(th_blk->uctx.uc_stack.ss_size == SIGSTKSZ) DEBUG_MSG("Correct assign\n"); /********************************************************************************************/ steque_enqueue(&thread_queue, th_blk); // add the thread to the scheduler queue //sigprocmask(SIG_UNBLOCK, &vtalrm, NULL); // enable alarm signal *thread = th_blk->tID; //list_thread(); gtthread_yield(); return SUCCESS; }
int swapcontext(ucontext_t * oucp, const ucontext_t * ucp) { int ret; if ((oucp == NULL) || (ucp == NULL)) { /*errno = EINVAL; */ return -1; } ret = getcontext(oucp); if (ret == 0) { ret = setcontext(ucp); } return ret; }
struct thread* initializeThread() { ucontext_t *ucp; ucp = (ucontext_t*)malloc(sizeof(ucontext_t)); getcontext(ucp); struct thread* temp = (struct thread*)malloc(sizeof(struct thread)); temp->context = ucp; temp->context->uc_stack.ss_sp = malloc(16384); temp->context->uc_stack.ss_size = 16384; temp->next = NULL; temp->prev = NULL; return temp; }
thread_t *thread_create(thread_context_t *ctx, thread_fn *start, void *user) { thread_t *t; t = calloc(1, sizeof(*t)); t->start = start; t->user = user; getcontext(&t->context); t->context.uc_stack.ss_sp = malloc(STACK_SIZE); t->context.uc_stack.ss_size = STACK_SIZE; t->context.uc_link = &ctx->poller; makecontext(&t->context, start_thread, 4, PTR(ctx), PTR(t)); return t; }
static void setExitContext() { static int exitContextCreated; if(!exitContextCreated) { getcontext(&exitContext); exitContext.uc_link = 0; exitContext.uc_stack.ss_sp = malloc(STACKSIZE); exitContext.uc_stack.ss_size = STACKSIZE; exitContext.uc_stack.ss_flags= 0; makecontext(&exitContext, (void (*) (void))&executeExitContext, 0); exitContextCreated = 1; } }
int thread_create(char *id, int tickets, void (*rutina)(int, int), int arg, int idInt) { struct Thread *newThread = getNewThreadnoStack(tickets, id); ucontext_t context; getcontext(&(context)); context.uc_stack.ss_sp = malloc(STACKSIZE); context.uc_stack.ss_size = STACKSIZE; context.uc_stack.ss_flags = 0; context.uc_link = &mainContext; makecontext (&(context), (void (*) (void))generalFunction, 3, rutina, arg, idInt); scheduler->addTask(newThread, context); return 1; }
/* =================================================================================================== spe_routine_create =================================================================================================== */ spe_routine_t* spe_routine_create(void) { spe_routine_t* routine = calloc(1, sizeof(spe_routine_t)); if (!routine) { SPE_LOG_ERR("routine calloc error"); return NULL; } getcontext(&routine->context); routine->context.uc_stack.ss_sp = routine->stack; routine->context.uc_stack.ss_size = sizeof(routine->stack); routine->handler = SPE_HANDLER_NULL; makecontext(&routine->context, (void(*)(void))routine_main, 1, routine); return routine; }
/* * Swap the current context for the context of the thread * passed by this function. * * If the thread is new ( !THREAD_IS_STARTED ) the the context * must be built. * * If the thread has already started then we simple resume the * context * * Threads are set to return to the calling process when completed * or yeiled. */ void _MyThreadRun( Thread* t ) { if( t->flags & THREAD_IS_STARTED ) { swapcontext(&t->return_ctx, &t->ctx); } else { t->flags |= THREAD_IS_STARTED; getcontext(&t->ctx); t->ctx.uc_stack.ss_sp = malloc(STACK_SIZE); t->ctx.uc_stack.ss_size = STACK_SIZE; t->ctx.uc_link = &t->return_ctx; if( t->func != NULL ) makecontext(&t->ctx, t->func, 1, t->args); swapcontext(&t->return_ctx, &t->ctx); } };
void dump_img(void) { // 2. read /proc/self/maps to get section headers, then get memory dump create_memory_checkpoint(); // 1. getcontext to save registers values ucontext_t mycontext; from_recover = 0; getcontext(&mycontext); // if this is not from recover, save the context and exit the program if (from_recover == 0) { write_context_to_ckpt_header(&mycontext, sizeof mycontext); exit(0); } }
void uctx_coro_makectx(struct coro_ctx *ctx, size_t ctx_size, void* (*f)(void*)) { if (getcontext(&ctx->uctx) < 0) { perror("getcontext"); abort(); } ctx->uctx.uc_stack.ss_sp = (void *)ctx + sizeof(struct coro_ctx); ctx->uctx.uc_stack.ss_size = ctx_size - sizeof(struct coro_ctx); ctx->uctx.uc_link = NULL; /* according to makecontext(3), to be portable we must pass pointer by a pair of int args */ makecontext(&ctx->uctx, (void(*)())uctx_coro_main, 2, (int)f, (int)((uintptr_t)f >> (sizeof(int)*8))); }
void __asmSaveContextAndCallScheduler() { /* Create new scheduler context */ getcontext(&signal_context); signal_context.uc_stack.ss_sp = signal_stack; signal_context.uc_stack.ss_size = STACKSIZE; signal_context.uc_stack.ss_flags = 0; sigemptyset(&signal_context.uc_sigmask); makecontext(&signal_context, (void (*)())schedulerWrapper, 1,contextT); /* save running thread, jump to scheduler */ swapcontext(contextT,&signal_context); }
void init() { head = NULL; act.sa_handler = sighandler; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGALRM, &act, 0); getcontext(&scheduler_context); scheduler_context.uc_stack.ss_sp = malloc(SZ); scheduler_context.uc_stack.ss_size = SZ; scheduler_context.uc_stack.ss_flags = 0; scheduler_context.uc_link = &main_context; makecontext(&scheduler_context, thread_run, 0); getcontext(&killer_context); killer_context.uc_stack.ss_sp = malloc(SZ); killer_context.uc_stack.ss_size = SZ; killer_context.uc_stack.ss_flags = 0; killer_context.uc_link = 0; makecontext(&killer_context, thread_kill, 0); }
/* Timer interrupt handler. Creates a new context to run the scheduler in, masks signals, then swaps contexts saving the previously executing thread and jumping to the scheduler. */ void timer_interrupt(int j, siginfo_t *si, void *old_context) { /* Create new scheduler context */ getcontext(&signal_context); signal_context.uc_stack.ss_sp = signal_stack; signal_context.uc_stack.ss_size = STACKSIZE; signal_context.uc_stack.ss_flags = 0; sigemptyset(&signal_context.uc_sigmask); makecontext(&signal_context, scheduler, 0); /* save running thread, jump to scheduler */ swapcontext(cur_context,&signal_context); }
afs_int32 savecontext(void (*ep) (void), struct lwp_context *savearea, char *newsp) { #if defined(AFS_LINUX20_ENV) /* getcontext does not export stack info */ int stackvar; #endif PRE_Block = 1; savearea->state = 0; getcontext(&savearea->ucontext); #if defined(AFS_LINUX20_ENV) savearea->topstack = &stackvar; #else savearea->topstack = savearea->ucontext.uc_stack.ss_sp; #endif switch (savearea->state) { case 0: if (newsp) { ucontext_t thread; getcontext(&thread); thread.uc_stack.ss_sp = newsp - AFS_LWP_MINSTACKSIZE + sizeof(void *) + sizeof(void *); thread.uc_stack.ss_size = AFS_LWP_MINSTACKSIZE - sizeof(void *); makecontext(&thread, ep, 0); setcontext(&thread); } else (*ep) (); break; case 2: break; } return 0; }
int t_init (void (*fun_addr)(), int fun_arg) { int i,j,k; //finds an empty slot for (i=1; i<N; i++) { if (t_state[i].state == FREE) break; } if (i == N) return(-1); if(getcontext(&t_state[i].run_env) == -1) { perror("getcontext in t_init"); exit(5); } t_state[i].state = INIT; t_state[i].function = fun_addr; t_state[i].mystk.ss_sp = (void *)(malloc(STACKSIZE)); if(t_state[i].mystk.ss_sp == NULL) { printf("thread failed to get stack space\n"); exit(8); } t_state[i].mystk.ss_size = STACKSIZE; t_state[i].mystk.ss_flags = 0; t_state[i].run_env.uc_stack = t_state[i].mystk; t_state[i].run_env.uc_link = &t_state[i].rtn_env; // t_state[i].rtn_env.uc_stack = t_state[i].mystk; getcontext(&t_state[i].rtn_env); makecontext(&t_state[i].rtn_env,returncontext,0); makecontext(&t_state[i].run_env, fun_addr, 1,fun_arg); return(i); }
// Called to start an M. void* runtime_mstart(void* mp) { m = (M*)mp; g = m->g0; initcontext(); g->entry = nil; g->param = nil; // Record top of stack for use by mcall. // Once we call schedule we're never coming back, // so other calls can reuse this stack space. #ifdef USING_SPLIT_STACK __splitstack_getcontext(&g->stack_context[0]); #else g->gcinitial_sp = ∓ // Setting gcstack_size to 0 is a marker meaning that gcinitial_sp // is the top of the stack, not the bottom. g->gcstack_size = 0; g->gcnext_sp = ∓ #endif getcontext(&g->context); if(g->entry != nil) { // Got here from mcall. void (*pfn)(G*) = (void (*)(G*))g->entry; G* gp = (G*)g->param; pfn(gp); *(int*)0x21 = 0x21; } runtime_minit(); #ifdef USING_SPLIT_STACK { int dont_block_signals = 0; __splitstack_block_signals(&dont_block_signals, nil); } #endif // Install signal handlers; after minit so that minit can // prepare the thread to be able to handle the signals. if(m == &runtime_m0) runtime_initsig(); schedule(nil); return nil; }
void myThreadInit(long pTimeInterval) { //DEBUGGING debuggingFile = fopen("DebuggingFile.txt", "w"); //DEBUGGING if (threadsQueue == NULL && deadThreadsQueue == NULL) { sigemptyset(&sigProcMask); sigaddset(&sigProcMask, SIGPROF); deadThreadsQueue = createDeadTheadsNodesQueue(); threadsQueue = createTCBQueue(); if (deadThreadsQueue == NULL || threadsQueue == NULL) { return; } else { srand((unsigned) time(&randomTimeSeed)); timeInterval = pTimeInterval * 1000; threadsQueue->quantum = pTimeInterval; TCB TCBMain = createNewTCB(); getcontext(&(TCBMain->threadContext)); setExitContext(); TCBMain->threadContext.uc_link = &exitContext; //La linea de abajo indica que el thread principal es administrado por el scheduler RoundRobin. // TCBMain->roundRobin = 1; // roundRobinControl = 1; // Descomentar las lineas comentadas de abajo y comentar la linea de arriba si se quiere que el thread principal sea administrado por el scheduler Sort. TCBMain->sort = 1; int nextTicket = searchEndTicket(threadsQueue); TCBMain->initialTicket = nextTicket; TCBMain->finalTicket = nextTicket; sortControl = 1; // threadsQueue->currentThread = TCBMain; insertThread(threadsQueue, TCBMain); memset(&schedulerHandle, 0, sizeof (schedulerHandle)); schedulerHandle.sa_handler = &realTime; sigaction(SIGPROF, &schedulerHandle, NULL); //printf("\nMyThread: Biblioteca MyThread Inicializada...\n"); timeQuantum.it_value.tv_sec = 0; timeQuantum.it_value.tv_usec = timeInterval; timeQuantum.it_interval.tv_sec = 0; timeQuantum.it_interval.tv_usec = timeInterval; setitimer(ITIMER_PROF, &timeQuantum, NULL); } } }
/*++ Function: CONTEXT_GetRegisters Abstract retrieve the machine registers value of the indicated process. Parameter processId: process ID registers: reg structure in which the machine registers value will be returned. Return returns TRUE if it succeeds, FALSE otherwise --*/ BOOL CONTEXT_GetRegisters(DWORD processId, ucontext_t *registers) { #if HAVE_BSD_REGS_T int regFd = -1; #endif // HAVE_BSD_REGS_T BOOL bRet = FALSE; if (processId == GetCurrentProcessId()) { #if HAVE_GETCONTEXT if (getcontext(registers) != 0) { ASSERT("getcontext() failed %d (%s)\n", errno, strerror(errno)); return FALSE; } #elif HAVE_BSD_REGS_T char buf[MAX_PATH]; struct reg bsd_registers; sprintf_s(buf, sizeof(buf), "/proc/%d/regs", processId); if ((regFd = PAL__open(buf, O_RDONLY)) == -1) { ASSERT("PAL__open() failed %d (%s) \n", errno, strerror(errno)); return FALSE; } if (lseek(regFd, 0, 0) == -1) { ASSERT("lseek() failed %d (%s)\n", errno, strerror(errno)); goto EXIT; } if (read(regFd, &bsd_registers, sizeof(bsd_registers)) != sizeof(bsd_registers)) { ASSERT("read() failed %d (%s)\n", errno, strerror(errno)); goto EXIT; } #define ASSIGN_REG(reg) MCREG_##reg(registers->uc_mcontext) = BSDREG_##reg(bsd_registers); ASSIGN_ALL_REGS #undef ASSIGN_REG #else #error "Don't know how to get current context on this platform!" #endif } else {
void thread_init(long nquantum, int totalProcessInit, struct sched_t *schedulerIn) { scheduler = schedulerIn; sigemptyset(&sigsetMask); sigaddset(&sigsetMask,SIGPROF); getcontext(&mainContext); memset(&schedulerHandle,0,sizeof(schedulerHandle)); schedulerHandle.sa_handler = timer_handler; sigaction(SIGPROF,&schedulerHandle,NULL); timeIntervalInMSec = nquantum; quantum.it_value.tv_sec = 0;// http://linux.die.net/man/2/setitimer quantum.it_value.tv_usec = timeIntervalInMSec; quantum.it_interval.tv_sec=0; quantum.it_interval.tv_usec = timeIntervalInMSec; states = (state*)malloc(sizeof(state) * totalProcessInit); int k; for( k = 0; k < totalProcessInit; k++){ state newState;; newState.id = k; newState.finish = 0; newState.percent = 0.0; newState.result = 0.0; newState.active = 0; states[k] = newState; } /*if(mode == EXPROPIATIVO) setitimer(ITIMER_PROF, &quantum, NULL);*/ /* sigemptyset(&sigsetMask); sigaddset(&sigsetMask, SIGPROF); //para mandar sennal cuando expire el timer timeIntervalInMSec = nquantum; schedulerHandle.sa_sigaction = timer_handler; schedulerHandle.sa_flags = SA_SIGINFO|SA_RESTART; sigemptyset(&schedulerHandle.sa_mask); sigaction(SIGRTMIN, &schedulerHandle, NULL); //inicializo el quantum quantum.it_value.tv_sec = 0;// http://linux.die.net/man/2/setitimer quantum.it_value.tv_usec = timeIntervalInMSec; quantum.it_interval.tv_sec=0; quantum.it_interval.tv_usec = timeIntervalInMSec; setitimer(ITIMER_PROF, &quantum, NULL);*/ }
MyThread MyThreadCreate (void(*start_funct)(void *), void *args) //Finalizes Create Thread Function { MyThread* child = insertNode(ready_queue); getcontext(&(child->context)); child->context.uc_stack.ss_sp=malloc(MEM); child->context.uc_stack.ss_size=MEM; child->context.uc_stack.ss_flags=0; child->id = threadCount++; child->parent = ready_queue->id; child->context.uc_link=&controller; makecontext(&(child->context), (void*)start_funct, 1, (int)args); //printf("\nHi, this is the %d thread getting created, my parent is: %d", child->id, ready_queue->id); //printQueues(); return *child; }
static int co_set_context(co_ctx_t *ctx, void *func, char *stkbase, long stksiz) { if (getcontext(&ctx->cc)) return -1; ctx->cc.uc_link = NULL; ctx->cc.uc_stack.ss_sp = stkbase; ctx->cc.uc_stack.ss_size = stksiz - sizeof(long); ctx->cc.uc_stack.ss_flags = 0; makecontext(&ctx->cc, func, 1); return 0; }