نمایش نتایج 1 تا 4 از 4

نام تاپیک: سمافور

  1. #1
    کاربر دائمی آواتار yassersajjadi
    تاریخ عضویت
    بهمن 1390
    محل زندگی
    مشهد
    پست
    104

    Question سمافور

    سلام ، ماشالا دوستان خیلی پیشرفت کردن من هنوز باسمافور ها مشکل دارم یعنی بعد اینکه مولتی پروسسور کردم کرنلو باهاش مواجه شدم
    اول کد رو ببینین تا بگم مشکل کجاست


    /*
    * Semaphore v 1.0.0
    * Create a semaphore by (struct semaphore ) then using sem_wait(struct semaphore *) in first
    * For acquiring and sem_signal(struct semaphore *) for release it.
    * Example :
    * struct semaphore s;
    * initsem(&s, "mysem");
    * sem_wait(&s);
    * ...
    * sem_signal(&s);
    */

    #include <types.h>
    #include <defs.h>
    #include <param.h>
    #include <memlayout.h>
    #include <mmu.h>
    #include <x86.h>
    #include <queue.h>
    #include <proc.h>
    #include <spinlock.h>
    #include <semaphore.h>




    void
    initsem(struct semaphore *sem, char* name){
    memset(sem, 0, sizeof(struct semaphore));
    // if count = 0 all process change to sleep
    // then count to be equal by 1.
    sem->count = 1;
    sem->wait = 0;
    initlock(&sem->lock, name);
    queue_init ( &sem->Queue );
    }

    void
    sem_wait(struct semaphore *sem){
    acquire(&sem->lock);

    if ( proc )
    {
    if(sem->count > 0)
    {
    sem->count--;
    }else{
    if(!sem->count){
    struct proc * p;
    if((p = queue_remove ( &sem->Queue, FIRST, NULL ))){
    cprintf("----------> force wakeup %x \n", p);
    wakeup(p);
    }
    }
    queue_append ( &sem->Queue, proc, &proc->SHeader );
    cprintf("----------> sleep %x \n", proc);
    sleep(proc, &sem->lock);
    cprintf("----------> wakeup1 \n");
    }
    }

    release(&sem->lock);
    }

    void
    sem_signal(struct semaphore *sem){
    acquire(&sem->lock);

    if(proc)
    {
    if(!sem->count){
    sem->count++;
    }else{
    struct proc * p;
    while(!(p = queue_remove ( &sem->Queue, FIRST, NULL )));
    cprintf("----------> wakeup %x \n", p);
    wakeup(p);
    }
    }

    release(&sem->lock);

    }

    بزارین اول بگم این چطوری کار میکنه ، وقتی اولین پروسه از سمافور wait میگذره مقدار شمارشگر یکی میاد پایین یعنی از حالت اولیه یک میشه صفر و پروسه بعدی که میاد سمافور اونو به لیست اضافه میکنه و به حالت خواب میبره و مشکل اینجاست که پروسه اولی از سمافور signal گذشته و مقدار شمارشگرو هم به ۱ برگردونده و دیگه هیچ پروسه ای نیست که این پروسه خواب رو بیدار کنه خب یه جور بنبست پیش اومده دیگه ، شاید بگین که اسپین لوک درست کار نکرده که در زمانی که پروسه داشته در سمافور به خواب میرفته اجازه داده که پروسه اول از سیگنال عبور کنه ولی اسپین ها درست کار میکنن و این به این خاطر هست که زمانی که به حالت خواب میرن باید سمافور ازاد بشه و بعد به حالت خواب بره و وقتی که پروسه بیدار شد دوباره قفل بشه و ادامه پیدا کنه

    خب الان تیکه تیکه کد رو توضیح میدم تا بفهمین چی گفتم



    void
    sleep(void *chan, struct spinlock *lk){

    if(proc == 0)
    panic("sleep");

    if(lk == 0)
    panic("sleep without lk");


    اینجا ما قفل سمافور رو ازاد میکنیم تا به حالت خواب بره

    if(lk != &ptable.lock){
    acquire(&ptable.lock);
    release(lk);
    }

    // Go to sleep.
    proc->chan = chan;

    // Set quantum times for next start

    uint laststart = proc->LastStarted;
    proc->LastStarted = proc->Quantum;
    proc->Quantum = ticks - laststart;


    اینجا پروسه به خواب میره

    struct proc *next, *backup;

    next = queue_get(&g_RunningQueue, FIRST);
    while(next){
    backup = queue_get_next(&next->ProcQHeader);
    if(next == proc)
    {
    next->state = SLEEPING;
    next = queue_remove ( &g_RunningQueue, FIRST, &next->ProcQHeader );
    queue_append ( &g_SleepingQueue, next, &next->ProcQHeader );
    }
    next = backup;
    }


    اینجا پروسه سویچ میشه به پروسه دیگه

    sched();

    // Tidy up.
    proc->chan = 0;


    اینجا دوباره سمافور قفل میشه

    // Reacquire original lock.
    if(lk != &ptable.lock){ //DOC: sleeplock2
    release(&ptable.lock);
    acquire(lk);
    }
    }





    خب حالا بریم سر کد سمافور


    void
    sem_wait(struct semaphore *sem){
    acquire(&sem->lock);

    if ( proc )
    {
    if(sem->count > 0)
    {
    sem->count--;
    }else{
    if(!sem->count){
    struct proc * p;
    if((p = queue_remove ( &sem->Queue, FIRST, NULL ))){
    cprintf("----------> force wakeup %x \n", p);
    wakeup(p);
    }
    }
    queue_append ( &sem->Queue, proc, &proc->SHeader );
    cprintf("----------> sleep %x \n", proc);


    اینجا به حالت خواب میره


    sleep(proc, &sem->lock);

    وقتی بیدار میشه از اینجا ادامه پیدا میکنه


    cprintf("----------> wakeup1 \n");
    }
    }

    release(&sem->lock);
    }

  2. #2
    کاربر دائمی آواتار yassersajjadi
    تاریخ عضویت
    بهمن 1390
    محل زندگی
    مشهد
    پست
    104

    نقل قول: سمافور

    کدو به اینم عوض کردم بازم فرقی نکرد


    /*
    * Semaphore v 1.0.0
    * Create a semaphore by (struct semaphore ) then using sem_wait(struct semaphore *) in first
    * For acquiring and sem_signal(struct semaphore *) for release it.
    * Example :
    * struct semaphore s;
    * initsem(&s, "mysem");
    * sem_wait(&s);
    * ...
    * sem_signal(&s);
    */

    #include <types.h>
    #include <defs.h>
    #include <param.h>
    #include <memlayout.h>
    #include <mmu.h>
    #include <x86.h>
    #include <queue.h>
    #include <proc.h>
    #include <spinlock.h>
    #include <semaphore.h>




    void
    initsem(struct semaphore *sem, char* name){
    memset(sem, 0, sizeof(struct semaphore));
    // if clock = 0 all process change to sleep
    // then clock to be equal by 1.
    sem->count = 0;
    initlock(&sem->lock, name);
    queue_init ( &sem->Queue );
    }

    void
    sem_wait(struct semaphore *sem){
    acquire(&sem->lock);

    if ( proc )
    {
    if(sem->count > 0)
    {
    queue_append ( &sem->Queue, proc, &proc->SHeader );
    cprintf("LOG: Sleeping %x \n", proc);
    sem->count++;
    sleep(proc, &sem->lock);
    cprintf("LOG: %x Wakeuped \n", proc);
    }else{
    sem->count++;
    }
    }

    release(&sem->lock);
    }

    void
    sem_signal(struct semaphore *sem){
    acquire(&sem->lock);

    if(proc)
    {
    if(sem->count > 1){
    struct proc * p;
    if((p = queue_remove ( &sem->Queue, FIRST, NULL ))){
    cprintf("LOG: Wakeuping %x \n", p);
    wakeup(p);
    sem->count--;
    }
    }else{
    sem->count--;
    }
    }

    release(&sem->lock);

    }

  3. #3
    کاربر دائمی آواتار yassersajjadi
    تاریخ عضویت
    بهمن 1390
    محل زندگی
    مشهد
    پست
    104

    نقل قول: سمافور

    یه تاخیر قبل از wakeup به کد بالا اضافه کردم درست شد، ولی اگه یه وقت کمی عملیات ، sleeping بیشتر طول بکشه دیگه فایده نداره

  4. #4

    نقل قول: سمافور

    سلام
    منم مدت زمان زیادی با سمافورها درگیر بودم. به احتمال زیاد باگ یه جای دیگه برنامه هست.

    سعی کن ساختارهای سوئیچ برنامه و اینها رو کنترل کنی و اینکه تمام ساختارهای داده باید دارای قفل باشن.

تاپیک های مشابه

  1. الگوریتمهایی برای حل ناحیه بحرانی یا الگوریتم سمافور یا....
    نوشته شده توسط نغمه در بخش الگوریتم، کامپایلر، هوش مصنوعی و ساختمان داده ها
    پاسخ: 129
    آخرین پست: شنبه 28 دی 1392, 14:13 عصر
  2. لطفا کمکم کنید(طراحی یک سمافور در لینوکس)
    نوشته شده توسط oscar_seb در بخش توسعه‌ی لینوکس و نرم افزارهای آزاد
    پاسخ: 1
    آخرین پست: چهارشنبه 08 تیر 1384, 18:32 عصر

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •