From be44179b005ee33d936ff55ef743bca5e84ee1b3 Mon Sep 17 00:00:00 2001 From: Bryan Ward Date: Tue, 14 May 2013 12:38:08 -0400 Subject: latest changes on pound. --- Makefile | 4 ++-- bin/rwrnlp.c | 17 +++++++++------- include/litmus/rt_param.h | 52 +++++++++++++++++++++++++++++++++++++++++------ include/spinlocks.h | 11 +++++----- multi.csv | 8 +++++--- src/spinlocks.c | 41 +++++++++++++++++++++++-------------- 6 files changed, 95 insertions(+), 38 deletions(-) diff --git a/Makefile b/Makefile index 6bf9ed9..84f83e2 100644 --- a/Makefile +++ b/Makefile @@ -207,7 +207,7 @@ obj-base_mt_task = base_mt_task.o ldf-base_mt_task = -pthread obj-rwrnlp = rwrnlp.o -ldf-rwrnlp = -pthread -lrt +ldf-rwrnlp = -lrt -pthread obj-rt_launch = rt_launch.o common.o @@ -224,7 +224,7 @@ lib-measure_syscall = -lm .SECONDEXPANSION: ${rt-apps}: $${obj-$$@} liblitmus.a - $(CC) -o $@ $(LDFLAGS) ${ldf-$@} $(filter-out liblitmus.a,$+) $(LOADLIBS) $(LDLIBS) ${liblitmus-flags} ${lib-$@} + $(CC) -o $@ $(LDFLAGS) ${ldf-$@} $(filter-out liblitmus.a,$+) $(LOADLIBS) $(LDLIBS) ${liblitmus-flags} ${lib-$@} -lrt # ############################################################################## # Dependency resolution. diff --git a/bin/rwrnlp.c b/bin/rwrnlp.c index 07e3899..a73e2ad 100644 --- a/bin/rwrnlp.c +++ b/bin/rwrnlp.c @@ -146,7 +146,7 @@ struct thread_context* parse_csv(const char *file, int *num_tasks) } else { ctx[cur_task].type = write_req; } - if (1 != fscanf(fstream, "%ld",&ctx[cur_task].resources)){ + if (1 != fscanf(fstream, "%lu",&ctx[cur_task].resources)){ fprintf(stderr, "invalid resource mask near line %d\n", cur_task); exit(EXIT_FAILURE); } @@ -286,32 +286,35 @@ static int loop_for(double exec_time, double emergency_exit) static int job(struct thread_context *ctx, double program_end) { double ncs_length; - double cs_length; + long lock_overhead, unlock_overhead; if (wctime() > program_end){ printf("Terminating...\n"); return 0; } else { ncs_length = (ctx->cost-ctx->cs_length)/2*S_PER_MS; - cs_length = ctx->cs_length * S_PER_MS; loop_for(ncs_length, program_end + 1); if(ctx->type == read_req){ //printf("%d:%d read locking...\n", __sync_fetch_and_add(&events,1), gettid()); - rwrnlp_read_lock(&rw_lock, ctx->resources, ctx->processor); + lock_overhead = rwrnlp_read_lock(&rw_lock, ctx->resources, ctx->processor); //printf("%d:%d read CS...\n", __sync_fetch_and_add(&events, 1), gettid()); loop_for(ctx->cs_length*S_PER_MS, program_end + 1); //printf("%d:%d read unlocking...\n", __sync_fetch_and_add(&events,1), gettid()); - rwrnlp_read_unlock(&rw_lock, ctx->processor); + unlock_overhead = rwrnlp_read_unlock(&rw_lock, ctx->processor); //printf("%d:%d ncs...\n", __sync_fetch_and_add(&events,1), gettid()); + printf("read lock overhead: %ld\n", lock_overhead); + printf("read unlock overhead: %ld\n", unlock_overhead); }else{ //printf("%d:%d write locking %lu\n", __sync_fetch_and_add(&events,1), gettid(), ctx->resources); - rwrnlp_write_lock(&rw_lock, ctx->resources, ctx->processor); + lock_overhead = rwrnlp_write_lock(&rw_lock, ctx->resources, ctx->processor); //printf("%d:%d write CS...\n", __sync_fetch_and_add(&events,1), gettid()); loop_for(ctx->cs_length*S_PER_MS, program_end + 1); //printf("%d:%d write unlocking...\n", __sync_fetch_and_add(&events,1), gettid()); - rwrnlp_write_unlock(&rw_lock, ctx->processor); + unlock_overhead = rwrnlp_write_unlock(&rw_lock, ctx->processor); //printf("%d:%d ncs...\n", __sync_fetch_and_add(&events,1), gettid()); + printf("write lock overhead: %ld\n", lock_overhead); + printf("write unlock overhead: %ld\n", unlock_overhead); } diff --git a/include/litmus/rt_param.h b/include/litmus/rt_param.h index 2026819..de29bac 100644 --- a/include/litmus/rt_param.h +++ b/include/litmus/rt_param.h @@ -33,6 +33,24 @@ typedef enum { PRECISE_ENFORCEMENT /* budgets are enforced with hrtimers */ } budget_policy_t; +/* Release behaviors for jobs. PERIODIC and EARLY jobs + must end by calling sys_complete_job() (or equivalent) + to set up their next release and deadline. */ +typedef enum { + /* Jobs are released sporadically (provided job precedence + constraints are met). */ + SPORADIC, + + /* Jobs are released periodically (provided job precedence + constraints are met). */ + PERIODIC, + + /* Jobs are released immediately after meeting precedence + constraints. Beware this can peg your CPUs if used in + the wrong applications. Only supported by EDF schedulers. */ + EARLY +} release_policy_t; + /* We use the common priority interpretation "lower index == higher priority", * which is commonly used in fixed-priority schedulability analysis papers. * So, a numerically lower priority value implies higher scheduling priority, @@ -61,7 +79,8 @@ struct rt_task { unsigned int cpu; unsigned int priority; task_class_t cls; - budget_policy_t budget_policy; /* ignored by pfair */ + budget_policy_t budget_policy; /* ignored by pfair */ + release_policy_t release_policy; }; union np_flag { @@ -89,11 +108,29 @@ union np_flag { * determining preemption/migration overheads). */ struct control_page { + /* This flag is used by userspace to communicate non-preempive + * sections. */ volatile union np_flag sched; + volatile uint64_t irq_count; /* Incremented by the kernel each time an IRQ is + * handled. */ + + /* Locking overhead tracing: userspace records here the time stamp + * and IRQ counter prior to starting the system call. */ + uint64_t ts_syscall_start; /* Feather-Trace cycles */ + uint64_t irq_syscall_start; /* Snapshot of irq_count when the syscall + * started. */ + /* to be extended */ }; +/* Expected offsets within the control page. */ + +#define LITMUS_CP_OFFSET_SCHED 0 +#define LITMUS_CP_OFFSET_IRQ_COUNT 8 +#define LITMUS_CP_OFFSET_TS_SC_START 16 +#define LITMUS_CP_OFFSET_IRQ_SC_START 24 + /* don't export internal data structures to user space (liblitmus) */ #ifdef __KERNEL__ @@ -142,11 +179,19 @@ struct rt_param { /* is the task present? (true if it can be scheduled) */ unsigned int present:1; + /* has the task completed? */ + unsigned int completed:1; + #ifdef CONFIG_LITMUS_LOCKING /* Is the task being priority-boosted by a locking protocol? */ unsigned int priority_boosted:1; /* If so, when did this start? */ lt_t boost_start_time; + + /* How many LITMUS^RT locks does the task currently hold/wait for? */ + unsigned int num_locks_held; + /* How many PCP/SRP locks does the task currently hold/wait for? */ + unsigned int num_local_locks_held; #endif /* user controlled parameters */ @@ -233,11 +278,6 @@ struct rt_param { lt_t tot_exec_time; }; -/* Possible RT flags */ -#define RT_F_RUNNING 0x00000000 -#define RT_F_SLEEP 0x00000001 -#define RT_F_EXIT_SEM 0x00000008 - #endif #endif diff --git a/include/spinlocks.h b/include/spinlocks.h index d83a0d8..2ae3d27 100644 --- a/include/spinlocks.h +++ b/include/spinlocks.h @@ -28,7 +28,8 @@ typedef struct rwrnlp_struct { int enter[NR_CPUS]; int leave[NR_CPUS]; - request requests[NR_CPUS]; + request requests[NR_CPUS][2]; + int curr[NR_CPUS]; request* wqueue[NR_RESOURCES][NR_CPUS]; unsigned int whead[NR_RESOURCES]; @@ -47,12 +48,12 @@ void spin_unlock(spinlock_t *lock); void rwrnlp_init(rwrnlp *lock); -void rwrnlp_read_lock(rwrnlp *lock, resource_mask_t resources, int processor); +long rwrnlp_read_lock(rwrnlp *lock, resource_mask_t resources, int processor); -void rwrnlp_write_lock(rwrnlp *lock, resource_mask_t resources, int processor); +long rwrnlp_write_lock(rwrnlp *lock, resource_mask_t resources, int processor); -void rwrnlp_read_unlock(rwrnlp *lock, int processor); +long rwrnlp_read_unlock(rwrnlp *lock, int processor); -void rwrnlp_write_unlock(rwrnlp *lock, int processor); +long rwrnlp_write_unlock(rwrnlp *lock, int processor); #endif //SPINLOCKS_H diff --git a/multi.csv b/multi.csv index acf5a3c..937b869 100644 --- a/multi.csv +++ b/multi.csv @@ -1,6 +1,8 @@ 0 10.0 17.0 3.0 0 1 +0 05.0 17.0 3.0 0 5 1 12.0 19.0 8.0 0 3 -3 17.0 23.0 8.0 1 4 -2 10.0 17.0 3.0 0 5 1 12.0 29.0 8.0 1 1 -3 17.0 21.0 8.0 1 4 +2 10.0 17.0 3.0 0 5 +2 05.0 19.0 3.0 0 3 +3 17.0 23.0 8.0 1 4 +3 17.0 21.0 8.0 1 5 diff --git a/src/spinlocks.c b/src/spinlocks.c index 9b04702..520e12a 100644 --- a/src/spinlocks.c +++ b/src/spinlocks.c @@ -60,12 +60,13 @@ void rwrnlp_init(rwrnlp *lock) for(i = 0; i < NR_CPUS; i++){ lock->enter[i] = 0; lock->leave[i] = 0; + lock->curr[i] = 0; } spin_init(lock->enqueue); spin_init(lock->state); } -void rwrnlp_read_lock(rwrnlp *lock, resource_mask_t resources, int processor) +long rwrnlp_read_lock(rwrnlp *lock, resource_mask_t resources, int processor) { request *req; #if MEASURE==TRUE @@ -76,7 +77,7 @@ void rwrnlp_read_lock(rwrnlp *lock, resource_mask_t resources, int processor) enter_np(); - req = &lock->requests[processor]; + req = &lock->requests[processor][lock->curr[processor]]; req->resources = resources; req->type = read_req; req->status = waiting; @@ -116,13 +117,15 @@ void rwrnlp_read_lock(rwrnlp *lock, resource_mask_t resources, int processor) clock_gettime(CLOCK_MONOTONIC, &now); overhead += diff_ns(&last, &now); } - printf("read lock overhead: %ld\n", overhead); + return overhead; +#else + return 0; #endif // printf("%d:%d reader satisfied\n", __sync_fetch_and_add(&events,1), gettid()); } -void rwrnlp_write_lock(rwrnlp *lock, resource_mask_t resources, int processor) +long rwrnlp_write_lock(rwrnlp *lock, resource_mask_t resources, int processor) { int r,i,start,end; request *req, *contender; @@ -137,7 +140,7 @@ void rwrnlp_write_lock(rwrnlp *lock, resource_mask_t resources, int processor) // printf("%d:%d rwrnlp_write_lock\n", __sync_fetch_and_add(&events,1), gettid()); - req = &lock->requests[processor]; + req = &lock->requests[processor][lock->curr[processor]]; req->resources = resources; req->type = write_req; @@ -179,9 +182,9 @@ void rwrnlp_write_lock(rwrnlp *lock, resource_mask_t resources, int processor) for(i = 0; i < NR_CPUS; i++){ if(i != processor){ - start = lock->enter[i]; - contender = &lock->requests[i]; end = lock->leave[i]; + contender = &lock->requests[i][lock->curr[processor]]; + start = lock->enter[i]; if(start <= end || contender->type == write_req || contender->status == waiting || @@ -210,27 +213,32 @@ void rwrnlp_write_lock(rwrnlp *lock, resource_mask_t resources, int processor) #if MEASURE==TRUE clock_gettime(CLOCK_MONOTONIC, &now); overhead += diff_ns(&last, &now); - printf("write lock overhead: %ld\n", overhead); + return overhead; +#else + return 0; #endif } -void rwrnlp_read_unlock(rwrnlp *lock, int processor) +long rwrnlp_read_unlock(rwrnlp *lock, int processor) { #if MEASURE==TRUE struct timespec now, last; clock_gettime(CLOCK_MONOTONIC, &last); #endif lock->leave[processor] += 1; + lock->curr[processor] = (lock->curr[processor] + 1) % 2; // printf("%d:%d rwrnlp_read_unlock\n", __sync_fetch_and_add(&events,1), gettid()); exit_np(); #if MEASURE==TRUE clock_gettime(CLOCK_MONOTONIC, &now); - printf("read unlock overhead: %ld\n", diff_ns(&last, &now)); + return diff_ns(&last, &now); +#else + return 0; #endif } -void rwrnlp_write_unlock(rwrnlp *lock, int processor) +long rwrnlp_write_unlock(rwrnlp *lock, int processor) { int r; request *req; @@ -239,13 +247,11 @@ void rwrnlp_write_unlock(rwrnlp *lock, int processor) struct timespec now, last; clock_gettime(CLOCK_MONOTONIC, &last); #endif - req= &lock->requests[processor]; + req= &lock->requests[processor][lock->curr[processor]]; tmp = req->resources; // printf("%d:%d rwrnlp_write_unlock\n", __sync_fetch_and_add(&events,1), gettid()); - lock->leave[processor] += 1; - spin_lock(lock->state); r = ffsl(tmp); while(r != 0){ @@ -257,12 +263,17 @@ void rwrnlp_write_unlock(rwrnlp *lock, int processor) lock->wlocked &= ~(req->resources); lock->unavailable &= ~(req->resources); spin_unlock(lock->state); + + lock->leave[processor] += 1; + lock->curr[processor] = (lock->curr[processor] + 1) % 2; // printf("%d:%d write unlocked %lu\n", __sync_fetch_and_add(&events,1), gettid(), req->resources); // printf("unavailable %lu\nwentitled %lu\nwlocked %lu\n", lock->unavailable, lock->wentitled, lock->wlocked); exit_np(); #if MEASURE==TRUE clock_gettime(CLOCK_MONOTONIC, &now); - printf("write unlock overhead: %ld\n", diff_ns(&last, &now)); + return diff_ns(&last, &now); +#else + return 0; #endif } -- cgit v1.2.2