aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2013-02-08 13:29:38 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2013-02-08 13:29:38 -0500
commite55f02611ab64ec1163f3035257f0e2120f0f3ed (patch)
treedadb06fc6626300fdf39ac1807ffae09f5bc9f54
parent6678944975e0eccc51039121fadaa7d29858bec2 (diff)
Optimize DGLs of size = 1.
-rw-r--r--litmus/locking.c97
1 files changed, 56 insertions, 41 deletions
diff --git a/litmus/locking.c b/litmus/locking.c
index f7d33156cf49..4fe572c28aea 100644
--- a/litmus/locking.c
+++ b/litmus/locking.c
@@ -250,7 +250,7 @@ void select_next_lock(dgl_wait_state_t* dgl_wait /*, struct litmus_lock* prev_lo
250 /* loop around */ 250 /* loop around */
251 dgl_wait->last_primary = dgl_wait->size; 251 dgl_wait->last_primary = dgl_wait->size;
252 } 252 }
253 253
254 // note reverse order 254 // note reverse order
255 for(dgl_wait->last_primary = dgl_wait->last_primary - 1; 255 for(dgl_wait->last_primary = dgl_wait->last_primary - 1;
256 dgl_wait->last_primary >= 0; 256 dgl_wait->last_primary >= 0;
@@ -347,16 +347,16 @@ int __attempt_atomic_dgl_acquire(struct litmus_lock *cur_lock, dgl_wait_state_t
347 return -1; 347 return -1;
348 } 348 }
349 } 349 }
350 350
351 /* take the locks */ 351 /* take the locks */
352 for(i = 0; i < dgl_wait->size; ++i) { 352 for(i = 0; i < dgl_wait->size; ++i) {
353 struct litmus_lock *l = dgl_wait->locks[i]; 353 struct litmus_lock *l = dgl_wait->locks[i];
354 354
355 l->ops->dgl_quick_lock(l, cur_lock, dgl_wait->task, &dgl_wait->wq_nodes[i]); 355 l->ops->dgl_quick_lock(l, cur_lock, dgl_wait->task, &dgl_wait->wq_nodes[i]);
356 356
357 BUG_ON(dgl_wait->task != *(l->nest.owner_ptr)); 357 BUG_ON(dgl_wait->task != *(l->nest.owner_ptr));
358 } 358 }
359 359
360 return 0; /* success */ 360 return 0; /* success */
361} 361}
362 362
@@ -488,31 +488,38 @@ asmlinkage long sys_litmus_dgl_lock(void* __user usr_dgl_ods, int dgl_size)
488 goto out; 488 goto out;
489 } 489 }
490 490
491 for(i = 0; i < dgl_size; ++i) { 491 if (dgl_size == 1) {
492 struct od_table_entry *entry = get_entry_for_od(dgl_ods[i]); 492 /* DGL size of 1. Just call regular singular lock. */
493 if(entry && is_lock(entry)) { 493 TRACE_CUR("DGL lock with size = 1. Treating as regular lock.\n");
494 dgl_wait_state.locks[i] = get_lock(entry); 494 err = sys_litmus_lock(dgl_ods[0]);
495 if(!supports_dgl(dgl_wait_state.locks[i])) { 495 }
496 TRACE_CUR("Lock %d does not support all required DGL operations.\n", 496 else {
497 dgl_wait_state.locks[i]->ident); 497 for(i = 0; i < dgl_size; ++i) {
498 struct od_table_entry *entry = get_entry_for_od(dgl_ods[i]);
499 if(entry && is_lock(entry)) {
500 dgl_wait_state.locks[i] = get_lock(entry);
501 if(!supports_dgl(dgl_wait_state.locks[i])) {
502 TRACE_CUR("Lock %d does not support all required DGL operations.\n",
503 dgl_wait_state.locks[i]->ident);
504 goto out;
505 }
506 }
507 else {
508 TRACE_CUR("Invalid lock identifier\n");
498 goto out; 509 goto out;
499 } 510 }
500 } 511 }
501 else {
502 TRACE_CUR("Invalid lock identifier\n");
503 goto out;
504 }
505 }
506 512
507 dgl_wait_state.task = t; 513 dgl_wait_state.task = t;
508 dgl_wait_state.size = dgl_size; 514 dgl_wait_state.size = dgl_size;
509 515
510 TS_DGL_LOCK_START; 516 TS_DGL_LOCK_START;
511 err = do_litmus_dgl_lock(&dgl_wait_state); 517 err = do_litmus_dgl_lock(&dgl_wait_state);
512 518
513 /* Note: task my have been suspended or preempted in between! Take 519 /* Note: task my have been suspended or preempted in between! Take
514 * this into account when computing overheads. */ 520 * this into account when computing overheads. */
515 TS_DGL_LOCK_END; 521 TS_DGL_LOCK_END;
522 }
516 523
517out: 524out:
518 return err; 525 return err;
@@ -567,28 +574,36 @@ asmlinkage long sys_litmus_dgl_unlock(void* __user usr_dgl_ods, int dgl_size)
567 if(__copy_from_user(&dgl_ods, usr_dgl_ods, dgl_size*(sizeof(int)))) 574 if(__copy_from_user(&dgl_ods, usr_dgl_ods, dgl_size*(sizeof(int))))
568 goto out; 575 goto out;
569 576
570 for(i = 0; i < dgl_size; ++i) { 577
571 entry = get_entry_for_od(dgl_ods[i]); 578 if (dgl_size == 1) {
572 if(entry && is_lock(entry)) { 579 /* DGL size of 1. Just call regular singular lock. */
573 dgl_locks[i] = get_lock(entry); 580 TRACE_CUR("DGL unlock with size = 1. Treating as regular unlock.\n");
574 if(!supports_dgl(dgl_locks[i])) { 581 err = sys_litmus_unlock(dgl_ods[0]);
575 TRACE_CUR("Lock %d does not support all required DGL operations.\n", 582 }
576 dgl_locks[i]->ident); 583 else {
584 for(i = 0; i < dgl_size; ++i) {
585 entry = get_entry_for_od(dgl_ods[i]);
586 if(entry && is_lock(entry)) {
587 dgl_locks[i] = get_lock(entry);
588 if(!supports_dgl(dgl_locks[i])) {
589 TRACE_CUR("Lock %d does not support all required DGL operations.\n",
590 dgl_locks[i]->ident);
591 goto out;
592 }
593 }
594 else {
595 TRACE_CUR("Invalid lock identifier\n");
577 goto out; 596 goto out;
578 } 597 }
579 } 598 }
580 else {
581 TRACE_CUR("Invalid lock identifier\n");
582 goto out;
583 }
584 }
585 599
586 TS_DGL_UNLOCK_START; 600 TS_DGL_UNLOCK_START;
587 err = do_litmus_dgl_unlock(dgl_locks, dgl_size); 601 err = do_litmus_dgl_unlock(dgl_locks, dgl_size);
588 602
589 /* Note: task my have been suspended or preempted in between! Take 603 /* Note: task my have been suspended or preempted in between! Take
590 * this into account when computing overheads. */ 604 * this into account when computing overheads. */
591 TS_DGL_UNLOCK_END; 605 TS_DGL_UNLOCK_END;
606 }
592 607
593out: 608out:
594 return err; 609 return err;