int thread_init (void) { char our_thread[4]="Tao"; printk(KERN_INFO "in init\n"); unsigned long t1; unsigned long t2; int i; int max; max = 20000; for (i = 0; i < max; i++) { t1 = get_tsc(); thread1 = kthread_create(thread_fn,NULL,our_thread); t2 = get_tsc(); //printk(KERN_INFO, "TAO:kthread_create_time=%ld\n", t2 - t1); printk("TAO:%d:kthread_create_time=%ld\n", i,(t2 - t1)); } if((thread1)) { printk(KERN_INFO "helloworld\n"); wake_up_process(thread1); } return 0; }
int main() { int i; unsigned long t1, t2; i = 0; pid_t pid; pid = fork(); if (pid) { t1 = get_tsc(); //sched_yield(); //give up in parent. Child has its time pieces waitpid(pid); printf("%ld",t1); sleep(0.01); return 0; } else { t2 = get_tsc(); printf("%ld\n",t2); return 0; } }
int main(int arvc, char* argv[]) { int num1,num2; sscanf (argv[1],"%d",&num1); sscanf (argv[2],"%d",&num2); unsigned long t1; unsigned long t2; unsigned long long sum; sum = 1; double diff; //str is in byte, while size is in kb //int stride = num1/4;//stride = 4mb int stride = num1; int n; for (n = 0;n<TIMES;n++) { //int size = (pow(2,num2)/4)*pow(2,10);//8kb int size = (pow(2,num2))*pow(2,10);//8kb int i; //int a[array_size]; long* a = malloc(size); long* b = a; //printf("%d\n",sizeof(long*)); //printf("%d\n",sizeof(long)); for(i = 0;i< (size / 8);i++) { //a[i] = (i+stride)%size * 4 + &a[i]; //a[i] = (int)(&(a[i]) + (stride % size)); //a[i] = (long)(a); //a[i] = (long)(&a[i] + stride % size); a[i] = (long)(&a[(i + stride / 8) % (size / 8)]); // a[i] = 2; } int index =0; int j = 0; t1 = get_tsc(); for(j = 0;j<REPETITION;j++) { b = *b; } t2 = get_tsc(); if (sum == 1) { sum = 0; }else{ sum += diff_tsc(t1, t2); //printf("%f\n", 1.0 * diff_tsc(t1, t2) / REPETITION); } free(a); } diff = 1.0 * sum / TIMES / REPETITION; printf("%f\n",diff); }
/* vizualizes the traversal cost of a pixel */ Vec3fa renderPixelCycles(float x, float y, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p) { /* initialize ray */ RTCRay ray; ray.org = p; ray.dir = normalize(x*vx + y*vy + vz); ray.tnear = 0.0f; ray.tfar = inf; ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.mask = -1; ray.time = g_debug; /* intersect ray with scene */ int64_t c0 = get_tsc(); rtcIntersect(g_scene,ray); int64_t c1 = get_tsc(); /* shade pixel */ return Vec3fa((float)(c1-c0)*scale,0.0f,0.0f); }
int main(int argc, char** argv) { int i; /* iterator for the loop */ int rv; /* return value */ struct sched_param sp = { PRIORITY }; /* sched priority */ uint64_t main_start; /* when did the program start to run */ uint64_t loop_start; uint64_t loop_end; uint64_t loop_elapsed; uint64_t foo; printf ("sched_setscheduler(): %d\n", sched_setscheduler (0, SCHED_FIFO, &sp)); rv = mlockall (MCL_CURRENT | MCL_FUTURE); fprintf (stderr, "mlockall(): %d\n", rv); main_start = get_tsc(); printf ("get_tsc(): %ld\n", main_start); while (1) { loop_start = get_tsc(); foo = loop_start; for (i=0; i<1000; i++) { foo += (loop_start + i) ^ argc; } loop_end = get_tsc(); loop_elapsed = loop_end - loop_start; /* this takes about 7700 cycles on a 2.66Ghz Xeon X5550 */ if ( loop_elapsed > MAX_PAUSE ) { printf ("At %ld pause %ld is longer than %d\n", get_tsc(), loop_elapsed, MAX_PAUSE); } } }
void log_admin_event(struct logging_thread *log, int id, int tag, size_t size, void *extradata) { struct ds_event_record evt; evt.data_len = size; evt.time_stamp = get_tsc(); evt.id = id; evt.event_tag = tag; km_mutex_lock(&log->write_lock); __logging_thread_write(log, &evt, sizeof(evt)); __logging_thread_write(log, extradata, size); km_mutex_unlock(&log->write_lock); }
int thread_fn(void* input) { unsigned long t2; unsigned long j0,j1; int delay = 60*HZ; j0 = jiffies; j1 = j0 + delay; int number = (int) input; printk(KERN_INFO "we are scheduled\n"); while (time_before(jiffies, j1)) { t2 = get_tsc(); printk("TAOI:%d:ktime=%ld\n",number, t2); schedule(); // force to schedule } return 0; }
void end_clock() { #ifdef ENABLE_TIME end_tsc = get_tsc(); printf("tsc %lf\n", (end_tsc - begin_tsc)/FREQ); #endif }
void begin_clock() { #ifdef ENABLE_TIME begin_tsc = get_tsc(); #endif }
static int set_tsc_freq_from_clock(void) { #define NS_PER_SEC 1E9 struct timespec sleeptime = {.tv_nsec = 5E8 }; /* 1/2 second */ struct timespec t_start, t_end; if (clock_gettime(CLOCK_MONOTONIC_RAW, &t_start) == 0) { uint64_t ns, end, start = get_tsc(); nanosleep(&sleeptime,NULL); clock_gettime(CLOCK_MONOTONIC_RAW, &t_end); end = get_tsc(); ns = ((t_end.tv_sec - t_start.tv_sec) * NS_PER_SEC); ns += (t_end.tv_nsec - t_start.tv_nsec); double secs = (double)ns/NS_PER_SEC; eal_tsc_resolution_hz = (uint64_t)((end - start)/secs); return 0; } return -1; } int main(int argc , char *argv[]) { int sock; struct sockaddr_in server; unsigned char buffer[1400] , server_reply[2000]; unsigned long long total_rcvd = 0, rcvd; memset(buffer, 'A', 1400); printf("Clock measure:%d\n\n",set_tsc_freq_from_clock()); //Create socket sock = socket(AF_INET , SOCK_STREAM , 0); if (sock == -1) { printf("Could not create socket"); } puts("Socket created"); server.sin_addr.s_addr = inet_addr("10.132.251.197"); server.sin_family = AF_INET; server.sin_port = htons( 80 ); //Connect to remote server if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0) { perror("connect failed. Error"); return 1; } puts("Connected\n"); uint64_t end = get_tsc() + eal_tsc_resolution_hz; //keep communicating with server while(1) { //Send some data if( send(sock , buffer , 1400 , 0) < 0) { puts("Send failed"); return 1; } //Receive a reply from the server if( (rcvd = recv(sock , server_reply , 2000 , 0)) < 0) { puts("recv failed"); break; } else { total_rcvd += rcvd; } if(get_tsc() >= end) { printf("%llu \n", total_rcvd); total_rcvd = 0; end = get_tsc() + eal_tsc_resolution_hz; } //puts("Server reply :"); //puts(server_reply); } close(sock); return 0; }
static int set_tsc_freq_from_clock(void) { #define NS_PER_SEC 1E9 struct timespec sleeptime = {.tv_nsec = 5E8 }; /* 1/2 second */ struct timespec t_start, t_end; if (clock_gettime(CLOCK_MONOTONIC_RAW, &t_start) == 0) { uint64_t ns, end, start = get_tsc(); nanosleep(&sleeptime,NULL); clock_gettime(CLOCK_MONOTONIC_RAW, &t_end); end = get_tsc(); ns = ((t_end.tv_sec - t_start.tv_sec) * NS_PER_SEC); ns += (t_end.tv_nsec - t_start.tv_nsec); double secs = (double)ns/NS_PER_SEC; eal_tsc_resolution_hz = (uint64_t)((end - start)/secs); return 0; } return -1; } int main(int argc , char *argv[]) { int socket_desc , client_sock , c , read_size; unsigned long long total_rcvd = 0; struct sockaddr_in server , client; char client_message[2000]; printf("Clock measure:%d\n\n",set_tsc_freq_from_clock()); //Create socket socket_desc = socket(AF_INET , SOCK_STREAM , 0); if (socket_desc == -1) { printf("Could not create socket"); } puts("Socket created"); //Prepare the sockaddr_in structure server.sin_family = AF_INET; server.sin_addr.s_addr = inet_addr("192.168.56.101"); server.sin_port = htons( 80 ); //Bind if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0) { //print the error message perror("bind failed. Error"); return 1; } puts("bind done"); //Listen listen(socket_desc , 3); //Accept and incoming connection puts("Waiting for incoming connections..."); c = sizeof(struct sockaddr_in); //accept connection from an incoming client client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c); if (client_sock < 0) { perror("accept failed"); return 1; } puts("Connection accepted"); uint64_t end = get_tsc() + eal_tsc_resolution_hz; //Receive a message from client while( 1 ) { read_size = recv(client_sock , client_message , 2000 , MSG_DONTWAIT ); if (read_size > 0) { total_rcvd += read_size; } if(get_tsc() >= end) { printf("%llu \n", total_rcvd); total_rcvd = 0; end = get_tsc() + eal_tsc_resolution_hz; } } if(read_size == 0) { puts("Client disconnected"); fflush(stdout); } else if(read_size == -1) { perror("recv failed"); } return 0; }
/* * Internal thread donation call. * * The current thread lock must be locked. */ int pthread_sched_thread_donate(pthread_thread_t *pchild, sched_wakecond_t wakeup_cond, oskit_s32_t timeout) { pthread_thread_t *pnext, *pthread = CURPTHREAD(); int enabled, preemptable; #ifdef MEASURE unsigned long before, after; #endif save_preemption_enable(preemptable); enabled = save_disable_interrupts(); #ifdef MEASURE before = get_tsc(); #endif CPUDEBUG(CORE3, "PSD0: 0x%x(%d) 0x%x(%d) %s\n", (int) pthread, pthread->tid, (int) pchild, pchild->tid, STATESTR(pchild)); /* * If the thread is not ready to accept this new donation, just * return status that the donation was not accepted. */ if (pchild->schedflags != SCHED_READY) { CPUDEBUG(CORE3, "PSD1: 0x%x(%d) 0x%x(%d) %s\n", (int) pthread, pthread->tid, (int) pchild, pchild->tid, STATESTR(pchild)); restore_interrupt_enable(enabled); return 0; } /* * Is another thread already donating to this thread? */ if (pchild->inherits_from) { CPUDEBUG(CORE3, "PSD2: 0x%x(%d) 0x%x(%d) 0x%x(%d)\n", (int) pthread, pthread->tid, (int) pchild, pchild->tid, (int) pchild->inherits_from, pchild->inherits_from->tid); } /* * We are commited to the donation. */ /* * The target thread is going to inherit from the current thread. */ pchild->inherits_from = pthread; pchild->nextup = NULL_THREADPTR; /* * BUT, if the thread being switched into is part of an old active * chain, need to decend the chain setting each thread to DONATED. * Set the back pointer too since it might no longer be valid if * another thread donated to the chain at some point. * * STOP when we hit a thread with WAKEUP_ALWAYS set, or at the end. * This is the thread that actually gets run. Lock that thread. */ pnext = pchild; if (pnext->donating_to) { while (pnext->donating_to) { pthread_thread_t *ptmp; if (pnext->schedflags != SCHED_READY) panic("pthread_sched_donate SCHED_READY"); if (pnext->wakeup_cond == WAKEUP_ALWAYS) break; pnext->schedflags = SCHED_DONATING; /* * Goto next in the chain. Lock the next one, * unlock the current one, set the back pointer. */ ptmp = pnext->donating_to; ptmp->inherits_from = pnext; ptmp->nextup = NULL_THREADPTR; CPUDEBUG(CORE3, "PSD3: " "Followed chain from 0x%x(%d) to 0x%x(%d)\n", (int) pnext, pnext->tid, (int) pnext->donating_to, pnext->donating_to->tid); pnext = ptmp; } } /* * Set up the links. */ pthread->schedflags = SCHED_DONATING; pthread->donating_to = pchild; pthread->wakeup_cond = wakeup_cond; pthread->timeout = timeout; pnext->schedflags = SCHED_RUNNING; #ifdef MEASURE after = get_tsc(); if (after > before) { stats.donations++; stats.donate_cycles += (after - before); } #endif /* Don't worry about the lock */ thread_switch(pnext, &pthread->schedlock, CURPTHREAD()); /* Must set the current thread pointer! */ SETCURPTHREAD(pthread); /* * Back from donation. * * Undo the donating link. Leave the back link alone since another * thread could have donated to the child if the chain was preempted. */ pthread->timeout = 0; pthread->donating_to = NULL_THREADPTR; pthread->schedflags = SCHED_RUNNING; if (pchild->inherits_from == pthread) pchild->inherits_from = NULL_THREADPTR; restore_interrupt_enable(enabled); /* Need to really *restore* the flag since we are in a new context */ PREEMPT_ENABLE = preemptable; return 1; }
/* * Wakeup call. */ void pthread_sched_wakeup(pthread_thread_t *pthread, int level) { int enabled; pthread_thread_t *pscheduler = pthread->scheduler; pthread_thread_t *inheritor, *ptmp; #ifdef MEASURE unsigned long before, after; #endif enabled = save_disable_interrupts(); #ifdef MEASURE before = get_tsc(); #endif CPUDEBUG(CORE0, "pthread_sched_wakeup: " "C:0x%x(%d)/%s T:0x%x(%d)/%s S:0x%x(%d)/%s\n", (int) CURPTHREAD(), CURPTHREAD()->tid, STATESTR(CURPTHREAD()), (int) pthread, pthread->tid, STATESTR(pthread), (int) pscheduler, (pscheduler ? pscheduler->tid : 0), (pscheduler ? STATESTR(pscheduler) : "")); /* * Thread is currently ready to run. The wrinkle is if the thread * was part of a donation chain that yielded, or a donation chain * that was interrupted by a wakeup. There will be a donating_to * link, which must be severed so that when the chain is run again, * the thread in question will run, rather then following the * chain. */ if (pthread->schedflags == SCHED_READY) { if (pthread->donating_to) { CPUDEBUG(CORE0, "PSW0: 0x%x(%d) 0x%x 0x%x\n", (int) pthread, pthread->tid, (int) pthread->donating_to, (int) pthread->scheduler); pthread->donate_rc = SCHEDULE_PREEMPTED; pthread->donating_to = NULL_THREADPTR; pthread->wakeup_cond = WAKEUP_ALWAYS; } goto done; } /* * Thread is donating, which means its on the active chain. */ if (pthread->schedflags == SCHED_DONATING) { pthread->schedflags = SCHED_READY; /* * Follow the chain down, setting each one along the way * to the ready state instead of donating. */ inheritor = pthread->donating_to; while (inheritor->donating_to) { inheritor->schedflags = SCHED_READY; ptmp = inheritor; inheritor = inheritor->donating_to; } /* * Go to the end of the chain. Severe the chain at the * thread being woken up. Point the last thread in the * chain (usually the thread actually running) back at the * this thread. This means that when the running thread * switches out, it will follow its link back to this * thread. When it runs, it will return from its donation, * so set the return code so that it reruns whatever thread * it was donating to. */ pthread->donating_to = NULL_THREADPTR; pthread->donate_rc = SCHEDULE_PREEMPTED; pthread->wakeup_cond = WAKEUP_ALWAYS; inheritor->nextup = pthread; /* * The wrinkle is if the last thread in the chain is not * the currently running thread. That means the chain * below this point was already woken up (it was severed). * Need to entend the backwards chain so that when the * currently running thread switches out, it follows the * links back to this thread (along multiple hops). The * intent is to run the highest level scheduler that wants * to run. */ if (inheritor != CURPTHREAD()) inheritor->wakeup_cond = WAKEUP_NEVER; PREEMPT_NEEDED = CURPTHREAD()->preempt = 1; CPUDEBUG(CORE3, "PSW1: 0x%x(%d)\n", (int) inheritor, inheritor->tid); goto done; } /* * The thread is not on the active chain, and its not in the READY * state (already woken up). Need to follow the chain back until we * get to a thread *is* DONATING. */ CPUDEBUG(CORE1, "PSW2:\n"); /* * Want to wake up either the thread donating to it, or its scheduler. * Of course, they might be the same. */ if (pthread->inherits_from && pthread->inherits_from != pscheduler) { /* * A non-scheduler thread was donating to another thread, * and the inheritor blocked. Now the inheritor is being * woken up. Need to wakeup the donator in the hopes that * it can provide some more CPU. */ /* cpuprintf("PSW3: 0x%x 0x%x 0x%x\n", (int) pthread, (int) pscheduler, (int) pthread->inherits_from); */ pthread->schedflags = SCHED_READY; inheritor = pthread->inherits_from; pthread_sched_wakeup(inheritor, level + 1); } else if (pscheduler) { pthread->schedflags = SCHED_READY; /* * If the thread waking up is different than the thread * the scheduler is currently donating to, this implies * two (or more) threads, and thus a conflict. Set the * wakeup_cond back to WAKEUP_ALWAYS so that the scheduler * will be woken up. */ if (pscheduler->donating_to && pscheduler->donating_to != pthread) { pscheduler->wakeup_cond = WAKEUP_ALWAYS; CPUDEBUG(CORE1, "PSW4: 0x%x\n", (int) pscheduler->donating_to); } /* * If the scheduler is WAKEUP_ON_SWITCH, then the * above case was not true, and the scheduler still has * only one thread to run. The scheduler *is* woken up, * but since it will donate to that thread anyway, do * not send it a message. */ if (pscheduler->wakeup_cond == WAKEUP_ALWAYS || pscheduler->wakeup_cond == WAKEUP_ON_BLOCK) { schedmsg_t msg; CPUDEBUG(CORE2, "PSW5: 0x%x(%d) 0x%x(%d)\n", (int) pscheduler, pscheduler->tid, (int) pthread, pthread->tid); msg.type = MSG_SCHED_UNBLOCK; msg.tid = pthread->tid; msg.opaque = 0; pthread_sched_special_send(pscheduler, &msg); } else { pthread_sched_wakeup(pscheduler, level + 1); } } else { /* * Hit the root scheduler, which was not running. * That means the current thread (the idle thread) * should switch back into the root scheduler. * Set the back link on the idle thread to force this * to happen. */ assert(pthread == pthread_root_scheduler); if (pthread->schedflags != SCHED_RUNNING) { pthread->schedflags = SCHED_READY; CURPTHREAD()->nextup = pthread; CURPTHREAD()->inherits_from = pthread; } } done: #ifdef MEASURE after = get_tsc(); if (level) { stats.wakeup_calls++; } else if (after > before) { stats.wakeups++; stats.wakeup_cycles += (after - before); } #endif restore_interrupt_enable(enabled); }
/* * Switch out of an application thread, back into its scheduler. Return * value to indicate whether a switch actually happened. */ int pthread_sched_dispatch(resched_flags_t reason) { pthread_thread_t *pthread = CURPTHREAD(); pthread_thread_t *inheritor, *donator, *nextup; int enabled, preemptable; #ifdef MEASURE unsigned long before, after; #endif save_preemption_enable(preemptable); enabled = save_disable_interrupts(); #ifdef MEASURE before = get_tsc(); #endif /* * See what donator should receive the message and get restarted. * Go back up the inheritance chain. Stop at the root scheduler * (which will have set WAKEUP_ALWAYS) or when some intermediate * thread says it wants to be woken up. */ donator = pthread->inherits_from; nextup = pthread->nextup; inheritor = pthread; assert(inheritor != donator); /* * Better be a donator unless its the root scheduler or idlethread. */ assert(donator || ((pthread == pthread_root_scheduler) || (pthread == IDLETHREAD))); /* * The current thread state is set accordingly. */ if (reason == RESCHED_BLOCK) pthread->schedflags = SCHED_WAITING; else pthread->schedflags = SCHED_READY; /* * Go back through the inheritance links, stopping at the first * thread to indicate that it wants to be woken up. That thread * is left locked across the thread switch. It is responsible for * unlocking itself when it gets to the other side. */ while (donator) { switch (reason) { case RESCHED_USERYIELD: donator->donate_rc = SCHEDULE_YIELDED; break; case RESCHED_BLOCK: donator->donate_rc = SCHEDULE_BLOCKED; break; case RESCHED_PREEMPT: /* time based preemption */ donator->donate_rc = SCHEDULE_TIMEDOUT; break; default: donator->donate_rc = SCHEDULE_PREEMPTED; break; } /* * With each step back through the active chain, set * the thread state accordingly. Blocks are different * then yields in that another thread should be able * to donate to a thread that yielded. However, blocked * chains should cause a wakeup for any thread along * the chain. */ if (reason == RESCHED_BLOCK) donator->schedflags = SCHED_WAITING; else donator->schedflags = SCHED_READY; if (nextup) { if (nextup == donator && (nextup = donator->nextup) == NULL_THREADPTR) break; } else { if (donator->wakeup_cond == WAKEUP_ALWAYS || donator->wakeup_cond == WAKEUP_ON_BLOCK) break; } inheritor = donator; donator = donator->inherits_from; } if (donator == NULL_THREADPTR) { /* * Nothing to run, not even the root scheduler has anything * to do. Control reaches here when the root scheduler * calls pthread_sched_wait(), or when the idle thread * attempts a reschedule in hopes of finding something to * do. */ if ((donator = IDLETHREAD) == pthread) { restore_interrupt_enable(enabled); return 0; } /* * Rather kludgy method to keep the idle loop an orphan. * The root scheduler does not know about the idle loop, * so don't want to terminate its message wait when the * idle loop does its yield to look for a new thread. */ donator->inherits_from = NULL_THREADPTR; donator->nextup = NULL_THREADPTR; goto dispatch; } #if 0 /* * Encode a return status for the donator so that it knows what * to do with the thread after it switches out. * * special flag indicates that the donation chain was modified * by a wakeup along the chain. The return code of the thread * being switched into was already set in the wakeup code, and * giving that thread a return code based on what the current * thread is doing makes no sense. * * The only reason to distingiush between all these reschedule * reasons is so that we can implement a POSIX style scheduler. */ switch (reason) { case RESCHED_USERYIELD: donator->donate_rc = SCHEDULE_YIELDED; break; case RESCHED_BLOCK: donator->donate_rc = SCHEDULE_BLOCKED; break; case RESCHED_PREEMPT: /* time based preemption */ donator->donate_rc = SCHEDULE_TIMEDOUT; break; default: donator->donate_rc = SCHEDULE_PREEMPTED; break; } #endif dispatch: /* * Clear directed yield flag. */ PREEMPT_NEEDED = pthread->preempt = 0; assert(donator); #ifdef MEASURE after = get_tsc(); if (after > before) { stats.switches++; stats.switch_cycles += (after - before); } #endif /* Don't worry about the lock */ thread_switch(donator, &pthread->schedlock, CURPTHREAD()); /* Must set the current thread pointer! */ SETCURPTHREAD(pthread); assert(pthread->inherits_from || ((pthread == pthread_root_scheduler) || (pthread == IDLETHREAD))); /* * Thread has switched back in. * * Time to look for exceptions before letting it return to * whatever it was doing before it yielded. */ pthread->schedflags = SCHED_RUNNING; if (pthread->sleeprec) { /* * Thread is returning to an osenv_sleep. The thread must * be allowed to return, even if it was killed, so the driver * state can be cleaned up. The death will be noticed later. */ goto done; } else if ((pthread->flags & (THREAD_KILLED|THREAD_EXITING)) == THREAD_KILLED) { /* * Thread was canceled. Time to actually reap it, but only * if its not already in the process of exiting. * * XXX: The problem is if the process lock is still * held. Since the rest of the oskit is not set up to * handle cancelation of I/O operations, let threads * continue to run until the process lock is released. * At that point the death will be noticed. */ if (! osenv_process_locked()) { pthread_exit_locked((void *) PTHREAD_CANCELED); /* * Never returns */ } else goto done; } /* * Look for signals. Deliver them in the context of the thread. */ SIGCHECK(pthread); done: restore_interrupt_enable(enabled); /* Need to really *restore* the flag since we are in a new context */ PREEMPT_ENABLE = preemptable; return 1; }