Subversion Repositories shark

Rev

Rev 38 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/*
2
 * Project: S.Ha.R.K.
3
 *
4
 * Coordinators:
5
 *   Giorgio Buttazzo    <giorgio@sssup.it>
6
 *   Paolo Gai           <pj@gandalf.sssup.it>
7
 *
8
 * Authors     :
9
 *   Paolo Gai           <pj@gandalf.sssup.it>
10
 *   Massimiliano Giorgi <massy@gandalf.sssup.it>
11
 *   Luca Abeni          <luca@gandalf.sssup.it>
12
 *   (see the web pages for full authors list)
13
 *
14
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
15
 *
16
 * http://www.sssup.it
17
 * http://retis.sssup.it
18
 * http://shark.sssup.it
19
 */
20
 
21
/**
22
 ------------
317 giacomo 23
 CVS :        $Id: sem.c,v 1.4 2003-11-05 15:04:15 giacomo Exp $
2 pj 24
 
25
 File:        $File$
317 giacomo 26
 Revision:    $Revision: 1.4 $
27
 Last update: $Date: 2003-11-05 15:04:15 $
2 pj 28
 ------------
29
 
30
 This file contains the Hartik 3.3.1 Semaphore functions
31
 
32
 Author:      Giuseppe Lipari
33
 
34
 Semaphores:
35
 this is the generalized version of the primitives signal & wait
36
 In this case, the user can specify the number to inc/dec the
37
 semaphore's counter. It is useful in the buffer management
38
 (see port section)
39
 
40
**/
41
 
42
/*
43
 * Copyright (C) 2000 Paolo Gai
44
 *
45
 * This program is free software; you can redistribute it and/or modify
46
 * it under the terms of the GNU General Public License as published by
47
 * the Free Software Foundation; either version 2 of the License, or
48
 * (at your option) any later version.
49
 *
50
 * This program is distributed in the hope that it will be useful,
51
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
52
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
53
 * GNU General Public License for more details.
54
 *
55
 * You should have received a copy of the GNU General Public License
56
 * along with this program; if not, write to the Free Software
57
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
58
 *
59
 */
60
 
61
 
62
#include <stdarg.h>
63
#include <modules/sem.h>
64
#include <kernel/config.h>
65
#include <ll/ll.h>
66
#include <ll/string.h>
67
#include <kernel/const.h>
68
#include <sys/types.h>
69
#include <kernel/descr.h>
70
#include <kernel/var.h>
71
#include <kernel/func.h>
72
#include <kernel/trace.h>
73
#include <limits.h>
74
#include <fcntl.h>
75
 
76
 
77
/* Semaphores descriptor tables */
78
static struct sem_des {
79
    char *name;     /* a name, for named semaphores */
80
    int index;      /* an index for sem_open, containing the sem number */
81
    int count;      /* the semaphore counter */
29 pj 82
    IQUEUE blocked; /* the blocked processes queue */
2 pj 83
    int next;       /* the semaphore queue */
84
    BYTE used;      /* 1 if the semaphore is used */
85
} sem_table[SEM_NSEMS_MAX];
86
 
87
 
88
/* this -IS- an extension to the proc_table!!! */
89
static struct {
90
    int decsem;   /* the value required in sem_xwait */
91
    int sem;      /* the semaphore on whitch the process is blocked */
92
} sp_table[MAX_PROC];
93
 
29 pj 94
static int free_sem;         /* Queue of free sem                    */
2 pj 95
 
96
 
97
 
98
/*----------------------------------------------------------------------*/
99
/* Cancellation test for semaphores                                     */
100
/*----------------------------------------------------------------------*/
101
 
102
/* this is the test that is done when a task is being killed
103
   and it is waiting on a sigwait */
104
static int semwait_cancellation_point(PID i, void *arg)
105
{
106
    LEVEL l;
107
 
108
    if (proc_table[i].status == WAIT_SEM) {
109
      /* the task that have to be killed is waiting on a sig_wait.
110
         we reset the data structures set in sig_wait and then when the
111
         task will return on the sig_wait it will fall into a
112
         task_testcancel */
113
 
114
      /* extract the process from the semaphore queue... */
29 pj 115
      iq_extract(i,&sem_table[ sp_table[i].sem ].blocked);
2 pj 116
 
117
      l = proc_table[i].task_level;
38 pj 118
      level_table[l]->public_unblock(l,i);
2 pj 119
 
120
      return 1;
121
    }
122
 
123
    return 0;
124
}
125
 
126
/*----------------------------------------------------------------------*/
127
/* Init the semaphoric structures                                       */
128
/*----------------------------------------------------------------------*/
129
void SEM_register_module(void)
130
{
131
    int i;
132
 
133
    for (i = 0; i < SEM_NSEMS_MAX; i++) {
134
        sem_table[i].name = NULL;
135
        sem_table[i].index = i;
136
        sem_table[i].count = 0;
29 pj 137
        iq_init(&sem_table[i].blocked, &freedesc, 0);
2 pj 138
        sem_table[i].next = i+1;
139
        sem_table[i].used = 0;
140
    }
141
    sem_table[SEM_NSEMS_MAX-1].next = NIL;
142
    free_sem = 0;
143
 
144
    register_cancellation_point(semwait_cancellation_point, NULL);
145
}
146
 
147
/*----------------------------------------------------------------------*/
148
/* Allocate a semaphoric descriptor and sets the counter to n           */
149
/*----------------------------------------------------------------------*/
150
 
151
// the pshared parameter is NRQ for PSE52
152
int sem_init(sem_t *sem, int pshared, unsigned int value)
153
{
317 giacomo 154
    SYS_FLAGS f;
155
 
2 pj 156
    if (value > SEM_VALUE_MAX)
157
      return EINVAL;
158
 
317 giacomo 159
    f = kern_fsave();
2 pj 160
    *sem = free_sem;
161
    if (*sem != NIL) {
162
        free_sem = sem_table[*sem].next;
163
        sem_table[*sem].name = NULL;
164
        sem_table[*sem].count = value;
29 pj 165
        iq_init(&sem_table[*sem].blocked, &freedesc, 0);
2 pj 166
        sem_table[*sem].used = 1;
167
    }
168
    else {
169
        errno = ENOSPC;
317 giacomo 170
        kern_frestore(f);
2 pj 171
        return -1;
172
    }
317 giacomo 173
    kern_frestore(f);
2 pj 174
    return 0;
175
}
176
 
177
/*----------------------------------------------------------------------*/
178
/* Frees a semaphores descriptor                                        */
179
/*----------------------------------------------------------------------*/
180
int sem_destroy(sem_t *sem)
181
{
317 giacomo 182
    SYS_FLAGS f;
183
 
184
    f = kern_fsave();
2 pj 185
 
186
    if (*sem < 0 || *sem >= SEM_NSEMS_MAX || !sem_table[*sem].used) {
187
      errno = EINVAL;
317 giacomo 188
      kern_frestore(f);
2 pj 189
      return -1;
190
    }
191
 
192
    if (sem_table[*sem].blocked.first != NIL) {
193
      errno = EBUSY;
317 giacomo 194
      kern_frestore(f);
2 pj 195
      return -1;
196
    }
197
 
198
    sem_table[*sem].used = 0;
199
    sem_table[*sem].next = free_sem;
200
    free_sem = *sem;
201
 
317 giacomo 202
    kern_frestore(f);
2 pj 203
    return 0;
204
}
205
 
206
/*----------------------------------------------------------------------*/
207
/* Allocate a named semaphore                                           */
208
/*----------------------------------------------------------------------*/
209
 
210
// the pshared parameter is NRQ for PSE52
211
sem_t *sem_open(const char *name, int oflag, ...)
212
{
213
    int i, j;
214
    int found = 0;
215
    mode_t m;
216
    sem_t sem;
317 giacomo 217
    SYS_FLAGS f;
2 pj 218
 
317 giacomo 219
    f = kern_fsave();
2 pj 220
 
221
    for (i = 0; i < SEM_NSEMS_MAX; i++)
222
      if (sem_table[i].used) {
223
        if (strcmp(name, sem_table[i].name) == 0) {
224
          found = 1;
225
          break;
226
        }
227
      }
228
    if (found) {
229
      if (oflag == (O_CREAT | O_EXCL)) {
230
          errno = EEXIST;
317 giacomo 231
          kern_frestore(f);
2 pj 232
          return SEM_FAILED;
233
      } else {
317 giacomo 234
          kern_frestore(f);
2 pj 235
          return &sem_table[i].index;
236
      }
237
    } else {
238
      if (!(oflag & O_CREAT)) {
239
          errno = ENOENT;
317 giacomo 240
          kern_frestore(f);
2 pj 241
          return SEM_FAILED;
242
      } else {
243
          va_list l;
244
 
245
          va_start(l, oflag);
246
            m = va_arg(l,mode_t);
247
            j = va_arg(l, int);
248
          va_end(l);
249
 
250
          if (j > SEM_VALUE_MAX) {
251
            errno = EINVAL;
317 giacomo 252
            kern_frestore(f);
2 pj 253
            return SEM_FAILED;
254
          }
255
 
256
          sem = free_sem;
257
          if (sem != -1) {
258
            free_sem = sem_table[sem].next;
259
            sem_table[sem].name = kern_alloc(strlen((char *)name)+1);
260
            strcpy(sem_table[sem].name, (char *)name);
261
            sem_table[sem].count = j;
29 pj 262
            iq_init(&sem_table[sem].blocked, &freedesc, 0);
2 pj 263
            sem_table[sem].used = 1;
317 giacomo 264
            kern_frestore(f);
2 pj 265
            return &sem_table[sem].index;
266
          }
267
          else {
268
            errno = ENOSPC;
317 giacomo 269
            kern_frestore(f);
2 pj 270
            return SEM_FAILED;
271
          }
272
      }
273
    }
274
}
275
 
276
/*----------------------------------------------------------------------*/
277
/* Frees a named semaphore                                              */
278
/*----------------------------------------------------------------------*/
279
int sem_close(sem_t *sem)
280
{
317 giacomo 281
    SYS_FLAGS f;
2 pj 282
 
317 giacomo 283
    f = kern_fsave();
284
 
2 pj 285
    if (*sem < 0 || *sem >= SEM_NSEMS_MAX || !sem_table[*sem].used) {
286
      errno = EINVAL;
317 giacomo 287
      kern_frestore(f);
2 pj 288
      return -1;
289
    }
290
 
291
/*  why not???
292
    if (sem_table[*sem].q_first != -1) {
293
      errno = EBUSY;
294
      kern_sti();
295
      return -1;
296
    } */
297
 
298
    kern_free(sem_table[*sem].name,strlen(sem_table[*sem].name)+1);
299
    sem_table[*sem].used = 0;
300
    sem_table[*sem].next = free_sem;
301
    free_sem = *sem;
302
 
317 giacomo 303
    kern_frestore(f);
2 pj 304
    return 0;
305
}
306
 
307
/*----------------------------------------------------------------------*/
308
/* Unlink a named semaphore                                             */
309
/*----------------------------------------------------------------------*/
310
int sem_unlink(const char *name)
311
{
312
    int i;
313
    int found = 0;
317 giacomo 314
    SYS_FLAGS f;
2 pj 315
 
317 giacomo 316
    f = kern_fsave();
2 pj 317
 
318
    for (i = 0; i < SEM_NSEMS_MAX; i++)
319
      if (sem_table[i].used) {
320
        if (strcmp(name, sem_table[i].name) == 0) {
321
          found = 1;
322
        }
323
      }
324
 
325
    if (found) {
326
      kern_free(sem_table[i].name,strlen((char *)name)+1);
327
      sem_table[i].used = 0;
328
      sem_table[i].next = free_sem;
329
      free_sem = i;
317 giacomo 330
      kern_frestore(f);
2 pj 331
      return 0;
332
    } else {
333
      errno = ENOENT;
317 giacomo 334
      kern_frestore(f);
2 pj 335
      return SEM_FAILED;
336
    }
337
}
338
 
339
/*----------------------------------------------------------------------*/
340
/* Generic wait. If it is possible, decrements the sem counter of n,    */
341
/* else blocks the task.                                                */
342
/*----------------------------------------------------------------------*/
343
int sem_wait(sem_t *s)
344
{
345
    struct sem_des *s1; /* It speeds up access */
346
 
347
    if (*s < 0 || *s >= SEM_NSEMS_MAX || !sem_table[*s].used) {
348
      errno = EINVAL;
349
      return -1;
350
    }
351
 
352
    task_testcancel();
353
 
354
    proc_table[exec_shadow].context = kern_context_save();
355
 
356
    s1 = &sem_table[*s];
357
 
358
    if (s1->blocked.first != NIL || s1->count == 0)  {
359
            /* We must block exec task   */
360
            LEVEL l;            /* for readableness only */
361
 
362
            /* tracer stuff */
363
            trc_logevent(TRC_SEM_WAIT,s);
364
 
38 pj 365
            kern_epilogue_macro();
366
 
2 pj 367
            l = proc_table[exec_shadow].task_level;
38 pj 368
            level_table[l]->public_block(l,exec_shadow);
2 pj 369
 
370
            /* we insert the task in the semaphore queue */
371
            proc_table[exec_shadow].status = WAIT_SEM;
372
 
373
            /* Prepare sem_table des... */
374
            sp_table[exec_shadow].decsem = 1;
375
            sp_table[exec_shadow].sem = *s;
376
 
377
            /* ...and put it in sem queue */
29 pj 378
            iq_insertlast(exec_shadow,&s1->blocked);
2 pj 379
 
380
            /* and finally we reschedule */
381
            exec = exec_shadow = -1;
382
            scheduler();
383
            kern_context_load(proc_table[exec_shadow].context);
384
 
385
            /* sem_wait is a cancellation point... */
386
            task_testcancel();
387
    }
388
    else {
389
            s1->count--;
390
            /* tracer stuff */
391
            trc_logevent(TRC_SEM_WAIT,s);
392
            kern_context_load(proc_table[exec_shadow].context);
393
    }
394
 
395
    return 0;
396
}
397
 
398
/*----------------------------------------------------------------------*/
399
/* Non-blocking wait                                                    */
400
/*----------------------------------------------------------------------*/
401
int sem_trywait(sem_t *s)
402
{
403
    struct sem_des *s1; /* It speeds up access */
317 giacomo 404
    SYS_FLAGS f;
2 pj 405
 
406
    if (*s < 0 || *s >= SEM_NSEMS_MAX || !sem_table[*s].used) {
407
      errno = EINVAL;
408
      return -1;
409
    }
410
 
317 giacomo 411
    f = kern_fsave();
2 pj 412
 
413
    s1 = &sem_table[*s];
414
 
415
    /* tracer stuff */
416
    //trc_logevent(TRC_SEM_WAITNB,s);
417
 
418
    if (s1->blocked.first != NIL || s1->count == 0)  {
419
      errno = EAGAIN;
317 giacomo 420
      kern_frestore(f);
2 pj 421
      return -1;
422
    }
423
    else
424
      s1->count--;
425
 
317 giacomo 426
    kern_frestore(f);
2 pj 427
    return 0;
428
}
429
 
430
 
431
/*----------------------------------------------------------------------*/
432
/* Generic wait. If it is possible, decrements the sem counter of n,    */
433
/* else blocks the task.                                                */
434
/*----------------------------------------------------------------------*/
435
int sem_xwait(sem_t *s, int n, int wait)
436
{
437
    struct sem_des *s1; /* It speeds up access */
317 giacomo 438
    SYS_FLAGS f;
439
 
440
    f = kern_fsave();
441
    kern_frestore(f);
2 pj 442
 
443
    if (*s < 0 || *s >= SEM_NSEMS_MAX || !sem_table[*s].used) {
444
      errno = EINVAL;
445
      return -1;
446
    }
447
 
448
    /* We do not need to save context if we are sure we shall not block! */
449
    if (wait == NON_BLOCK)
317 giacomo 450
      f = kern_fsave();
2 pj 451
    else
452
      proc_table[exec_shadow].context = kern_context_save();
453
 
454
    s1 = &sem_table[*s];
455
 
456
    /* The non blocking wait is really simple! */
457
    /* We do not suspend or schedule anything  */    
458
    if (wait == NON_BLOCK) {
459
      /* tracer */
460
      //trc_logevent(TRC_SEM_WAITNB,s);
461
 
462
      if (s1->blocked.first != NIL || s1->count < n)  {
463
        errno = EAGAIN;
317 giacomo 464
        kern_frestore(f);
2 pj 465
        return -1;
466
      }
467
      else
468
        s1->count -= n;
469
 
317 giacomo 470
      kern_frestore(f);
2 pj 471
      return 0;
472
    }
473
    /* The blocking wait is more complex... */
474
    else {
475
        /* the blocking wait is a cancellation point */
476
        task_testcancel();
477
 
478
        if (s1->blocked.first != NIL || s1->count < n)  {
479
                    /* We must block exec task   */
480
                    LEVEL l;            /* for readableness only */
481
 
482
                    /* tracer */
483
                    trc_logevent(TRC_SEM_WAIT,s);
38 pj 484
 
485
                    kern_epilogue_macro();
2 pj 486
 
487
                    l = proc_table[exec_shadow].task_level;
38 pj 488
                    level_table[l]->public_block(l,exec_shadow);
2 pj 489
 
490
                    /* we insert the task in the semaphore queue */
491
                    proc_table[exec_shadow].status = WAIT_SEM;
492
 
493
                    /* Prepare sem_table des... */
494
                    sp_table[exec_shadow].decsem = n;
495
                    sp_table[exec_shadow].sem = *s;
496
 
497
                    /* ...and put it in sem queue */
29 pj 498
                    iq_insertlast(exec_shadow,&s1->blocked);
2 pj 499
 
500
                    /* and finally we reschedule */
501
                    exec = exec_shadow = -1;
502
                    scheduler();
503
                    kern_context_load(proc_table[exec_shadow].context);
504
 
505
                    /* sem_wait is a cancellation point... */
506
                    task_testcancel();
507
            }
508
            else {
509
                    s1->count -= n;
510
                    /* tracer */
511
                    trc_logevent(TRC_SEM_WAIT,s);
512
                    kern_context_load(proc_table[exec_shadow].context);
513
            }
514
    }
515
 
516
    return 0;
517
}
518
 
519
/*----------------------------------------------------------------------*/
520
/* Generic signal. It increments the sem counter of 1, and wakes one    */
521
/* of the tasks that are blocked on the semaphore, if it is possible.The*/
522
/* semaphoric queue is a FIFO queue, in order to eliminate deadlocks    */
523
/*----------------------------------------------------------------------*/
524
int sem_post(sem_t *s)
525
{
526
    struct sem_des *s1;        /* it speeds up access          */
527
    int p;                     /* idem                         */
528
    LEVEL l;
529
 
530
    if (*s < 0 || *s >= SEM_NSEMS_MAX || !sem_table[*s].used) {
531
      errno = EINVAL;
532
      return -1;
533
    }
534
 
535
    // ugly patch to call a sem_post!!!
536
    if (ll_ActiveInt()) {
537
      SYS_FLAGS f;
538
      f = kern_fsave();
539
      s1 = &sem_table[*s];
540
      s1->count ++;              /* inc sem count                */
541
 
542
      p = s1->blocked.first;
543
      if (p != NIL && sp_table[p].decsem <= s1->count) {
544
        /* Dec sem count */
545
        s1->count -= sp_table[p].decsem;
546
 
547
        /* Get task from blocked queue */
29 pj 548
        iq_extract(p,&s1->blocked);
2 pj 549
 
550
        l = proc_table[p].task_level;
38 pj 551
        level_table[l]->public_unblock(l,p);
2 pj 552
        /* only a task can be awaken */
553
        /* Preempt if necessary */
554
        event_need_reschedule();
555
      }
556
 
557
      /* tracer */
558
      trc_logevent(TRC_SEM_SIGNAL,s);
559
      kern_frestore(f);
560
    }
561
    else {
562
      proc_table[exec].context = kern_context_save();
563
 
564
      s1 = &sem_table[*s];
565
      s1->count ++;              /* inc sem count                */
566
 
567
      p = s1->blocked.first;
568
      if (p != NIL && sp_table[p].decsem <= s1->count) {
569
        /* Dec sem count */
570
        s1->count -= sp_table[p].decsem;
571
 
572
        /* Get task from blocked queue */
29 pj 573
        iq_extract(p,&s1->blocked);
2 pj 574
 
575
        l = proc_table[p].task_level;
38 pj 576
        level_table[l]->public_unblock(l,p);
2 pj 577
        /* only a task can be awaken */
578
        /* Preempt if necessary */
579
        scheduler();
580
      }
581
 
582
      /* tracer */
583
      trc_logevent(TRC_SEM_SIGNAL,s);
584
 
585
      kern_context_load(proc_table[exec_shadow].context);
586
    }
587
 
588
    return 0;
589
}
590
 
591
/*----------------------------------------------------------------------*/
592
/* Generic signal. It increments the sem counter of n, and wakes all the*/
593
/* tasks that are blocked on the semaphore, if it is possible. The      */
594
/* semaphoric queue is a FIFO queue, in order to eliminate deadlocks    */
595
/*----------------------------------------------------------------------*/
596
int sem_xpost(sem_t *s, int n)
597
{
598
    struct sem_des *s1;        /* it speeds up access          */
599
    int p;                     /* idem                         */
600
    int fl = 0;                /* a flag                       */
601
    LEVEL l;
602
 
603
    if (*s < 0 || *s >= SEM_NSEMS_MAX || !sem_table[*s].used) {
604
      errno = EINVAL;
605
      return -1;
606
    }
607
 
608
    // ugly patch to call a sem_post!!!
609
    if (ll_ActiveInt()) {      
610
      SYS_FLAGS f;
611
      f = kern_fsave();
612
      s1 = &sem_table[*s];
613
      s1->count += n;                     /* inc sem count                */
614
 
615
      p = s1->blocked.first;
616
      while (p != NIL && sp_table[p].decsem <= s1->count) {
617
        /* Dec sem count */
618
        s1->count -= sp_table[p].decsem;
619
 
620
        /* Get task from blocked queue */
29 pj 621
        iq_extract(p,&s1->blocked);
2 pj 622
 
623
        l = proc_table[p].task_level;
38 pj 624
        level_table[l]->public_unblock(l,p);
2 pj 625
 
626
        /* Next task to wake            */
627
        p = s1->blocked.first;
628
 
629
        fl = 1;
630
      }
631
 
632
      /* tracer */
633
      trc_logevent(TRC_SEM_SIGNAL,s);
634
 
635
      /* Preempt if necessary */
636
      if (fl) event_need_reschedule();
637
      kern_frestore(f);
638
    }
639
    else {
640
      proc_table[exec].context = kern_context_save();
641
 
642
      s1 = &sem_table[*s];
643
      s1->count += n;                     /* inc sem count                */
644
 
645
      p = s1->blocked.first;
646
      while (p != NIL && sp_table[p].decsem <= s1->count) {
647
        /* Dec sem count */
648
        s1->count -= sp_table[p].decsem;
649
 
650
        /* Get task from blocked queue */
29 pj 651
        iq_extract(p,&s1->blocked);
2 pj 652
 
653
        l = proc_table[p].task_level;
38 pj 654
        level_table[l]->public_unblock(l,p);
2 pj 655
 
656
        /* Next task to wake            */
657
        p = s1->blocked.first;
658
 
659
        fl = 1;
660
      }
661
 
662
      /* tracer */
663
      trc_logevent(TRC_SEM_SIGNAL,s);
664
 
665
      /* Preempt if necessary */
666
      if (fl) scheduler();
667
 
668
      kern_context_load(proc_table[exec_shadow].context);
669
    }
670
 
671
    return 0;
672
}
673
 
674
/*----------------------------------------------------------------------*/
675
/* Getvalue returns the value of the semaphore (>=0). If someone is     */
676
/* blocked on the semaphore, return the number of process blocked (<0)  */
677
/*----------------------------------------------------------------------*/
678
int sem_getvalue(sem_t *sem, int *sval)
679
{
680
    PID p;
317 giacomo 681
    SYS_FLAGS f;
2 pj 682
 
683
    if (*sem < 0 || *sem >= SEM_NSEMS_MAX || !sem_table[*sem].used) {
684
      errno = EINVAL;
685
      return -1;
686
    }
687
 
317 giacomo 688
    f = kern_fsave();
2 pj 689
 
29 pj 690
    if (iq_isempty(&sem_table[*sem].blocked))
2 pj 691
      /* the sem is free */
692
      *sval = sem_table[*sem].count;
693
    else {
694
      /* the sem is busy */
695
      *sval = 0;
29 pj 696
      p = iq_query_first(&sem_table[*sem].blocked);
2 pj 697
      do {
698
        (*sval)--;
29 pj 699
        p = iq_query_next(p, &sem_table[*sem].blocked);
2 pj 700
      } while (p != NIL);
701
    }
702
 
317 giacomo 703
    kern_frestore(f);
2 pj 704
    return 0;
705
}
706
 
707
 
708
/*----------------------------------------------------------------------*/
709
/* this function returns 1 if the task is blocked on a semaphore        */
710
/*----------------------------------------------------------------------*/
711
int isBlocked(PID i)
712
{
713
    if (proc_table[i].status == WAIT_SEM) return 1;
714
    else return 0;
715
}
716