~statik/ubuntu/maverick/erlang/erlang-merge-testing

« back to all changes in this revision

Viewing changes to erts/emulator/beam/erl_message.c

  • Committer: Bazaar Package Importer
  • Author(s): Sergei Golovan
  • Date: 2009-05-01 10:14:38 UTC
  • mfrom: (3.1.4 sid)
  • Revision ID: james.westby@ubuntu.com-20090501101438-6qlr6rsdxgyzrg2z
Tags: 1:13.b-dfsg-2
* Cleaned up patches: removed unneeded patch which helped to support
  different SCTP library versions, made sure that changes for m68k
  architecture applied only when building on this architecture.
* Removed duplicated information from binary packages descriptions.
* Don't require libsctp-dev build-dependency on solaris-i386 architecture
  which allows to build Erlang on Nexenta (thanks to Tim Spriggs for
  the suggestion).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* ``The contents of this file are subject to the Erlang Public License,
 
1
/*
 
2
 * %CopyrightBegin%
 
3
 * 
 
4
 * Copyright Ericsson AB 1997-2009. All Rights Reserved.
 
5
 * 
 
6
 * The contents of this file are subject to the Erlang Public License,
2
7
 * Version 1.1, (the "License"); you may not use this file except in
3
8
 * compliance with the License. You should have received a copy of the
4
9
 * Erlang Public License along with this software. If not, it can be
5
 
 * retrieved via the world wide web at http://www.erlang.org/.
 
10
 * retrieved online at http://www.erlang.org/.
6
11
 * 
7
12
 * Software distributed under the License is distributed on an "AS IS"
8
13
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
9
14
 * the License for the specific language governing rights and limitations
10
15
 * under the License.
11
16
 * 
12
 
 * The Initial Developer of the Original Code is Ericsson Utvecklings AB.
13
 
 * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
14
 
 * AB. All Rights Reserved.''
15
 
 * 
16
 
 *     $Id$
 
17
 * %CopyrightEnd%
17
18
 */
18
19
/*
19
20
 * Message passing primitives.
240
241
/* Add a message last in message queue */
241
242
void
242
243
erts_queue_message(Process* receiver,
243
 
                   ErtsProcLocks receiver_locks,
 
244
                   ErtsProcLocks *receiver_locks,
244
245
                   ErlHeapFragment* bp,
245
246
                   Eterm message,
246
247
                   Eterm seq_trace_token)
247
248
{
248
249
    ErlMessage* mp;
249
 
 
250
 
#if !defined(ERTS_SMP)
 
250
#ifdef ERTS_SMP
 
251
    ErtsProcLocks need_locks;
 
252
#else
251
253
    ASSERT(bp != NULL || receiver->mbuf == NULL);
252
254
#endif
253
255
 
254
 
    ERTS_SMP_LC_ASSERT(receiver_locks == erts_proc_lc_my_proc_locks(receiver));
255
 
    ERTS_SMP_LC_ASSERT((ERTS_PROC_LOCKS_MSG_SEND & receiver_locks)
256
 
                       == ERTS_PROC_LOCKS_MSG_SEND);
 
256
    ERTS_SMP_LC_ASSERT(*receiver_locks == erts_proc_lc_my_proc_locks(receiver));
 
257
 
 
258
    mp = message_alloc();
257
259
 
258
260
#ifdef ERTS_SMP
259
 
    if (ERTS_PROC_PENDING_EXIT(receiver)) {
260
 
        /* Drop message if receiver has a pending exit ... */
 
261
    need_locks = ~(*receiver_locks) & (ERTS_PROC_LOCK_MSGQ
 
262
                                       | ERTS_PROC_LOCK_STATUS);
 
263
    if (need_locks) {
 
264
        *receiver_locks |= need_locks;
 
265
        if (erts_smp_proc_trylock(receiver, need_locks) == EBUSY) {
 
266
            if (need_locks == ERTS_PROC_LOCK_MSGQ) {
 
267
                erts_smp_proc_unlock(receiver, ERTS_PROC_LOCK_STATUS);
 
268
                need_locks = (ERTS_PROC_LOCK_MSGQ
 
269
                              | ERTS_PROC_LOCK_STATUS);
 
270
            }
 
271
            erts_smp_proc_lock(receiver, need_locks);
 
272
        }
 
273
    }
 
274
 
 
275
    if (receiver->is_exiting || ERTS_PROC_PENDING_EXIT(receiver)) {
 
276
        /* Drop message if receiver is exiting or has a pending
 
277
         * exit ...
 
278
         */
261
279
        if (bp)
262
280
            free_message_buffer(bp);
 
281
        message_free(mp);
263
282
        return;
264
283
    }
265
284
#endif
266
285
 
267
 
    mp = message_alloc();
268
286
    ERL_MESSAGE_TERM(mp) = message;
269
287
    ERL_MESSAGE_TOKEN(mp) = seq_trace_token;
270
288
    mp->next = NULL;
271
289
 
272
290
#ifdef ERTS_SMP
273
 
    if (receiver_locks & ERTS_PROC_LOCK_MAIN) {
 
291
    if (*receiver_locks & ERTS_PROC_LOCK_MAIN) {
274
292
        mp->bp = bp;
275
293
 
276
294
        /*
295
313
 
296
314
    ACTIVATE(receiver);
297
315
 
298
 
    if (receiver->status == P_WAITING) {
299
 
        add_to_schedule_q(receiver);
300
 
    } else if (receiver->status == P_SUSPENDED) {
 
316
    switch (receiver->status) {
 
317
    case P_GARBING:
 
318
        switch (receiver->gcstatus) {
 
319
        case P_SUSPENDED:
 
320
            goto suspended;
 
321
        case P_WAITING:
 
322
            goto waiting;
 
323
        default:
 
324
            break;
 
325
        }
 
326
        break;
 
327
    case P_SUSPENDED:
 
328
    suspended:
301
329
        receiver->rstatus = P_RUNABLE;
 
330
        break;
 
331
    case P_WAITING:
 
332
    waiting:
 
333
        erts_add_to_runq(receiver);
 
334
        break;
 
335
    default:
 
336
        break;
302
337
    }
303
338
 
304
339
    if (IS_TRACED_FL(receiver, F_TRACE_RECEIVE)) {
621
656
                  Eterm message,
622
657
                  unsigned flags)
623
658
{
 
659
    Uint msize;
624
660
    ErlHeapFragment* bp = NULL;
625
661
    Eterm token = NIL;
626
662
 
629
665
    BM_START_TIMER(send);
630
666
 
631
667
    if (SEQ_TRACE_TOKEN(sender) != NIL && !(flags & ERTS_SND_FLG_NO_SEQ_TRACE)) {
632
 
        Uint msize;
633
668
        Eterm* hp;
634
669
 
635
670
        BM_SWAP_TIMER(send,size);
636
 
        msize = size_object(message);
 
671
        msize = size_object(message);
637
672
        BM_SWAP_TIMER(size,send);
638
673
 
639
674
        seq_trace_update_send(sender);
653
688
        BM_SWAP_TIMER(copy,send);
654
689
 
655
690
        erts_queue_message(receiver,
656
 
                           *receiver_locks,
 
691
                           receiver_locks,
657
692
                           bp,
658
693
                           message,
659
694
                           token);
692
727
        ACTIVATE(receiver);
693
728
 
694
729
        if (receiver->status == P_WAITING) {
695
 
            add_to_schedule_q(receiver);
 
730
            erts_add_to_runq(receiver);
696
731
        } else if (receiver->status == P_SUSPENDED) {
697
732
            receiver->rstatus = P_RUNABLE;
698
733
        }
705
740
#else
706
741
    } else if (sender == receiver) {
707
742
        /* Drop message if receiver has a pending exit ... */
708
 
        if (!ERTS_PROC_PENDING_EXIT(receiver)) {
 
743
#ifdef ERTS_SMP
 
744
        ErtsProcLocks need_locks = (~(*receiver_locks)
 
745
                                    & (ERTS_PROC_LOCK_MSGQ
 
746
                                       | ERTS_PROC_LOCK_STATUS));
 
747
        if (need_locks) {
 
748
            *receiver_locks |= need_locks;
 
749
            if (erts_smp_proc_trylock(receiver, need_locks) == EBUSY) {
 
750
                if (need_locks == ERTS_PROC_LOCK_MSGQ) {
 
751
                    erts_smp_proc_unlock(receiver, ERTS_PROC_LOCK_STATUS);
 
752
                    need_locks = ERTS_PROC_LOCK_MSGQ|ERTS_PROC_LOCK_STATUS;
 
753
                }
 
754
                erts_smp_proc_lock(receiver, need_locks);
 
755
            }
 
756
        }
 
757
        if (!ERTS_PROC_PENDING_EXIT(receiver))
 
758
#endif
 
759
        {
709
760
            ErlMessage* mp = message_alloc();
710
761
 
711
762
            mp->bp = NULL;
732
783
        return;
733
784
    } else {
734
785
#ifdef ERTS_SMP
735
 
        Uint msz;
736
786
        ErlOffHeap *ohp;
737
787
        Eterm *hp;
738
 
        /* Drop message if receiver has a pending exit ... */
739
 
        if (!ERTS_PROC_PENDING_EXIT(receiver)) {
740
 
            BM_SWAP_TIMER(send,size);
741
 
            msz = size_object(message);
742
 
            BM_SWAP_TIMER(size,send);
743
 
            hp = erts_alloc_message_heap(msz,&bp,&ohp,receiver,receiver_locks);
744
 
            BM_SWAP_TIMER(send,copy);
745
 
            message = copy_struct(message, msz, &hp, ohp);
746
 
            BM_MESSAGE_COPIED(msz);
747
 
            BM_SWAP_TIMER(copy,send);
748
 
            erts_queue_message(receiver, 
749
 
                               *receiver_locks,
750
 
                               bp, message, token);
751
 
        }
 
788
        BM_SWAP_TIMER(send,size);
 
789
        msize = size_object(message);
 
790
        BM_SWAP_TIMER(size,send);
 
791
        hp = erts_alloc_message_heap(msize,&bp,&ohp,receiver,receiver_locks);
 
792
        BM_SWAP_TIMER(send,copy);
 
793
        message = copy_struct(message, msize, &hp, ohp);
 
794
        BM_MESSAGE_COPIED(msz);
 
795
        BM_SWAP_TIMER(copy,send);
 
796
        erts_queue_message(receiver, receiver_locks, bp, message, token);
752
797
        BM_SWAP_TIMER(send,system);
753
798
#else
754
799
        ErlMessage* mp = message_alloc();
755
 
        Uint msize;
756
800
        Eterm *hp;
757
801
        BM_SWAP_TIMER(send,size);
758
 
        msize = size_object(message);
 
802
        msize = size_object(message);
759
803
        BM_SWAP_TIMER(size,send);
760
804
        
761
805
        if (receiver->stop - receiver->htop <= msize) {
776
820
        LINK_MESSAGE(receiver, mp);
777
821
 
778
822
        if (receiver->status == P_WAITING) {
779
 
            add_to_schedule_q(receiver);
 
823
            erts_add_to_runq(receiver);
780
824
        } else if (receiver->status == P_SUSPENDED) {
781
825
            receiver->rstatus = P_RUNABLE;
782
826
        }
824
868
        /* the trace token must in this case be updated by the caller */
825
869
        seq_trace_output(token, save, SEQ_TRACE_SEND, to->id, NULL);
826
870
        temptoken = copy_struct(token, sz_token, &hp, &bp->off_heap);
827
 
        erts_queue_message(to, *to_locksp, bp, save, temptoken);
 
871
        erts_queue_message(to, to_locksp, bp, save, temptoken);
828
872
    } else {
829
873
        ErlOffHeap *ohp;
830
874
        sz_reason = size_object(reason);
841
885
                     ? from
842
886
                     : copy_struct(from, sz_from, &hp, ohp));
843
887
        save = TUPLE3(hp, am_EXIT, from_copy, mess);
844
 
        erts_queue_message(to, *to_locksp, bp, save, NIL);
 
888
        erts_queue_message(to, to_locksp, bp, save, NIL);
845
889
    }
846
890
}