Subversion Repositories HelenOS

Rev

Rev 2894 | Rev 2899 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2894 Rev 2898
Line 42... Line 42...
42
#include <arch.h>
42
#include <arch.h>
43
 
43
 
44
void udebug_stoppable_begin(void)
44
void udebug_stoppable_begin(void)
45
{
45
{
46
    int nsc;
46
    int nsc;
47
    call_t *db_call;
47
    call_t *db_call, *go_call;
48
    ipl_t ipl;
48
    ipl_t ipl;
49
 
49
 
50
    ipl = interrupts_disable();
50
    ipl = interrupts_disable();
51
    spinlock_lock(&TASK->lock);
51
    spinlock_lock(&TASK->lock);
52
 
52
 
Line 57... Line 57...
57
        klog_printf("udebug_stoppable_begin");
57
        klog_printf("udebug_stoppable_begin");
58
        klog_printf(" - nsc := %d", nsc);
58
        klog_printf(" - nsc := %d", nsc);
59
    }
59
    }
60
 
60
 
61
    if (TASK->dt_state == UDEBUG_TS_BEGINNING && nsc == 0) {
61
    if (TASK->dt_state == UDEBUG_TS_BEGINNING && nsc == 0) {
-
 
62
        /*
-
 
63
         * This was the last non-stoppable thread. Reply to
-
 
64
         * DEBUG_BEGIN call.
-
 
65
         */
-
 
66
 
-
 
67
        /* Lock order OK, THREAD->debug_lock is after TASK->lock */
-
 
68
        spinlock_lock(&THREAD->debug_lock);
-
 
69
        THREAD->debug_stoppable = true;
-
 
70
        spinlock_unlock(&THREAD->debug_lock);
-
 
71
 
62
        TASK->dt_state = UDEBUG_TS_ACTIVE;
72
        TASK->dt_state = UDEBUG_TS_ACTIVE;
63
        TASK->debug_begin_call = NULL;
73
        TASK->debug_begin_call = NULL;
64
        spinlock_unlock(&TASK->lock);
74
        spinlock_unlock(&TASK->lock);
65
        interrupts_restore(ipl);
75
        interrupts_restore(ipl);
66
 
76
 
67
        IPC_SET_RETVAL(db_call->data, 0);
77
        IPC_SET_RETVAL(db_call->data, 0);
68
        klog_printf("udebug_stoppable_begin/ipc_answer");
78
        klog_printf("udebug_stoppable_begin/ipc_answer");
69
        ipc_answer(&TASK->answerbox, db_call);     
79
        ipc_answer(&TASK->answerbox, db_call);     
-
 
80
 
-
 
81
    } else if (TASK->dt_state == UDEBUG_TS_ACTIVE) {
-
 
82
        /*
-
 
83
         * Active debugging session
-
 
84
         */
-
 
85
 
-
 
86
        /* Lock order OK, THREAD->debug_lock is after TASK->lock */
-
 
87
        spinlock_lock(&THREAD->debug_lock);
-
 
88
        THREAD->debug_stoppable = true;
-
 
89
 
-
 
90
        if (THREAD->debug_stop) {
-
 
91
            /*
-
 
92
             * Thread was requested to stop - answer go call
-
 
93
             */
-
 
94
 
-
 
95
            /* Make sure nobody takes this call away from us */
-
 
96
            go_call = THREAD->debug_go_call;
-
 
97
            THREAD->debug_go_call = NULL;
-
 
98
 
-
 
99
            IPC_SET_RETVAL(go_call->data, 0);
-
 
100
            IPC_SET_ARG1(go_call->data, UDEBUG_EVENT_STOP);
-
 
101
 
-
 
102
            THREAD->cur_event = UDEBUG_EVENT_STOP;
-
 
103
            spinlock_unlock(&THREAD->debug_lock);
-
 
104
 
-
 
105
                ipc_answer(&TASK->answerbox, go_call);
-
 
106
 
-
 
107
                spinlock_unlock(&TASK->lock);
-
 
108
            interrupts_restore(ipl);
-
 
109
        } else {
-
 
110
            /*
-
 
111
             * No stop request - nothing happens.
-
 
112
             */
-
 
113
            spinlock_unlock(&THREAD->debug_lock);
-
 
114
                spinlock_unlock(&TASK->lock);
-
 
115
            interrupts_restore(ipl);
-
 
116
        }
70
    } else {
117
    } else {
-
 
118
        /*
-
 
119
         * All other cases - nothing special happens.
-
 
120
         */
-
 
121
 
-
 
122
        /* Lock order OK, THREAD->debug_lock is after TASK->lock */
-
 
123
        spinlock_lock(&THREAD->debug_lock);
-
 
124
        THREAD->debug_stoppable = true;
-
 
125
        spinlock_unlock(&THREAD->debug_lock);
-
 
126
 
71
            spinlock_unlock(&TASK->lock);
127
            spinlock_unlock(&TASK->lock);
72
        interrupts_restore(ipl);
128
        interrupts_restore(ipl);
73
    }
129
    }
74
}
130
}
75
 
131
 
Line 79... Line 135...
79
 
135
 
80
restart:
136
restart:
81
    ipl = interrupts_disable();
137
    ipl = interrupts_disable();
82
    spinlock_lock(&TASK->lock);
138
    spinlock_lock(&TASK->lock);
83
 
139
 
-
 
140
    /* Lock order OK, THREAD->debug_lock is after TASK->lock */
-
 
141
    spinlock_lock(&THREAD->debug_lock);
-
 
142
 
-
 
143
    if (TASK->dt_state == UDEBUG_TS_ACTIVE) {
-
 
144
        klog_printf("udebug_stoppable_end");
-
 
145
        klog_printf("debug_stop=%d", THREAD->debug_stop);
-
 
146
    }
-
 
147
 
84
    if ((TASK->dt_state == UDEBUG_TS_BEGINNING ||
148
    if ((TASK->dt_state == UDEBUG_TS_BEGINNING ||
85
        TASK->dt_state == UDEBUG_TS_ACTIVE) &&
149
        TASK->dt_state == UDEBUG_TS_ACTIVE) &&
86
        THREAD->debug_stop == true) {
150
        THREAD->debug_stop == true) {
87
        TASK->debug_begin_call = NULL;
151
        TASK->debug_begin_call = NULL;
-
 
152
        spinlock_unlock(&THREAD->debug_lock);
88
        spinlock_unlock(&TASK->lock);
153
        spinlock_unlock(&TASK->lock);
89
        interrupts_restore(ipl);
154
        interrupts_restore(ipl);
90
 
155
 
91
        klog_printf("udebug_stoppable_end: waitq_sleep");
156
        klog_printf("udebug_stoppable_end: waitq_sleep");
92
        waitq_sleep(&THREAD->go_wq);
157
        waitq_sleep(&THREAD->go_wq);
93
        goto restart;
158
        goto restart;
94
        /* must try again - have to lose stoppability atomically */
159
        /* must try again - have to lose stoppability atomically */
95
    } else {
160
    } else {
96
        ++TASK->not_stoppable_count;
161
        ++TASK->not_stoppable_count;
-
 
162
        THREAD->debug_stoppable = false;
-
 
163
 
-
 
164
        spinlock_unlock(&THREAD->debug_lock);
97
        spinlock_unlock(&TASK->lock);
165
        spinlock_unlock(&TASK->lock);
98
        interrupts_restore(ipl);
166
        interrupts_restore(ipl);
99
    }
167
    }
100
}
168
}
101
 
169