SHARE
TWEET

Untitled

a guest May 21st, 2019 54 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
  3.  *  The President and Fellows of Harvard College.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. Neither the name of the University nor the names of its contributors
  14.  *    may be used to endorse or promote products derived from this software
  15.  *    without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
  18.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
  21.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27.  * SUCH DAMAGE.
  28.  */
  29.  
  30. /*
  31.  * Synchronization primitives.
  32.  * The specifications of the functions are in synch.h.
  33.  */
  34.  
  35. #include <types.h>
  36. #include <lib.h>
  37. #include <spinlock.h>
  38. #include <wchan.h>
  39. #include <thread.h>
  40. #include <current.h>
  41. #include <synch.h>
  42.  
  43. ////////////////////////////////////////////////////////////
  44. //
  45. // Semaphore.
  46.  
  47. struct semaphore *
  48. sem_create(const char *name, unsigned initial_count)
  49. {
  50.         struct semaphore *sem;
  51.  
  52.         sem = kmalloc(sizeof(*sem));
  53.         if (sem == NULL) {
  54.                 return NULL;
  55.         }
  56.  
  57.         sem->sem_name = kstrdup(name);
  58.         if (sem->sem_name == NULL) {
  59.                 kfree(sem);
  60.                 return NULL;
  61.         }
  62.  
  63.     sem->sem_wchan = wchan_create(sem->sem_name);
  64.     if (sem->sem_wchan == NULL) {
  65.         kfree(sem->sem_name);
  66.         kfree(sem);
  67.         return NULL;
  68.     }
  69.  
  70.     spinlock_init(&sem->sem_lock);
  71.         sem->sem_count = initial_count;
  72.  
  73.         return sem;
  74. }
  75.  
  76. void
  77. sem_destroy(struct semaphore *sem)
  78. {
  79.         KASSERT(sem != NULL);
  80.  
  81.     /* wchan_cleanup will assert if anyone's waiting on it */
  82.     spinlock_cleanup(&sem->sem_lock);
  83.     wchan_destroy(sem->sem_wchan);
  84.         kfree(sem->sem_name);
  85.         kfree(sem);
  86. }
  87.  
  88. void
  89. P(struct semaphore *sem)
  90. {
  91.         KASSERT(sem != NULL);
  92.  
  93.         /*
  94.          * May not block in an interrupt handler.
  95.          *
  96.          * For robustness, always check, even if we can actually
  97.          * complete the P without blocking.
  98.          */
  99.         KASSERT(curthread->t_in_interrupt == false);
  100.  
  101.     /* Use the semaphore spinlock to protect the wchan as well. */
  102.     spinlock_acquire(&sem->sem_lock);
  103.         while (sem->sem_count == 0) {
  104.         /*
  105.          *
  106.          * Note that we don't maintain strict FIFO ordering of
  107.          * threads going through the semaphore; that is, we
  108.          * might "get" it on the first try even if other
  109.          * threads are waiting. Apparently according to some
  110.          * textbooks semaphores must for some reason have
  111.          * strict ordering. Too bad. :-)
  112.          *
  113.          * Exercise: how would you implement strict FIFO
  114.          * ordering?
  115.          */
  116.         wchan_sleep(sem->sem_wchan, &sem->sem_lock);
  117.         }
  118.         KASSERT(sem->sem_count > 0);
  119.         sem->sem_count--;
  120.     spinlock_release(&sem->sem_lock);
  121. }
  122.  
  123. void
  124. V(struct semaphore *sem)
  125. {
  126.         KASSERT(sem != NULL);
  127.  
  128.     spinlock_acquire(&sem->sem_lock);
  129.  
  130.         sem->sem_count++;
  131.         KASSERT(sem->sem_count > 0);
  132.     wchan_wakeone(sem->sem_wchan, &sem->sem_lock);
  133.  
  134.     spinlock_release(&sem->sem_lock);
  135. }
  136.  
  137. ////////////////////////////////////////////////////////////
  138. //
  139. // Lock.
  140.  
  141. #include "opt-lock.h"
  142. #if OPT_LOCK==1
  143.  
  144.  
  145. struct lock *
  146. lock_create(const char *name)
  147. {
  148.         struct lock *lock;
  149.  
  150.         lock = kmalloc(sizeof(*lock)); //allocato come puntatore, punta e basta
  151.         if (lock == NULL) {
  152.                 return NULL;
  153.         }
  154.  
  155.         lock->lk_name = kstrdup(name);
  156.         if (lock->lk_name == NULL) {
  157.                 kfree(lock);
  158.                 return NULL;
  159.         }
  160.  
  161.         // add stuff here as needed
  162.  
  163.     lock->lk_wchan = wchan_create(lock->lk_name);
  164.     if (lock->lk_wchan == NULL) {
  165.         kfree(lock->lk_name);
  166.         kfree(lock);
  167.         return NULL;
  168.     }
  169.  
  170.     spinlock_init(&lock->lk_lock);
  171.         lock->lk_count = 1;
  172.     //
  173.         return lock;
  174. }
  175.  
  176. void
  177. lock_destroy(struct lock *lock)
  178. {
  179.         KASSERT(lock != NULL);
  180.    
  181.         // add stuff here as needed
  182.     /* wchan_cleanup will assert if anyone's waiting on it */
  183.  
  184.     spinlock_cleanup(&lock->lk_lock);
  185.     wchan_destroy(lock->lk_wchan);
  186.     lock->lk_thread = NULL;
  187.     //
  188.  
  189.         kfree(&lock->lk_name);
  190.         //kfree(lock); //crasha qua in subpage_kfree (malloc.c)
  191.     //forse √® allocato come size of*lock??
  192. }
  193.  
  194. void
  195. lock_acquire(struct lock *lock)
  196. {
  197.         // Write this
  198.     KASSERT(lock != NULL);
  199.  
  200.  
  201.     spinlock_acquire(&lock->lk_lock);
  202.         while (lock->lk_count == 0) {
  203.         wchan_sleep(lock->lk_wchan, &lock->lk_lock);
  204.     }
  205.        
  206.     KASSERT(lock->lk_count > 0);
  207.         lock->lk_count--;
  208.     lock->lk_thread = curthread;
  209.     spinlock_release(&lock->lk_lock);
  210.  
  211.         //(void)lock;  // suppress warning until code gets written
  212. }
  213.  
  214. void
  215. lock_release(struct lock *lock)
  216. {
  217.         // Write this
  218.     KASSERT(lock != NULL);
  219.     KASSERT(lock->lk_thread == curthread); //controllo se possiedo il lock
  220.  
  221.     spinlock_acquire(&lock->lk_lock);
  222.  
  223.         lock->lk_count++;
  224.         KASSERT(lock->lk_count > 0);
  225.     wchan_wakeone(lock->lk_wchan, &lock->lk_lock);
  226.  
  227.     spinlock_release(&lock->lk_lock);
  228.         //(void)lock;  // suppress warning until code gets written
  229. }
  230.  
  231. bool
  232. lock_do_i_hold(struct lock *lock)
  233. {
  234.         // Write this
  235.     spinlock_acquire(&lock->lk_lock);
  236.     struct thread * whocreated = lock -> lk_thread;
  237.     spinlock_release(&lock->lk_lock);
  238.  
  239.     if( whocreated == curthread)
  240.         return true;
  241.     else return false;
  242.         //(void)lock;  // suppress warning until code gets written
  243.  
  244.         return false; // dummy until code gets written
  245. }
  246.  
  247.  
  248.  
  249. ////////////////////////////////////////////////////////////
  250. //
  251. // CV
  252.  
  253.  
  254. struct cv *
  255. cv_create(const char *name)
  256. {
  257.         struct cv *cv;
  258.  
  259.         cv = kmalloc(sizeof(*cv));
  260.         if (cv == NULL) {
  261.                 return NULL;
  262.         }
  263.  
  264.         cv->cv_name = kstrdup(name);
  265.         if (cv->cv_name==NULL) {
  266.                 kfree(cv);
  267.                 return NULL;
  268.         }
  269.  
  270.     //
  271.     cv->cv_wchan = wchan_create(cv->cv_name);
  272.             if (cv->cv_wchan==NULL) {
  273.                 kfree(cv);
  274.                 return NULL;
  275.         }
  276.     spinlock_init(&cv->cv_slock);
  277.     //
  278.         return cv;
  279. }
  280.  
  281. void
  282. cv_destroy(struct cv *cv)
  283. {
  284.         KASSERT(cv != NULL);
  285.         // add stuff here as needed
  286.     wchan_destroy(cv->cv_wchan);
  287.     spinlock_cleanup(&cv->cv_slock);
  288.     //
  289.  
  290.         kfree(cv->cv_name);
  291.         kfree(cv);
  292. }
  293.  
  294. void
  295. cv_wait(struct cv *cv, struct lock *lock)
  296. {
  297.         // Write this
  298.     KASSERT(lock != NULL);
  299.     KASSERT(cv != NULL);
  300.     int res = lock_do_i_hold(lock);
  301.     KASSERT(res == true);
  302.    
  303.     spinlock_acquire(&cv->cv_slock);
  304.     //serve per evitare che qualcuno acquisisca il LOCK prima del risveglio
  305.  
  306.     lock_release(lock); //rilascia il blocco prima di andare a dormire
  307.     wchan_sleep(cv->cv_wchan, &cv->cv_slock);  
  308.     /*  {  
  309.         thread_switch(S_SLEEP, wc, lk);
  310.             spinlock_acquire(lk);
  311.         }
  312.     */
  313.     //spinlock_release --> dentro thread_switch per togliere il lock dal thread corrente   
  314.     //spinlock_acquire --> dentro wchan_sleep sul thread risvegliato
  315.  
  316.     spinlock_release(&cv->cv_slock);
  317.     lock_acquire(lock);
  318.  
  319.         //(void)cv;    // suppress warning until code gets written
  320.         //(void)lock;  // suppress warning until code gets written
  321. }
  322.  
  323. void
  324. cv_signal(struct cv *cv, struct lock *lock)
  325. {
  326.         // Write this
  327.     KASSERT(lock != NULL);
  328.     KASSERT(cv != NULL);
  329.     int res = lock_do_i_hold(lock);
  330.     KASSERT(res == true);
  331.  
  332.     spinlock_acquire(&cv->cv_slock);
  333.  
  334.     wchan_wakeone(cv->cv_wchan, &cv->cv_slock); //slock per omogeneit√†
  335.  
  336.     spinlock_release(&cv->cv_slock);
  337.  
  338.  
  339.     //(void)cv;    // suppress warning until code gets written
  340.     //(void)lock;  // suppress warning until code gets written
  341. }
  342.  
  343. void
  344. cv_broadcast(struct cv *cv, struct lock *lock)
  345. {
  346.     // Write this
  347.     KASSERT(lock != NULL);
  348.     KASSERT(cv != NULL);
  349.     int res = lock_do_i_hold(lock);
  350.     KASSERT(res == true);
  351.  
  352.     spinlock_acquire(&cv->cv_slock);
  353.  
  354.     wchan_wakeall(cv->cv_wchan, &cv->cv_slock); //slock per omogeneit√†
  355.  
  356.     spinlock_release(&cv->cv_slock);
  357.  
  358.     //(void)cv;    // suppress warning until code gets written
  359.     //(void)lock;  // suppress warning until code gets written
  360. }
  361.  
  362. #endif
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top