~clint-fewbar/ubuntu/precise/erlang/merge-15b

« back to all changes in this revision

Viewing changes to erts/emulator/beam/erl_thr_queue.h

  • Committer: Package Import Robot
  • Author(s): Sergei Golovan
  • Date: 2011-12-15 19:20:10 UTC
  • mfrom: (1.1.18) (3.5.15 sid)
  • mto: (3.5.16 sid)
  • mto: This revision was merged to the branch mainline in revision 33.
  • Revision ID: package-import@ubuntu.com-20111215192010-jnxcfe3tbrpp0big
Tags: 1:15.b-dfsg-1
* New upstream release.
* Upload to experimental because this release breaks external drivers
  API along with ABI, so several applications are to be fixed.
* Removed SSL patch because the old SSL implementation is removed from
  the upstream distribution.
* Removed never used patch which added native code to erlang beam files.
* Removed the erlang-docbuilder binary package because the docbuilder
  application was dropped by upstream.
* Documented dropping ${erlang-docbuilder:Depends} substvar in
  erlang-depends(1) manpage.
* Made erlang-base and erlang-base-hipe provide virtual package
  erlang-abi-15.b (the number means the first erlang version, which
  provides current ABI).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * %CopyrightBegin%
 
3
 *
 
4
 * Copyright Ericsson AB 2011. All Rights Reserved.
 
5
 *
 
6
 * The contents of this file are subject to the Erlang Public License,
 
7
 * Version 1.1, (the "License"); you may not use this file except in
 
8
 * compliance with the License. You should have received a copy of the
 
9
 * Erlang Public License along with this software. If not, it can be
 
10
 * retrieved online at http://www.erlang.org/.
 
11
 *
 
12
 * Software distributed under the License is distributed on an "AS IS"
 
13
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 
14
 * the License for the specific language governing rights and limitations
 
15
 * under the License.
 
16
 *
 
17
 * %CopyrightEnd%
 
18
 */
 
19
 
 
20
/*
 
21
 * Description: Lock-free queue for communication between threads.
 
22
 *
 
23
 *              Currently only a many-to-one version has been,
 
24
 *              implemented, i.e., many threads can enqueue but
 
25
 *              only one thread can dequeue at a time. It doesn't
 
26
 *              have to be the same thread dequeuing every time, but
 
27
 *              synchronization so that only one thread dequeues
 
28
 *              at a time has to be provided by other means.
 
29
 *
 
30
 *              When/If the need for a many-to-many queue arises,
 
31
 *              this implementation can relatively easy be extended
 
32
 *              to support that too.
 
33
 *
 
34
 *              Usage instructions can be found in erts_thr_queue.c
 
35
 *
 
36
 * Author:      Rickard Green
 
37
 */
 
38
 
 
39
#ifndef ERL_THR_QUEUE_H__
 
40
#define ERL_THR_QUEUE_H__
 
41
 
 
42
#include "sys.h"
 
43
#include "erl_threads.h"
 
44
#include "erl_alloc.h"
 
45
#include "erl_thr_progress.h"
 
46
 
 
47
typedef enum {
 
48
    ERTS_THR_Q_LIVE_UNDEF,
 
49
    ERTS_THR_Q_LIVE_SHORT,
 
50
    ERTS_THR_Q_LIVE_LONG
 
51
} ErtsThrQLive_t;
 
52
 
 
53
#define ERTS_THR_Q_INIT_DEFAULT                                         \
 
54
{                                                                       \
 
55
    {                                                                   \
 
56
        ERTS_THR_Q_LIVE_UNDEF,                                          \
 
57
        ERTS_THR_Q_LIVE_SHORT                                           \
 
58
    },                                                                  \
 
59
    NULL,                                                               \
 
60
    NULL,                                                               \
 
61
    1                                                                   \
 
62
}
 
63
 
 
64
typedef struct ErtsThrQ_t_ ErtsThrQ_t;
 
65
 
 
66
typedef struct {
 
67
    struct {
 
68
        ErtsThrQLive_t queue;
 
69
        ErtsThrQLive_t objects;
 
70
    } live;
 
71
    void *arg;
 
72
    void (*notify)(void *);
 
73
    int auto_finalize_dequeue;
 
74
} ErtsThrQInit_t;
 
75
 
 
76
typedef struct ErtsThrQElement_t_ ErtsThrQElement_t;
 
77
typedef struct ErtsThrQElement_t ErtsThrQPrepEnQ_t;
 
78
 
 
79
typedef union {
 
80
    erts_atomic_t atmc;
 
81
    ErtsThrQElement_t *ptr;
 
82
} ErtsThrQPtr_t;
 
83
 
 
84
struct ErtsThrQElement_t_ {
 
85
    ErtsThrQPtr_t next;
 
86
    union {
 
87
        erts_atomic_t atmc;
 
88
        void *ptr;
 
89
    } data;
 
90
};
 
91
 
 
92
typedef struct {
 
93
    ErtsThrQElement_t *start;
 
94
    ErtsThrQElement_t *end;
 
95
} ErtsThrQFinDeQ_t;
 
96
 
 
97
typedef enum {
 
98
    ERTS_THR_Q_CLEAN,
 
99
    ERTS_THR_Q_NEED_THR_PRGR,
 
100
    ERTS_THR_Q_DIRTY,
 
101
} ErtsThrQCleanState_t;
 
102
 
 
103
#ifdef USE_THREADS
 
104
 
 
105
typedef struct {
 
106
    ErtsThrQElement_t marker;
 
107
    erts_atomic_t last;
 
108
    erts_atomic_t um_refc[2];
 
109
    erts_atomic32_t um_refc_ix;
 
110
    ErtsThrQLive_t live;
 
111
#ifdef ERTS_SMP
 
112
    erts_atomic32_t thr_prgr_clean_scheduled;
 
113
#endif
 
114
    void *arg;
 
115
    void (*notify)(void *);
 
116
} ErtsThrQTail_t;
 
117
 
 
118
struct ErtsThrQ_t_ {
 
119
    /*
 
120
     * This structure needs to be cache line aligned for best
 
121
     * performance.
 
122
     */
 
123
    union {
 
124
        /* Modified by threads enqueuing */
 
125
        ErtsThrQTail_t data;
 
126
        char align__[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(ErtsThrQTail_t))];
 
127
    } tail;
 
128
    /*
 
129
     * Everything below this point is *only* accessed by the
 
130
     * thread dequeuing.
 
131
     */
 
132
    struct {
 
133
        ErtsThrQPtr_t head;
 
134
        ErtsThrQLive_t live;
 
135
        ErtsThrQElement_t *first;
 
136
        ErtsThrQElement_t *unref_end;
 
137
        int clean_reached_head_count;
 
138
        struct {
 
139
            int automatic;
 
140
            ErtsThrQElement_t *start;
 
141
            ErtsThrQElement_t *end;
 
142
        } deq_fini;
 
143
        struct {
 
144
#ifdef ERTS_SMP
 
145
            ErtsThrPrgrVal thr_progress;
 
146
            int thr_progress_reached;
 
147
#endif
 
148
            int um_refc_ix;
 
149
            ErtsThrQElement_t *unref_end;
 
150
        } next;
 
151
        int used_marker;
 
152
        void *arg;
 
153
        void (*notify)(void *);
 
154
    } head;
 
155
    struct {
 
156
        int finalizing;
 
157
        ErtsThrQLive_t live;
 
158
        void *blk;
 
159
    } q;
 
160
};
 
161
 
 
162
#else /* !USE_THREADS */
 
163
 
 
164
struct ErtsThrQ_t_ {
 
165
    ErtsThrQInit_t init;
 
166
    ErtsThrQElement_t *first;
 
167
    ErtsThrQElement_t *last;
 
168
    struct {
 
169
        void *blk;
 
170
    } q;
 
171
};
 
172
 
 
173
#endif
 
174
 
 
175
void erts_thr_q_init(void);
 
176
void erts_thr_q_initialize(ErtsThrQ_t *, ErtsThrQInit_t *);
 
177
ErtsThrQCleanState_t erts_thr_q_finalize(ErtsThrQ_t *);
 
178
ErtsThrQ_t *erts_thr_q_create(ErtsThrQInit_t *);
 
179
ErtsThrQCleanState_t erts_thr_q_destroy(ErtsThrQ_t *);
 
180
ErtsThrQCleanState_t erts_thr_q_clean(ErtsThrQ_t *);
 
181
ErtsThrQCleanState_t erts_thr_q_inspect(ErtsThrQ_t *, int);
 
182
ErtsThrQPrepEnQ_t *erts_thr_q_prepare_enqueue(ErtsThrQ_t *);
 
183
void erts_thr_q_enqueue_prepared(ErtsThrQ_t *, void *, ErtsThrQPrepEnQ_t *);
 
184
void erts_thr_q_enqueue(ErtsThrQ_t *, void *);
 
185
void * erts_thr_q_dequeue(ErtsThrQ_t *);
 
186
int erts_thr_q_get_finalize_dequeue_data(ErtsThrQ_t *,
 
187
                                         ErtsThrQFinDeQ_t *);
 
188
void erts_thr_q_append_finalize_dequeue_data(ErtsThrQFinDeQ_t *,
 
189
                                             ErtsThrQFinDeQ_t *);
 
190
int erts_thr_q_finalize_dequeue(ErtsThrQFinDeQ_t *);
 
191
void erts_thr_q_finalize_dequeue_state_init(ErtsThrQFinDeQ_t *);
 
192
 
 
193
#ifdef ERTS_SMP
 
194
ERTS_GLB_INLINE ErtsThrPrgrVal erts_thr_q_need_thr_progress(ErtsThrQ_t *q);
 
195
#endif
 
196
 
 
197
#if ERTS_GLB_INLINE_INCL_FUNC_DEF
 
198
 
 
199
#ifdef ERTS_SMP
 
200
ERTS_GLB_INLINE ErtsThrPrgrVal
 
201
erts_thr_q_need_thr_progress(ErtsThrQ_t *q)
 
202
{
 
203
    return q->head.next.thr_progress;
 
204
}
 
205
#endif
 
206
 
 
207
#endif /* ERTS_GLB_INLINE_INCL_FUNC_DEF */
 
208
 
 
209
#endif /* ERL_THR_QUEUE_H__ */