// thread relinquish use of the processor // and wait in the ready queuee void th_yield() { entry_section(); if (threads[curr]->state == RUNNING) rq_push(curr); else if (threads[curr]->state == WAITING) wq_push(curr); // transfer the control to the next thread if (rq_begin != rq_end) { int old = curr; curr = rq_front(); rq_pop(); threads[curr]->state = RUNNING; exit_section(); th_swap(threads[old], threads[curr]); entry_section(); recycle_dead(); } exit_section(); }
/* handle received messages */ uint8_t rxCallback(linkID_t port) { uint8_t len; packet_t thePacket; /* is the callback for the link ID we want to handle? */ if (port == myLinkID) { if ((SMPL_SUCCESS == SMPL_Receive(myLinkID, (uint8_t *) &thePacket, &len)) && len) { uint8_t plen = thePacket.dlen + HEADER_SIZE; uint8_t *packet_ptr = (uint8_t *) &thePacket; if (thePacket.dev_id != BS_ID) return 1; if (plen <= len) { // add to the queue uint8_t i; for (i = 0; i < plen; i++) rq_push(packet_ptr[i]); newRepPacket++; } // drop frame. we're done with it. return 1; } } /* keep frame for later handling */ return 0; }
void on_accept(int fd, short ev, void *arg){ int client_fd, err_len; char *err, *err_log; struct sockaddr_in client_addr; socklen_t client_len; client_len = sizeof(client_addr); uint64_t u; ssize_t s; extern NOTIFY_TOKEN_STATE notify_token_thread; extern int token_efd; int isDep; /* Accept the new connection. */ client_fd = accept(fd, (struct sockaddr *)&client_addr, &client_len); if (client_fd == -1) { err = strerror(errno); /*err_len = strlen(err); err_log = calloc(1, err_len+10); sprintf(err_log, "accept-- %s", err); d_log(err_log); free(err_log);*/ DEBUG("accept error %s --", err); return; } if(rq_push(client_fd) == 0){ if(notify_token_thread == NT_FREE){ /* thread = work_threads+1; write(thread->notify_write_fd, "", 1); token_sem_post();*/ u = 1; s = write(token_efd, &u , sizeof(uint64_t)); if(s != sizeof(uint64_t))DEBUG("write to token_efd"); } /*else{ DEBUG("notify_token error"); } */ }else{ close(client_fd); d_log("RQ is full"); } if(proc_status == NT_FREE){ proc_status = NT_HAS; anyThread(fproc, NULL); } }
static void put_dead(int tid) { th_data *dtd = threads[tid]->u; wstatus[tid] = dtd->status; // check wait queue that waits for tid int i; for (i=wq_begin; i!=wq_end; i=(i+1)%MAX_QUEUE) { int ctid = wait_queue[i]; th_data *td = threads[ctid]->u; if (td->waitfor == tid) { wait_queue[i] = wq_front(); wq_pop(); rq_push(ctid); } } // check ready queue if tid in it if (threads[tid]->state == READY) for (i=rq_begin; i!=rq_end; i=(i+1)%MAX_QUEUE) { if (ready_queue[i] == tid) { rq_end = (rq_end+MAX_QUEUE-1)%MAX_QUEUE; if (rq_end != i) { ready_queue[i] = ready_queue[rq_end]; break; } } } // check wait queue if tid in it if (threads[tid]->state == WAITING) for (i=wq_begin; i!=wq_end; i=(i+1)%MAX_QUEUE) { if (wait_queue[i] == tid) { wq_end = (wq_end+MAX_QUEUE-1)%MAX_QUEUE; if (wq_end != i) { wait_queue[i] = wait_queue[rq_end]; break; } } } recycle_dead(); dead_thread = tid; threads[tid]->state = TERMINATED; recycle_dead(); }
// thread creation int th_fork(th_t *thread, void *(*start_routine)(void*), void *arg) { if (thread == 0 || start_routine == 0) return -1; entry_section(); th_start(); th_data *td = thread->u; td->param = arg; td->func = start_routine; thread->tid = th_it; threads[th_it] = thread; makecontext(&thread->uct, th_caller, 0); rq_push(th_it); th_next(); exit_section(); return 0; }