int main (int argc, char **argv) { error_t err; pthread_rwlockattr_t attr; pthread_rwlock_t lock; int pshared; int i; pthread_t tid[THREADS]; void *ret; err = pthread_rwlockattr_init (&attr); if (err) error (1, err, "pthread_rwlockattr_init"); err = pthread_rwlockattr_getpshared (&attr, &pshared); if (err) error (1, err, "pthread_rwlockattr_getpshared"); /* Assert the default state as mandated by POSIX. */ assert (pshared == PTHREAD_PROCESS_PRIVATE); err = pthread_rwlockattr_setpshared (&attr, pshared); if (err) error (1, err, "pthread_rwlockattr_setpshared"); err = pthread_rwlock_init (&lock, &attr); if (err) error (1, err, "pthread_rwlock_init"); err = pthread_rwlockattr_destroy (&attr); if (err) error (1, err, "pthread_rwlockattr_destroy"); /* Now test the lock. */ for (i = 0; i < THREADS; i++) { err = pthread_create (&tid[i], 0, test1, &lock); if (err) error (1, err, "pthread_create"); } for (i = 0; i < 10; i++) { sched_yield (); /* Get a write lock. */ pthread_rwlock_wrlock (&lock); /* Increment a and b giving other threads a chance to run in between. */ sched_yield (); a++; sched_yield (); b++; sched_yield (); /* Unlock. */ pthread_rwlock_unlock (&lock); } for (i = 0; i < THREADS; i++) { err = pthread_join (tid[i], &ret); if (err) error (1, err, "pthread_join"); } /* Read lock it. */ err = pthread_rwlock_tryrdlock (&lock); assert (err == 0); /* Try to write lock it. It should fail with EBUSY. */ err = pthread_rwlock_trywrlock (&lock); assert (err == EBUSY); /* Drop the read lock. */ err = pthread_rwlock_unlock (&lock); assert (err == 0); /* Get a write lock. */ err = pthread_rwlock_trywrlock (&lock); assert (err == 0); /* Fail trying to acquire another write lock. */ err = pthread_rwlock_trywrlock (&lock); assert (err == EBUSY); /* Try to get a read lock which should also fail. */ err = pthread_rwlock_tryrdlock (&lock); assert (err == EBUSY); /* Unlock it. */ err = pthread_rwlock_unlock (&lock); assert (err == 0); err = pthread_rwlock_destroy (&lock); if (err) error (1, err, "pthread_rwlock_destroy"); return 0; }
void timer_del_safe(struct timer_ln* tl) #endif { again: /* quick exit if timer inactive */ if ( !(tl->flags & F_TIMER_ACTIVE)){ #ifdef TIMER_DEBUG LOG(timerlog, "timer_del called on an inactive timer %p (%p, %p)," " flags %x\n", tl, tl->next, tl->prev, tl->flags); LOG(timerlog, "WARN: -timer_del-; called from %s(%s):%d\n", func, file, line); LOG(timerlog, "WARN: -timer_del-: added %d times" ", last from: %s(%s):%d, deleted %d times" ", last from: %s(%s):%d, init %d times, expired %d \n", tl->add_calls, tl->add_func, tl->add_file, tl->add_line, tl->del_calls, tl->del_func, tl->del_file, tl->del_line, tl->init, tl->expires_no); #else DBG("timer_del called on an inactive timer %p (%p, %p)," " flags %x\n", tl, tl->next, tl->prev, tl->flags); #endif return; } #ifdef USE_SLOW_TIMER if (IS_ON_SLOW_LIST(tl) && (tl->slow_idx!=*t_idx)){ LOCK_SLOW_TIMER_LIST(); if (!IS_ON_SLOW_LIST(tl) || (tl->slow_idx==*t_idx)){ UNLOCK_SLOW_TIMER_LIST(); goto again; } if (IS_RUNNING_SLOW(tl)){ UNLOCK_SLOW_TIMER_LIST(); if (IS_IN_TIMER_SLOW()){ /* if somebody tries to shoot himself in the foot, * warn him and ignore the delete */ LOG(L_CRIT, "BUG: timer handle %p (s) tried to delete" " itself\n", tl); #ifdef TIMER_DEBUG LOG(timerlog, "WARN: -timer_del-: called from %s(%s):%d\n", func, file, line); LOG(timerlog, "WARN: -timer_del-: added %d times" ", last from: %s(%s):%d, deleted %d times" ", last from: %s(%s):%d, init %d times, expired %d \n", tl->add_calls, tl->add_func, tl->add_file, tl->add_line, tl->del_calls, tl->del_func, tl->del_file, tl->del_line, tl->init, tl->expires_no); #endif return; /* do nothing */ } sched_yield(); /* wait for it to complete */ goto again; } if (tl->next!=0){ _timer_rm_list(tl); /* detach */ tl->next=tl->prev=0; #ifdef TIMER_DEBUG tl->del_file=file; tl->del_func=func; tl->del_line=line; tl->flags|=F_TIMER_DELETED; #endif }else{ #ifdef TIMER_DEBUG LOG(timerlog, "timer_del: (s) timer %p (%p, %p) flags %x " "already detached\n", tl, tl->next, tl->prev, tl->flags); LOG(timerlog, "WARN: -timer_del-: @%d tl=%p " "{ %p, %p, %d, %d, %p, %p, %04x, -}\n", get_ticks_raw(), tl, tl->next, tl->prev, tl->expire, tl->initial_timeout, tl->data, tl->f, tl->flags); LOG(timerlog, "WARN: -timer_del-; called from %s(%s):%d\n", func, file, line); LOG(timerlog, "WARN: -timer_del-: added %d times" ", last from: %s(%s):%d, deleted %d times" ", last from: %s(%s):%d, init %d times, expired %d \n", tl->add_calls, tl->add_func, tl->add_file, tl->add_line, tl->del_calls, tl->del_func, tl->del_file, tl->del_line, tl->init, tl->expires_no); #else DBG("timer_del: (s) timer %p (%p, %p) flags %x " "already detached\n", tl, tl->next, tl->prev, tl->flags); #endif } UNLOCK_SLOW_TIMER_LIST(); }else{ #endif LOCK_TIMER_LIST(); #ifdef USE_SLOW_TIMER if (IS_ON_SLOW_LIST(tl) && (tl->slow_idx!=*t_idx)){ UNLOCK_TIMER_LIST(); goto again; } #endif if (IS_RUNNING(tl)){ UNLOCK_TIMER_LIST(); if (IS_IN_TIMER()){ /* if somebody tries to shoot himself in the foot, * warn him and ignore the delete */ LOG(L_CRIT, "BUG: timer handle %p tried to delete" " itself\n", tl); #ifdef TIMER_DEBUG LOG(timerlog, "WARN: -timer_del-: called from %s(%s):%d\n", func, file, line); LOG(timerlog, "WARN: -timer_del-: added %d times" ", last from: %s(%s):%d, deleted %d times" ", last from: %s(%s):%d, init %d times, expired %d \n", tl->add_calls, tl->add_func, tl->add_file, tl->add_line, tl->del_calls, tl->del_func, tl->del_file, tl->del_line, tl->init, tl->expires_no); #endif return; /* do nothing */ } sched_yield(); /* wait for it to complete */ goto again; } if ((tl->next!=0)&&(tl->prev!=0)){ _timer_rm_list(tl); /* detach */ tl->next=tl->prev=0; #ifdef TIMER_DEBUG tl->del_file=file; tl->del_func=func; tl->del_line=line; tl->flags|=F_TIMER_DELETED; #endif }else{ #ifdef TIMER_DEBUG LOG(timerlog, "timer_del: (f) timer %p (%p, %p) flags %x " "already detached\n", tl, tl->next, tl->prev, tl->flags); LOG(timerlog, "WARN: -timer_del-: @%d tl=%p " "{ %p, %p, %d, %d, %p, %p, %04x, -}\n", get_ticks_raw(), tl, tl->next, tl->prev, tl->expire, tl->initial_timeout, tl->data, tl->f, tl->flags); LOG(timerlog, "WARN: -timer_del-; called from %s(%s):%d\n", func, file, line); LOG(timerlog, "WARN: -timer_del-: added %d times" ", last from: %s(%s):%d, deleted %d times" ", last from: %s(%s):%d, init %d times, expired %d \n", tl->add_calls, tl->add_func, tl->add_file, tl->add_line, tl->del_calls, tl->del_func, tl->del_file, tl->del_line, tl->init, tl->expires_no); #else DBG("timer_del: (f) timer %p (%p, %p) flags %x " "already detached\n", tl, tl->next, tl->prev, tl->flags); #endif } UNLOCK_TIMER_LIST(); #ifdef USE_SLOW_TIMER } #endif }
/* * Rollback transaction. */ static inline void stm_rollback(stm_tx_t *tx, int reason) { w_entry_t *w; int i; PRINT_DEBUG("==> stm_rollback(%p[%lu-%lu])\n", tx, (unsigned long)tx->start, (unsigned long)tx->end); assert(IS_ACTIVE(tx->status)); /* Drop locks */ i = tx->w_set.nb_entries; if (i > 0) { w = tx->w_set.entries; for (; i > 0; i--, w++) { if (w->next == NULL) { /* Only drop lock for last covered address in write set */ ATOMIC_STORE(w->lock, LOCK_SET_TIMESTAMP(w->version)); } } /* Make sure that all lock releases become visible */ ATOMIC_MB_WRITE; } tx->retries++; tx->aborts++; if (tx->retries == 1) tx->aborts_1++; else if (tx->retries == 2) tx->aborts_2++; if (tx->max_retries < tx->retries) tx->max_retries = tx->retries; /* Callbacks */ if (nb_abort_cb != 0) { int cb; for (cb = 0; cb < nb_abort_cb; cb++) abort_cb[cb].f(TXARGS abort_cb[cb].arg); } /* Set status to ABORTED */ SET_STATUS(tx->status, TX_ABORTED); /* Reset nesting level */ tx->nesting = 1; /* Wait until contented lock is free */ if (tx->c_lock != NULL) { /* Busy waiting (yielding is expensive) */ while (LOCK_GET_OWNED(ATOMIC_LOAD(tx->c_lock))) { sched_yield(); } tx->c_lock = NULL; } /* Reset field to restart transaction */ stm_prepare(tx); /* Jump back to transaction start */ if (tx->attr == NULL || !tx->attr->no_retry) siglongjmp(tx->env, reason); }
int main(void) { int child_count, i; struct sched_param param; int *child_pid; float ratio; /* Only use a single CPU and one child process when set_affinity is availaible.It's because no matter what value of the counter is set to, There is no guarantee that the LOOP of the child can be certainly big enough on any device at any time. */ int rc = set_affinity_single(); if (rc) { nb_child = get_ncpu(); if (nb_child == -1) { printf("Can not get the number of" "CPUs of your machine.\n"); return PTS_UNRESOLVED; } } else { nb_child = 1; } child_pid = malloc(nb_child * sizeof(int)); if (child_pid == NULL) { printf("malloc failed\n"); return PTS_UNRESOLVED; } param.sched_priority = (sched_get_priority_min(SCHED_RR) + sched_get_priority_max(SCHED_RR)) / 2; if (sched_setscheduler(getpid(), SCHED_RR, ¶m) == -1) { if (errno == EPERM) { printf ("This process does not have the permission to set its own scheduling policy.\nTry to launch this test as root\n"); } else { perror ("An error occurs when calling sched_setscheduler()"); } return PTS_UNRESOLVED; } if (signal(SIGTERM, sigterm_handler) == SIG_ERR) { perror("An error occurs when calling signal()"); return PTS_UNRESOLVED; } pipe(the_pipe); for (i = 0; i < nb_child; i++) { child_pid[i] = fork(); if (child_pid[i] == -1) { perror("An error occurs when calling fork()"); return PTS_UNRESOLVED; } else if (child_pid[i] == 0) { child_process(i); printf("This code should not be executed.\n"); return PTS_UNRESOLVED; } } param.sched_priority = sched_get_priority_max(SCHED_RR); if (sched_setparam(0, ¶m) != 0) { perror("An error occurs when calling sched_setparam()"); return PTS_UNRESOLVED; } close(STDIN); close(the_pipe[1]); dup2(the_pipe[0], STDIN); close(the_pipe[0]); for (i = 0; i < NB_LOOP; i++) { count++; } if (kill(child_pid[nb_child - 1], SIGTERM) != 0) { perror("An error occurs when calling kill()"); return PTS_UNRESOLVED; } param.sched_priority = sched_get_priority_min(SCHED_RR); if (sched_setparam(0, ¶m) != 0) { perror("An error occurs when calling sched_setparam()"); return PTS_UNRESOLVED; } while (scanf("*%i*", &child_count) == 0) sched_yield(); for (i = 0; i < (nb_child - 1); i++) { if (kill(child_pid[i], SIGKILL) != 0) { perror("An error occurs when calling kill()"); return PTS_UNRESOLVED; } } if (child_count) ratio = (float)count / (float)child_count; if (child_count == 0 || ratio >= ACCEPTABLE_RATIO) { printf("Test PASSED\n"); return PTS_PASS; } else if (ratio <= (1 / ACCEPTABLE_RATIO)) { printf ("Higher numerical values for the priority represent the lower priorities.\n"); return PTS_FAIL; } else { printf ("The difference between the processes is not representative.\n"); return PTS_UNRESOLVED; } }
void *receiver(void* data) { char buffer[NUM_MSGS]; int count = 0; size_t recv_size; mca_status_t status; int i; mcapi_param_t parms; mcapi_info_t version; /* create a node */ mcapi_initialize(DOMAIN,NODE+1,NULL,&parms,&version,&status); if (status != MCAPI_SUCCESS) { fprintf(stderr,"\nFAIL: Failed to initialize: %s\n",mcapi_display_status(status,status_buff,sizeof(status_buff))); WRONG; } /* make recv endpoint */ recv_endpt = mcapi_endpoint_create(1,&status); if (status != MCAPI_SUCCESS) { fprintf(stderr,"\nFAIL: Failed to create recv endpoint: %s\n",mcapi_display_status(status,status_buff,sizeof(status_buff))); WRONG; } /* do the receives */ for (count = 0; count < NUM_MSGS; count++) { mcapi_msg_recv(recv_endpt, buffer, sizeof(buffer), &recv_size, &status); if ((status != MCAPI_SUCCESS) && (TIMEOUT)) { /* yield and then retry */ for (i = 0; i < TIMEOUT; i++) { if (status != MCAPI_SUCCESS) { fprintf(stderr,"\nWARNING: Recv failed: reason:%s recv_count:%d. Will yield and re-try.\n",mcapi_display_status(status,status_buff,sizeof(status_buff)),count); sched_yield(); mcapi_msg_recv(recv_endpt, buffer, sizeof(buffer), &recv_size, &status); } if (status == MCAPI_SUCCESS) { break; } } } if (status == MCAPI_SUCCESS) { printf("count=%d, Received: [%s]\n",count,buffer); } else { fprintf(stderr,"\nFAIL: Recv failed: reason:%s recv_count:%d.\n",mcapi_display_status(status,status_buff,sizeof(status_buff)),count); WRONG; } } /* finalize */ mcapi_finalize(&status); if (status != MCAPI_SUCCESS) { fprintf(stderr,"\nFAIL: Failed to finalize: %s\n",mcapi_display_status(status,status_buff,sizeof(status_buff))); WRONG; } return NULL; }
/** * Code for the consumer threads. They take the orders and process them. The * argument to this function should be a null-terminated string representing the * category name for this thread. */ void *consumer_thread(void *args) { char *category, *input; customer_t *customer; order_t *order; receipt_t *receipt; // Get the category for this thread. input = (char *) args; category = (char *) malloc(strlen(input) + 1); strcpy(category, input); while (!is_done || !queue_isempty(queue)) { // We wait until there is something in the queue pthread_mutex_lock(&queue->mutex); if (!is_done && queue_isempty(queue)) { pthread_cond_wait(&queue->nonempty, &queue->mutex); } if (is_done && queue_isempty(queue)) { // No more orders to process. Exit this thread. pthread_mutex_unlock(&queue->mutex); return NULL; } else if (queue_isempty(queue)) { // The queue is empty again. pthread_mutex_unlock(&queue->mutex); sched_yield(); continue; } order = (order_t *) queue_peek(queue); if (strcmp(order->category, category) != 0) { // This book is not in our category. pthread_mutex_unlock(&queue->mutex); sched_yield(); } else { // Process the order. order = (order_t *) queue_dequeue(queue); customer = database_retrieve_customer(customerDatabase, order->customer_id); if (!customer) { // Invalid customer ID fprintf(stderr, "There is no customer in the database with" "customer ID %d.\n", order->customer_id); } else { receipt = receipt_create(order->title, order->price, customer->credit_limit - order->price); if (customer->credit_limit < order->price) { // Insufficient funds. printf("%s has insufficient funds for a purchase.\n" "\tBook: %s\n\tRemaining credit: $%.2f\n\n", customer->name, order->title, customer->credit_limit); queue_enqueue(customer->failed_orders, receipt); } else { // Subtract price from remaining credit customer->credit_limit -= order->price; printf("Customer %s has made a successful purchase!\n" "\tBook: %s\n\tPrice: $%.2f\n" "\tRemaining credit: $%.2f\n\n", customer->name, order->title, order->price, customer->credit_limit); queue_enqueue(customer->successful_orders, receipt); } } order_destroy(order); pthread_mutex_unlock(&queue->mutex); } } free(category); return NULL; }
RETINFO_t *map_and_thread(char *tmpfile, /* name of temporary file to be created */ void *(*exec_func) (void *), /* thread function to execute */ int fault_type, /* type of fault to be generated */ int num_thread, /* number of threads to create */ RETINFO_t * retinfo) { /* return map address and oper status */ int fd = 0; /* file descriptor of the file created */ int thrd_ndx = 0; /* index to the number of threads created */ int map_type = 0; /* specifies the type of the mapped object */ void *th_status; /* status of the thread when it is finished */ long th_args[5]; /* argument list passed to thread_fault() */ char *empty_buf = NULL; /* empty buffer used to fill temp file */ long pagesize /* contains page size at runtime */ = sysconf(_SC_PAGESIZE); static pthread_t pthread_ids[NUMTHREAD]; /* contains ids of the threads created */ caddr_t map_addr = NULL; /* address where the file is mapped */ /* Create a file with permissions 0666, and open it with RDRW perms */ /* if the name is not a NULL */ if (strcmp(tmpfile, "NULL")) { if ((fd = open(tmpfile, O_RDWR | O_CREAT, S_IRWXO | S_IRWXU | S_IRWXG)) == -1) { perror("map_and_thread(): open()"); close(fd); fflush(NULL); retinfo->status = FAILED; return retinfo; } /* Write pagesize * pages_num bytes to the file */ empty_buf = (char *)malloc(pagesize * pages_num); if (write(fd, empty_buf, pagesize * pages_num) != (pagesize * pages_num)) { perror("map_and_thread(): write()"); free(empty_buf); fflush(NULL); remove_files(tmpfile, NULL); close(fd); retinfo->status = FAILED; return retinfo; } map_type = (fault_type == COW_FAULT) ? MAP_PRIVATE : MAP_SHARED; /* Map the file, if the required fault type is COW_FAULT map the file */ /* private, else map the file shared. if READ_FAULT is required to be */ /* generated map the file with read protection else map with read - */ /* write protection. */ if ((map_addr = (caddr_t) mmap(0, pagesize * pages_num, ((fault_type == READ_FAULT) ? PROT_READ : PROT_READ | PROT_WRITE), map_type, fd, 0)) == MAP_FAILED) { perror("map_and_thread(): mmap()"); free(empty_buf); fflush(NULL); remove_files(tmpfile, NULL); close(fd); retinfo->status = FAILED; return retinfo; } else { retinfo->mapaddr = map_addr; if (verbose_print) tst_resm(TINFO, "map_and_thread(): mmap success, address = %p", map_addr); fflush(NULL); } } /* As long as wait is set to TRUE, the thread that will be created will */ /* loop in its exec routine */ wait_thread = TRUE; /* Create a few threads, ideally number of threads equals number of CPU'S */ /* so that we can assume that each thread will run on a single CPU in */ /* of SMP machines. Currently we will create NR_CPUS number of threads. */ th_args[1] = (long)map_addr; th_args[2] = pagesize; th_args[3] = fault_type; do { th_args[0] = thrd_ndx; th_args[4] = (long)0; /*************************************************************/ /* The way it was, args could be overwritten by subsequent uses * of it before the called routine had a chance to fully initialize. * This flag stops the overwrite until that routine gets to * begin. At that point, it is done initializing and it is * safe for the this thread to continue (which will change * args). * A basic race condition. */ thread_begin = TRUE; if (pthread_create(&pthread_ids[thrd_ndx++], NULL, exec_func, (void *)&th_args)) { perror("map_and_thread(): pthread_create()"); thread_begin = FALSE; free(empty_buf); fflush(NULL); remove_files(tmpfile, map_addr); close(fd); retinfo->status = FAILED; return retinfo; } else { /***************************************************/ /* Yield until new thread is done with args. */ while (thread_begin) sched_yield(); } } while (thrd_ndx < num_thread); if (verbose_print) tst_resm(TINFO, "map_and_thread(): pthread_create() success"); wait_thread = FALSE; /* suspend the execution of the calling thread till the execution of the */ /* other thread has been terminated. */ for (thrd_ndx = 0; thrd_ndx < NUMTHREAD; thrd_ndx++) { if (pthread_join(pthread_ids[thrd_ndx], &th_status)) { perror("map_and_thread(): pthread_join()"); free(empty_buf); fflush(NULL); remove_files(tmpfile, map_addr); close(fd); retinfo->status = FAILED; return retinfo; } else { if ((long)th_status == 1) { tst_resm(TINFO, "thread [%ld] - process exited with errors", (long)pthread_ids[thrd_ndx]); free(empty_buf); remove_files(tmpfile, map_addr); close(fd); exit(1); } } } /* remove the temporary file that was created. - clean up */ /* but dont try to remove special files. */ /***********************************************/ /* Was if !(remove_files()) ... * If that routine succeeds, it returns SUCCESS, which * happens to be 0. So if the routine succeeded, the * above condition would indicate failure. This change * fixes that. */ if (remove_files(tmpfile, map_addr) == FAILED) { free(empty_buf); retinfo->status = FAILED; return retinfo; } free(empty_buf); close(fd); retinfo->status = SUCCESS; return retinfo; }
void CmiYield(void) { sched_yield(); }
static void yield() {sched_yield();};
int fork_parent() { int p[2]; pid_t pid; char buffer[READ_BUFFER]; int rr, status, result; if (pipe(p)) { return -1; } fflush(stderr); pid = fork(); if(pid < 0){ return -1; } if(pid == 0){ /* in child - make pipe stderr and detach from terminal */ close(p[0]); if (p[1] != STDERR_FILENO) { if (dup2(p[1], STDERR_FILENO) != STDERR_FILENO) { exit(EX_OSERR); } close(p[1]); } close(STDOUT_FILENO); close(STDIN_FILENO); /* TODO: could point STDIN and STDOUT at /dev/null */ setsid(); return 0; } /* in parent - read from pipe, exit when pipe closes */ close(p[1]); do { rr = read(p[0], buffer, READ_BUFFER); switch (rr) { case -1: switch (errno) { case EAGAIN: case EINTR: rr = 1; break; default: fprintf(stderr, "unable to read error messages: %s\n", strerror(errno)); fflush(stderr); break; } break; case 0: /* eof */ break; default: write(STDERR_FILENO, buffer, rr); /* don't care if write fails, can't do anything about it */ break; } } while (rr > 0); sched_yield(); result = 0; if (waitpid(pid, &status, WNOHANG) > 0) { /* got a child */ if (WIFEXITED(status)) { result = WEXITSTATUS(status); fprintf(stderr, "exited with code %d\n", result); } else if (WIFSIGNALED(status)) { fprintf(stderr, "killed by signal %d\n", WTERMSIG(status)); fflush(stderr); result = EX_SOFTWARE; #if 0 /* mimic child - problematic, it may ovewrite the child core file */ result = WTERMSIG(status); raise(result); #endif #if 0 } else if (WIFSTOPPED(status)) { /* too clever by half */ result = WSTOPSIG(status); fprintf(stderr, "stopped by signal %d, restarting with %d\n", result, SIGCONT); kill(pid, SIGCONT); result = 0; #endif } } /* else child probably ok */ exit(result); /* not reached */ return -1; }
void Thread::Yield() { #ifdef _POSIX_PRIORITY_SCHEDULING sched_yield(); #endif //_POSIX_PRIORITY_SCHEDULING }
/* Devilishly complex routine. * * Has to deal with EOF and EPIPE on input, * with line wrapping, with last line not ending in '\n' * (possibly not ending YET!), with backspace and tabs. * It reads input again if last time we got an EOF (thus supporting * growing files) or EPIPE (watching output of slow process like make). * * Variables used: * flines[] - array of lines already read. Linewrap may cause * one source file line to occupy several flines[n]. * flines[max_fline] - last line, possibly incomplete. * terminated - 1 if flines[max_fline] is 'terminated' * (if there was '\n' [which isn't stored itself, we just remember * that it was seen]) * max_lineno - last line's number, this one doesn't increment * on line wrap, only on "real" new lines. * readbuf[0..readeof-1] - small preliminary buffer. * readbuf[readpos] - next character to add to current line. * last_line_pos - screen line position of next char to be read * (takes into account tabs and backspaces) * eof_error - < 0 error, == 0 EOF, > 0 not EOF/error */ static void read_lines(void) { #define readbuf bb_common_bufsiz1 char *current_line, *p; int w = width; char last_terminated = terminated; #if ENABLE_FEATURE_LESS_REGEXP unsigned old_max_fline = max_fline; time_t last_time = 0; unsigned seconds_p1 = 3; /* seconds_to_loop + 1 */ #endif if (option_mask32 & FLAG_N) w -= 8; IF_FEATURE_LESS_REGEXP(again0:) p = current_line = ((char*)xmalloc(w + 4)) + 4; max_fline += last_terminated; if (!last_terminated) { const char *cp = flines[max_fline]; strcpy(p, cp); p += strlen(current_line); free(MEMPTR(flines[max_fline])); /* last_line_pos is still valid from previous read_lines() */ } else { last_line_pos = 0; } while (1) { /* read lines until we reach cur_fline or wanted_match */ *p = '\0'; terminated = 0; while (1) { /* read chars until we have a line */ char c; /* if no unprocessed chars left, eat more */ if (readpos >= readeof) { ndelay_on(0); eof_error = safe_read(STDIN_FILENO, readbuf, sizeof(readbuf)); ndelay_off(0); readpos = 0; readeof = eof_error; if (eof_error <= 0) goto reached_eof; } c = readbuf[readpos]; /* backspace? [needed for manpages] */ /* <tab><bs> is (a) insane and */ /* (b) harder to do correctly, so we refuse to do it */ if (c == '\x8' && last_line_pos && p[-1] != '\t') { readpos++; /* eat it */ last_line_pos--; /* was buggy (p could end up <= current_line)... */ *--p = '\0'; continue; } { size_t new_last_line_pos = last_line_pos + 1; if (c == '\t') { new_last_line_pos += 7; new_last_line_pos &= (~7); } if ((int)new_last_line_pos >= w) break; last_line_pos = new_last_line_pos; } /* ok, we will eat this char */ readpos++; if (c == '\n') { terminated = 1; last_line_pos = 0; break; } /* NUL is substituted by '\n'! */ if (c == '\0') c = '\n'; *p++ = c; *p = '\0'; } /* end of "read chars until we have a line" loop */ /* Corner case: linewrap with only "" wrapping to next line */ /* Looks ugly on screen, so we do not store this empty line */ if (!last_terminated && !current_line[0]) { last_terminated = 1; max_lineno++; continue; } reached_eof: last_terminated = terminated; flines = xrealloc_vector(flines, 8, max_fline); flines[max_fline] = (char*)xrealloc(MEMPTR(current_line), strlen(current_line) + 1 + 4) + 4; LINENO(flines[max_fline]) = max_lineno; if (terminated) max_lineno++; if (max_fline >= MAXLINES) { eof_error = 0; /* Pretend we saw EOF */ break; } if (!(option_mask32 & FLAG_S) ? (max_fline > cur_fline + max_displayed_line) : (max_fline >= cur_fline && max_lineno > LINENO(flines[cur_fline]) + max_displayed_line) ) { #if !ENABLE_FEATURE_LESS_REGEXP break; #else if (wanted_match >= num_matches) { /* goto_match called us */ fill_match_lines(old_max_fline); old_max_fline = max_fline; } if (wanted_match < num_matches) break; #endif } if (eof_error <= 0) { if (eof_error < 0) { if (errno == EAGAIN) { /* not yet eof or error, reset flag (or else * we will hog CPU - select() will return * immediately */ eof_error = 1; } else { print_statusline("read error"); } } #if !ENABLE_FEATURE_LESS_REGEXP break; #else if (wanted_match < num_matches) { break; } else { /* goto_match called us */ time_t t = time(NULL); if (t != last_time) { last_time = t; if (--seconds_p1 == 0) break; } sched_yield(); goto again0; /* go loop again (max 2 seconds) */ } #endif } max_fline++; current_line = ((char*)xmalloc(w + 4)) + 4; p = current_line; last_line_pos = 0; } /* end of "read lines until we reach cur_fline" loop */ fill_match_lines(old_max_fline); #if ENABLE_FEATURE_LESS_REGEXP /* prevent us from being stuck in search for a match */ wanted_match = -1; #endif #undef readbuf }
InterruptContext* Thread::handleSignal(InterruptContext* context) { kthread_mutex_lock(&signalMutex); assert(pendingSignals); assert(signalPending); // Choose the next unblocked pending signal. PendingSignal* pending; if (!sigismember(&signalMask, pendingSignals->siginfo.si_signo)) { pending = pendingSignals; pendingSignals = pending->next; } else { PendingSignal* currentSignal = pendingSignals; while (currentSignal->next && sigismember(&signalMask, currentSignal->next->siginfo.si_signo)) { currentSignal = currentSignal->next; } assert(currentSignal->next); pending = currentSignal->next; currentSignal->next = pending->next; } siginfo_t siginfo = pending->siginfo; delete pending; updatePendingSignals(); kthread_mutex_unlock(&signalMutex); struct sigaction action = process->sigactions[siginfo.si_signo]; assert(!(action.sa_handler == SIG_IGN || (action.sa_handler == SIG_DFL && sigismember(&defaultIgnoredSignals, siginfo.si_signo)))); if (action.sa_handler == SIG_DFL) { process->terminateBySignal(siginfo); sched_yield(); __builtin_unreachable(); } uintptr_t frameAddress = (context->STACK_POINTER - sizeof(SignalStackFrame)) & ~0xF; SignalStackFrame* frame = (SignalStackFrame*) frameAddress; frame->siginfo = siginfo; frame->ucontext.uc_link = nullptr; frame->ucontext.uc_sigmask = signalMask; frame->ucontext.uc_stack.ss_sp = nullptr; frame->ucontext.uc_stack.ss_size = 0; frame->ucontext.uc_stack.ss_flags = SS_DISABLE; Registers::save(context, &frame->ucontext.uc_mcontext.__regs); Registers::saveFpu(&frame->ucontext.uc_mcontext.__fpuEnv); #ifdef __i386__ frame->signoParam = siginfo.si_signo; frame->infoParam = &frame->siginfo; frame->contextParam = &frame->ucontext; context->eflags &= ~0x400; // Direction Flag #elif defined(__x86_64__) context->rdi = siginfo.si_signo; context->rsi = (uintptr_t) &frame->siginfo; context->rdx = (uintptr_t) &frame->ucontext; context->rflags &= ~0x400; // Direction Flag #else # error "Signal handler parameters are unimplemented for this architecture." #endif uintptr_t* sigreturnPointer = (uintptr_t*) frameAddress - 1; *sigreturnPointer = process->sigreturn; context->INSTRUCTION_POINTER = (uintptr_t) action.sa_sigaction; context->STACK_POINTER = (uintptr_t) sigreturnPointer; signalMask |= action.sa_mask | _SIGSET(siginfo.si_signo); return context; }
void SysThread::yield() { sched_yield(); }
int get_command(struct cfg_stable *cfs, int controlfd, struct rtpp_command *cmd) { char **ap; char *cp; int len, i; if (cfs->umode == 0) { for (;;) { len = read(controlfd, cmd->buf, sizeof(cmd->buf) - 1); if (len != -1 || (errno != EAGAIN && errno != EINTR)) break; sched_yield(); } } else { cmd->rlen = sizeof(cmd->raddr); len = recvfrom(controlfd, cmd->buf, sizeof(cmd->buf) - 1, 0, sstosa(&cmd->raddr), &cmd->rlen); } if (len == -1) { if (errno != EAGAIN && errno != EINTR) rtpp_log_ewrite(RTPP_LOG_ERR, cfs->glog, "can't read from control socket"); return (-1); } cmd->buf[len] = '\0'; rtpp_log_write(RTPP_LOG_DBUG, cfs->glog, "received command \"%s\"", cmd->buf); cp = cmd->buf; cmd->argc = 0; memset(cmd->argv, 0, sizeof(cmd->argv)); for (ap = cmd->argv; (*ap = rtpp_strsep(&cp, "\r\n\t ")) != NULL;) if (**ap != '\0') { cmd->argc++; if (++ap >= &cmd->argv[10]) break; } cmd->cookie = NULL; if (cmd->argc < 1 || (cfs->umode != 0 && cmd->argc < 2)) { rtpp_log_write(RTPP_LOG_ERR, cfs->glog, "command syntax error"); reply_error(cfs, controlfd, cmd, 0); return (0); } /* Stream communication mode doesn't use cookie */ if (cfs->umode != 0) { cmd->cookie = cmd->argv[0]; for (i = 1; i < cmd->argc; i++) cmd->argv[i - 1] = cmd->argv[i]; cmd->argc--; cmd->argv[cmd->argc] = NULL; } else { cmd->cookie = NULL; } return (cmd->argc); }
/***** The next function can return only when the sigthr has terminated. * This avoids the signal thread try to kill a terminated thread. */ void waitsigend(cell_t * c) { while ( c->sigok == 0 ) { sched_yield(); } }
void yieldThread(void) { sched_yield(); return; }
/****** * Last but not least, the main function */ int main(int argc, char * argv[]) { /* Main is responsible for : * the mutex attributes initializing * the creation of the cells * the destruction of everything on SIGUSR1 reception */ int ret; int i; struct sigaction sa; unsigned long long globopcnt=0, globsigcnt=0; #ifndef WITHOUT_XOPEN int sz = 2 + (sizeof(types) / sizeof(int)); #else int sz = 2; #endif pthread_mutexattr_t ma[sz-1]; pthread_mutexattr_t *pma[sz]; cell_t data[sz * N * SCALABILITY_FACTOR]; pma[sz-1] = NULL; #if VERBOSE > 0 output("Mutex lock / unlock stress sample is starting\n"); output("Kill with SIGUSR1 to stop the process\n"); output("\t kill -USR1 <pid>\n\n"); #endif /* Initialize the mutex attributes */ for (i=0; i<sz-1; i++) { pma[i] = &ma[i]; ret = pthread_mutexattr_init(pma[i]); if (ret != 0) { UNRESOLVED(ret, "Unable to init a mutex attribute object"); } #ifndef WITHOUT_XOPEN /* we have the mutex attribute types */ if (i != 0) { ret = pthread_mutexattr_settype(pma[i], types[i-1]); if (ret != 0) { UNRESOLVED(ret, "Unable to set type of a mutex attribute object"); } } #endif } #if VERBOSE > 1 output("%i mutex attribute objects were initialized\n", sz - 1); #endif /* Initialize the thread-local-data key */ ret = pthread_key_create(&_c, NULL); if (ret != 0) { UNRESOLVED(ret, "Unable to initialize TLD key"); } #if VERBOSE > 1 output("TLD key initialized\n"); #endif /* Register the signal handler for SIGUSR1 */ sigemptyset (&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = globalsig; if ((ret = sigaction (SIGUSR1, &sa, NULL))) { UNRESOLVED(ret, "Unable to register signal handler"); } /* Register the signal handler for SIGUSR2 */ sa.sa_handler = sighdl; if ((ret = sigaction (SIGUSR2, &sa, NULL))) { UNRESOLVED(ret, "Unable to register signal handler"); } /* Start every threads */ #if VERBOSE > 0 output("%i cells of 10 threads are being created...\n", sz * N * SCALABILITY_FACTOR); #endif for (i=0; i< sz * N * SCALABILITY_FACTOR; i++) cell_init(i, &data[i], pma[i % sz]); #if VERBOSE > 0 output("All threads created and running.\n"); #endif /* We stay here while not interrupted */ do { sched_yield(); } while (do_it); #if VERBOSE > 0 output("Starting to join the threads...\n"); #endif /* Everybody is stopping, we must join them, and destroy the cell data */ for (i=0; i< sz * N * SCALABILITY_FACTOR; i++) cell_fini(i, &data[i], &globopcnt, &globsigcnt); /* Destroy the mutex attributes objects */ for (i=0; i<sz-1; i++) { ret = pthread_mutexattr_destroy(pma[i]); if (ret != 0) { UNRESOLVED(ret, "Unable to destroy a mutex attribute object"); } } /* Destroy the thread-local-data key */ ret = pthread_key_delete(_c); if (ret != 0) { UNRESOLVED(ret, "Unable to destroy TLD key"); } #if VERBOSE > 1 output("TLD key destroyed\n"); #endif /* output the total counters */ #if VERBOSE > 1 output("===============================================\n"); #endif #if VERBOSE > 0 output("Total counters:\n\t%llu locks and unlocks\n\t%llu signals\n", globopcnt, globsigcnt); output("pthread_mutex_lock stress test passed.\n"); #endif PASSED; }
void *POSIX_Init( void *argument ) { struct timespec tr; int status; int priority; pthread_t thread_id; struct utsname uts; TEST_BEGIN(); /* print some system information */ puts( "Init: uname - EFAULT (invalid uts pointer argument)" ); status = uname( NULL ); rtems_test_assert( status == -1 ); rtems_test_assert( errno == EFAULT ); status = uname( &uts ); rtems_test_assert( !status ); printf( "Init: uts.sysname: %s\n", uts.sysname ); printf( "Init: uts.nodename: %s\n", uts.nodename ); printf( "Init: uts.release: %s\n", uts.release ); printf( "Init: uts.version: %s\n", uts.version ); printf( "Init: uts.machine: %s\n", uts.machine ); puts(""); /* get id of this thread */ Init_id = pthread_self(); printf( "Init: ID is 0x%08" PRIxpthread_t "\n", Init_id ); /* exercise get minimum priority */ priority = sched_get_priority_min( SCHED_FIFO ); printf( "Init: sched_get_priority_min (SCHED_FIFO) -- %d\n", priority ); rtems_test_assert( priority != -1 ); puts( "Init: sched_get_priority_min -- EINVAL (invalid policy)" ); priority = sched_get_priority_min( -1 ); rtems_test_assert( priority == -1 ); rtems_test_assert( errno == EINVAL ); /* exercise get maximum priority */ priority = sched_get_priority_max( SCHED_FIFO ); printf( "Init: sched_get_priority_max (SCHED_FIFO) -- %d\n", priority ); rtems_test_assert( priority != -1 ); puts( "Init: sched_get_priority_max -- EINVAL (invalid policy)" ); priority = sched_get_priority_max( -1 ); rtems_test_assert( priority == -1 ); rtems_test_assert( errno == EINVAL ); puts( "Init: sched_rr_get_interval -- ESRCH (invalid PID)" ); status = sched_rr_get_interval( 4, &tr ); rtems_test_assert( status == -1 ); rtems_test_assert( errno == ESRCH ); puts( "Init: sched_rr_get_interval -- EINVAL (invalid interval pointer)" ); status = sched_rr_get_interval( getpid(), NULL ); rtems_test_assert( status == -1 ); rtems_test_assert( errno == EINVAL ); /* print the round robin time quantum */ status = sched_rr_get_interval( getpid(), &tr ); printf( "Init: Round Robin quantum is %" PRIdtime_t " seconds, %ld nanoseconds\n", tr.tv_sec, tr.tv_nsec ); rtems_test_assert( !status ); /* create a thread */ puts( "Init: pthread_create - SUCCESSFUL" ); status = pthread_create( &thread_id, NULL, Task_1_through_3, NULL ); rtems_test_assert( !status ); /* too may threads error */ puts( "Init: pthread_create - EAGAIN (too many threads)" ); status = pthread_create( &thread_id, NULL, Task_1_through_3, NULL ); rtems_test_assert( status == EAGAIN ); puts( "Init: sched_yield to Task_1" ); status = sched_yield(); rtems_test_assert( !status ); /* switch to Task_1 */ /* exit this thread */ puts( "Init: pthread_exit" ); pthread_exit( NULL ); /* switch to Task_1 */ return NULL; /* just so the compiler thinks we returned something */ }
/* * Dump the stack for the specified thread, which is still running. * * This is very dangerous, because stack frames are being pushed on and * popped off, and if the thread exits we'll be looking at freed memory. * The plan here is to take a snapshot of the stack and then dump that * to try to minimize the chances of catching it mid-update. This should * work reasonably well on a single-CPU system. * * There is a small chance that calling here will crash the VM. */ void dvmDumpRunningThreadStack(const DebugOutputTarget* target, Thread* thread) { StackSaveArea* saveArea; const u1* origStack; u1* stackCopy = NULL; int origSize, fpOffset; void* fp; int depthLimit = 200; if (thread == NULL || thread->curFrame == NULL) { dvmPrintDebugMessage(target, "DumpRunning: Thread at %p has no curFrame (threadid=%d)\n", thread, (thread != NULL) ? thread->threadId : 0); return; } /* wait for a full quantum */ sched_yield(); /* copy the info we need, then the stack itself */ origSize = thread->interpStackSize; origStack = (const u1*) thread->interpStackStart - origSize; stackCopy = (u1*) malloc(origSize); fpOffset = (u1*) thread->curFrame - origStack; memcpy(stackCopy, origStack, origSize); /* * Run through the stack and rewrite the "prev" pointers. */ //LOGI("DR: fpOff=%d (from %p %p)\n",fpOffset, origStack, thread->curFrame); fp = stackCopy + fpOffset; while (true) { int prevOffset; if (depthLimit-- < 0) { /* we're probably screwed */ dvmPrintDebugMessage(target, "DumpRunning: depth limit hit\n"); dvmAbort(); } saveArea = SAVEAREA_FROM_FP(fp); if (saveArea->prevFrame == NULL) break; prevOffset = (u1*) saveArea->prevFrame - origStack; if (prevOffset < 0 || prevOffset > origSize) { dvmPrintDebugMessage(target, "DumpRunning: bad offset found: %d (from %p %p)\n", prevOffset, origStack, saveArea->prevFrame); saveArea->prevFrame = NULL; break; } saveArea->prevFrame = stackCopy + prevOffset; fp = saveArea->prevFrame; } /* * We still need to pass the Thread for some monitor wait stuff. */ dumpFrames(target, stackCopy + fpOffset, thread); free(stackCopy); }
bool __SwitchToThread(uint32_t dwSleepMSec, uint32_t dwSwitchCount) { return sched_yield() == 0; }
void Debug_Yield(void) { unsigned int rand = rand_r(&randYieldSeed) % 100; if (rand < yieldPercent) sched_yield(); }
void *sender(void* data) { char buffer[NUM_MSGS]; int count = 0; mca_status_t status; int i; mcapi_param_t parms; mcapi_info_t version; mcapi_priority_t priority = 1; mcapi_endpoint_t remote_recv_endpt; /* create a node */ mcapi_initialize(DOMAIN,NODE,NULL,&parms,&version,&status); if (status != MCAPI_SUCCESS) { fprintf(stderr,"\nERROR: Failed to initialize: %s\n",mcapi_display_status(status,status_buff,sizeof(status_buff))); WRONG; } /* make send endpoint */ send_endpt = mcapi_endpoint_create(0,&status); if (status != MCAPI_SUCCESS) { fprintf(stderr,"\nERROR: Failed to create send endpoint: %s\n",mcapi_display_status(status,status_buff,sizeof(status_buff))); WRONG; } /* get a recv endpoint */ remote_recv_endpt = mcapi_endpoint_get(DOMAIN,NODE+1,1,MCA_INFINITE,&status); if (status != MCAPI_SUCCESS) { fprintf(stderr,"\nERROR: Failed to get receive endpoint: %s\n",mcapi_display_status(status,status_buff,sizeof(status_buff))); WRONG; } /* do the sends */ for (count = 0; count < NUM_MSGS; count++) { sprintf(buffer,"Sending: %d",count); printf("Sending: [%s]\n",buffer); mcapi_msg_send(send_endpt, remote_recv_endpt, buffer, strlen(buffer), priority, &status); if ((status != MCAPI_SUCCESS) && (TIMEOUT)) { /* yield and then retry */ for (i = 0; i < TIMEOUT; i++) { if (status == MCAPI_ERR_MEM_LIMIT) { fprintf(stderr,"WARNING: Send failed: reason:%s send_count:%d. Will yield and re-try.\n",mcapi_display_status(status,status_buff,sizeof(status_buff)),count); sched_yield(); mcapi_msg_send(send_endpt, remote_recv_endpt, buffer, strlen(buffer), priority, &status); } if (status == MCAPI_SUCCESS) { break; } } } if (status != MCAPI_SUCCESS) { fprintf(stderr,"\nFAIL: Send failed: reason:%s send_count:%d\n",mcapi_display_status(status,status_buff,sizeof(status_buff)),count); WRONG; } } /* finalize */ mcapi_finalize(&status); if (status != MCAPI_SUCCESS) { fprintf(stderr,"\nFAIL: Failed to finalize: %s\n",mcapi_display_status(status,status_buff,sizeof(status_buff))); WRONG; } return NULL; }
/* main function */ int main() { int ret; pthread_t child; struct sigaction sa; /* Initialize output */ output_init(); /* Set the signal handler */ sa.sa_flags = SA_RESTART; sa.sa_handler = handler; ret = sigemptyset( &sa.sa_mask ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to empty signal set" ); } /* Install the signal handler for SIGNAL */ ret = sigaction( SIGNAL, &sa, 0 ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to set signal handler" ); } /* Initialize the semaphore */ ret = sem_init( &sem, 0, 0 ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to init a semaphore" ); } /* Create the child thread */ ret = pthread_create( &child, NULL, threaded, NULL ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to create a child thread" ); } /* Let the child thread enter the wait routine... we use sched_yield as there is no certain way to test that the child is waiting for the semaphore... */ sched_yield(); sched_yield(); sched_yield(); /* Ok, now kill the child */ ret = pthread_kill( child, SIGNAL ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to kill the child thread" ); } /* wait that the child receives the signal */ while ( !caught ) sched_yield(); /* Now let the child run and terminate */ ret = sem_post( &sem ); if ( ret != 0 ) { UNRESOLVED( errno, "Failed to post the semaphore" ); } ret = pthread_join( child, NULL ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to join the thread" ); } /* terminate */ ret = sem_destroy( &sem ); if ( ret != 0 ) { UNRESOLVED( ret, "Failed to destroy the semaphore" ); } /* Test passed */ #if VERBOSE > 0 output( "Test passed\n" ); #endif PASSED; }
void* thread_idle(void *arg) { extern uint_t __ktext_start; register uint_t id; register uint_t cpu_nr; register struct thread_s *this; register struct cpu_s *cpu; struct thread_s *thread; register struct page_s *reserved_pg; register uint_t reserved; kthread_args_t *args; bool_t isBSCPU; uint_t tm_now; uint_t count; error_t err; this = current_thread; cpu = current_cpu; id = cpu->gid; cpu_nr = arch_onln_cpu_nr(); args = (kthread_args_t*) arg; isBSCPU = (cpu == cpu->cluster->bscpu); cpu_trace_write(cpu, thread_idle_func); if(isBSCPU) pmm_tlb_flush_vaddr((vma_t)&__ktext_start, PMM_UNKNOWN); cpu_set_state(cpu, CPU_ACTIVE); rt_timer_read(&tm_now); this->info.tm_born = tm_now; this->info.tm_tmp = tm_now; //// Reset stats /// cpu_time_reset(cpu); //////////////////// mcs_barrier_wait(&boot_sync); printk(INFO, "INFO: Starting Thread Idle On Core %d\tOK\n", cpu->gid); if(isBSCPU && (id == args->val[2])) { for(reserved = args->val[0]; reserved < args->val[1]; reserved += PMM_PAGE_SIZE) { reserved_pg = ppm_ppn2page(&cpu->cluster->ppm, reserved >> PMM_PAGE_SHIFT); page_state_set(reserved_pg, PGINIT); ppm_free_pages(reserved_pg); } } thread = kthread_create(this->task, &thread_event_manager, NULL, cpu->cluster->id, cpu->lid); if(thread == NULL) PANIC("Failed to create default events handler Thread for CPU %d\n", id); thread->task = this->task; cpu->event_mgr = thread; wait_queue_init(&thread->info.wait_queue, "Events"); err = sched_register(thread); assert(err == 0); sched_add_created(thread); if(isBSCPU) { dqdt_update(); #if 0 thread = kthread_create(this->task, &cluster_manager_thread, cpu->cluster, cpu->cluster->id, cpu->lid); if(thread == NULL) { PANIC("Failed to create cluster manager thread, cid %d, cpu %d\n", cpu->cluster->id, cpu->gid); } thread->task = this->task; cpu->cluster->manager = thread; wait_queue_init(&thread->info.wait_queue, "Cluster-Mgr"); err = sched_register(thread); assert(err == 0); sched_add_created(thread); #endif if(clusters_tbl[cpu->cluster->id].flags & CLUSTER_IO) { thread = kthread_create(this->task, &kvfsd, NULL, cpu->cluster->id, cpu->lid); if(thread == NULL) { PANIC("Failed to create KVFSD on cluster %d, cpu %d\n", cpu->cluster->id, cpu->gid); } thread->task = this->task; wait_queue_init(&thread->info.wait_queue, "KVFSD"); err = sched_register(thread); assert(err == 0); sched_add_created(thread); printk(INFO,"INFO: kvfsd has been created\n"); } } cpu_set_state(cpu,CPU_IDLE); while (true) { cpu_disable_all_irq(NULL); if((event_is_pending(&cpu->re_listner)) || (event_is_pending(&cpu->le_listner))) { wakeup_one(&cpu->event_mgr->info.wait_queue, WAIT_ANY); } sched_idle(this); count = sched_runnable_count(&cpu->scheduler); cpu_enable_all_irq(NULL); if(count != 0) sched_yield(this); //arch_set_power_state(cpu, ARCH_PWR_IDLE); } return NULL; }
//method for timing a memory access (memory read) of addresses void Test2(struct args_st *arguments, size_t *timings) { size_t slot = 0; struct perf_event_attr pe; int perf_event_fd, addr; long long cpu_cycles; int i = 0; //init the perf_event_attr before calling the syscall memset(&pe, 0, sizeof(struct perf_event_attr)); pe.type = PERF_TYPE_HARDWARE; pe.size = sizeof(struct perf_event_attr); pe.config = PERF_COUNT_HW_CPU_CYCLES; //we are going to count the number of CPU cycles pe.disabled = 1; pe.exclude_kernel = 1; pe.exclude_hv = 1; perf_event_fd = perf_event_open(&pe, 0, -1, -1, 0); if(perf_event_fd == -1) { fprintf(stderr, "Error opening leader %llx\n", pe.config); exit(EXIT_FAILURE); } //Check overhead printf("[+] Computing overhead\n"); long long overhead = 0, tmp = 0; int N = 10000; for(i = 0; i < N; i++) { ioctl(perf_event_fd, PERF_EVENT_IOC_RESET, 0); ioctl(perf_event_fd, PERF_EVENT_IOC_ENABLE, 0); ioctl(perf_event_fd, PERF_EVENT_IOC_DISABLE, 0); read(perf_event_fd, &cpu_cycles, sizeof(long long)); overhead += cpu_cycles; } overhead /= N; //Start probing addresses of the shared library from base_address to end_address //in order to test the timing variations char *probe; i = 0; printf("[+] Probing memread\n"); sched_yield(); for(probe = arguments->base_address; probe < arguments->end_address; probe += arguments->stride) { clearcache(arguments->base_address, arguments->end_address); //start counting the cpu cycles ioctl(perf_event_fd, PERF_EVENT_IOC_RESET, 0); ioctl(perf_event_fd, PERF_EVENT_IOC_ENABLE, 0); //do a memory read memread(probe); //stop counting the cpu cycles ioctl(perf_event_fd, PERF_EVENT_IOC_DISABLE, 0); //read the cpu cycles counter read(perf_event_fd, &cpu_cycles, sizeof(long long)); //store it timings[i++] = cpu_cycles - overhead; } sched_yield(); }
gboolean mono_threads_core_yield (void) { return sched_yield () == 0; }
void i386_init(void) { extern char edata[], end[]; // Before doing anything else, complete the ELF loading process. // Clear the uninitialized global data (BSS) section of our program. // This ensures that all static/global variables start out zero. memset(edata, 0, end - edata); // Initialize the console. // Can't call cprintf until after we do this! cons_init(); // Lab 2 memory management initialization functions mem_init(); // Lab 3 user environment initialization functions env_init(); trap_init(); // Lab 4 multiprocessor initialization functions mp_init(); lapic_init(); // Lab 4 multitasking initialization functions pic_init(); // Lab 6 hardware initialization functions time_init(); pci_init(); // Acquire the big kernel lock before waking up APs // Your code here: lock_kernel(); // Starting non-boot CPUs boot_aps(); // Should always have idle processes at first. int i; for (i = 0; i < NCPU; i++) ENV_CREATE(user_idle, ENV_TYPE_IDLE); // Start fs. ENV_CREATE(fs_fs, ENV_TYPE_FS); #if !defined(TEST_NO_NS) // Start ns. ENV_CREATE(net_ns, ENV_TYPE_NS); #endif #if defined(TEST) // Don't touch -- used by grading script! ENV_CREATE(TEST, ENV_TYPE_USER); #else // Touch all you want. ENV_CREATE(user_icode, ENV_TYPE_USER); #endif // TEST* // Should not be necessary - drains keyboard because interrupt has given up. kbd_intr(); // Schedule and run the first user environment! sched_yield(); }
// Deschedule current environment and pick a different one to run. static void sys_yield(void) { sched_yield(); }
void assert_thread_woken(struct ThreadState *thread) { while (thread->state == STATE_ABOUT_TO_WAIT) { sched_yield(); } ASSERT_EQ(thread->state, STATE_WAIT_RETURNED); }