~ubuntu-branches/ubuntu/natty/eglibc/natty-security

« back to all changes in this revision

Viewing changes to nptl/DESIGN-condvar.txt

  • Committer: Bazaar Package Importer
  • Author(s): Aurelien Jarno
  • Date: 2009-05-05 09:54:14 UTC
  • Revision ID: james.westby@ubuntu.com-20090505095414-c45qsg9ixjheohru
ImportĀ upstreamĀ versionĀ 2.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Conditional Variable pseudocode.
 
2
================================
 
3
 
 
4
       int pthread_cond_timedwait (pthread_cond_t *cv, pthread_mutex_t *mutex);
 
5
       int pthread_cond_signal    (pthread_cond_t *cv);
 
6
       int pthread_cond_broadcast (pthread_cond_t *cv);
 
7
 
 
8
struct pthread_cond_t {
 
9
 
 
10
   unsigned int cond_lock;
 
11
 
 
12
         internal mutex
 
13
 
 
14
   uint64_t total_seq;
 
15
 
 
16
     Total number of threads using the conditional variable.
 
17
 
 
18
   uint64_t wakeup_seq;
 
19
 
 
20
     sequence number for next wakeup.
 
21
 
 
22
   uint64_t woken_seq;
 
23
 
 
24
     sequence number of last woken thread.
 
25
 
 
26
   uint32_t broadcast_seq;
 
27
 
 
28
}
 
29
 
 
30
 
 
31
struct cv_data {
 
32
 
 
33
   pthread_cond_t *cv;
 
34
 
 
35
   uint32_t bc_seq
 
36
 
 
37
}
 
38
 
 
39
 
 
40
 
 
41
cleanup_handler(cv_data)
 
42
{
 
43
  cv = cv_data->cv;
 
44
  lll_lock(cv->lock);
 
45
 
 
46
  if (cv_data->bc_seq == cv->broadcast_seq) {
 
47
    ++cv->wakeup_seq;
 
48
    ++cv->woken_seq;
 
49
  }
 
50
 
 
51
  /* make sure no signal gets lost.  */
 
52
  FUTEX_WAKE(cv->wakeup_seq, ALL);
 
53
 
 
54
  lll_unlock(cv->lock);
 
55
}
 
56
 
 
57
 
 
58
cond_timedwait(cv, mutex, timeout):
 
59
{
 
60
   lll_lock(cv->lock);
 
61
   mutex_unlock(mutex);
 
62
 
 
63
   cleanup_push
 
64
 
 
65
   ++cv->total_seq;
 
66
   val = seq =  cv->wakeup_seq;
 
67
   cv_data.bc = cv->broadcast_seq;
 
68
   cv_data.cv = cv;
 
69
 
 
70
   while (1) {
 
71
 
 
72
     lll_unlock(cv->lock);
 
73
 
 
74
     enable_async(&cv_data);
 
75
 
 
76
     ret = FUTEX_WAIT(cv->wakeup_seq, val, timeout);
 
77
 
 
78
     restore_async
 
79
 
 
80
     lll_lock(cv->lock);
 
81
 
 
82
     if (bc != cv->broadcast_seq)
 
83
       goto bc_out;
 
84
 
 
85
     val = cv->wakeup_seq;
 
86
 
 
87
     if (val != seq && cv->woken_seq != val) {
 
88
       ret = 0;
 
89
       break;
 
90
     }
 
91
 
 
92
     if (ret == TIMEDOUT) {
 
93
       ++cv->wakeup_seq;
 
94
       break;
 
95
     }
 
96
   }
 
97
 
 
98
   ++cv->woken_seq;
 
99
 
 
100
 bc_out:
 
101
   lll_unlock(cv->lock);
 
102
 
 
103
   cleanup_pop
 
104
 
 
105
   mutex_lock(mutex);
 
106
 
 
107
   return ret;
 
108
}
 
109
 
 
110
cond_signal(cv)
 
111
{
 
112
   lll_lock(cv->lock);
 
113
 
 
114
   if (cv->total_seq > cv->wakeup_seq) {
 
115
     ++cv->wakeup_seq;
 
116
     FUTEX_WAKE(cv->wakeup_seq, 1);
 
117
   }
 
118
 
 
119
   lll_unlock(cv->lock);
 
120
}
 
121
 
 
122
cond_broadcast(cv)
 
123
{
 
124
   lll_lock(cv->lock);
 
125
 
 
126
   if (cv->total_seq > cv->wakeup_seq) {
 
127
     cv->wakeup_seq = cv->total_seq;
 
128
     cv->woken_seq = cv->total_seq;
 
129
     ++cv->broadcast_seq;
 
130
     FUTEX_WAKE(cv->wakeup_seq, ALL);
 
131
   }
 
132
 
 
133
   lll_unlock(cv->lock);
 
134
}