syscall_emul.cc (13571:a320800ceccf) syscall_emul.cc (13644:6180ee72e061)
1/*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 88 unchanged lines hidden (view full) ---

97exitImpl(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc,
98 bool group)
99{
100 int index = 0;
101 int status = p->getSyscallArg(tc, index);
102
103 System *sys = tc->getSystemPtr();
104
1/*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;

--- 88 unchanged lines hidden (view full) ---

97exitImpl(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc,
98 bool group)
99{
100 int index = 0;
101 int status = p->getSyscallArg(tc, index);
102
103 System *sys = tc->getSystemPtr();
104
105 int activeContexts = 0;
106 for (auto &system: sys->systemList)
107 activeContexts += system->numRunningContexts();
108 if (activeContexts == 1) {
109 /**
110 * Even though we are terminating the final thread context, dist-gem5
111 * requires the simulation to remain active and provide
112 * synchronization messages to the switch process. So we just halt
113 * the last thread context and return. The simulation will be
114 * terminated by dist-gem5 in a coordinated manner once all nodes
115 * have signaled their readiness to exit. For non dist-gem5
116 * simulations, readyToExit() always returns true.
117 */
118 if (!DistIface::readyToExit(0)) {
119 tc->halt();
120 return status;
121 }
122
123 exitSimLoop("exiting with last active thread context", status & 0xff);
124 return status;
125 }
126
127 if (group)
128 *p->exitGroup = true;
129
130 if (p->childClearTID)
131 exitFutexWake(tc, p->childClearTID, p->tgid());
132
133 bool last_thread = true;
134 Process *parent = nullptr, *tg_lead = nullptr;

--- 6 unchanged lines hidden (view full) ---

141 * Threads in a thread group require special handing. For instance,
142 * we send the SIGCHLD signal so that it appears that it came from
143 * the head of the group. We also only delete file descriptors if
144 * we are the last thread in the thread group.
145 */
146 if (walk->pid() == p->tgid())
147 tg_lead = walk;
148
105 if (group)
106 *p->exitGroup = true;
107
108 if (p->childClearTID)
109 exitFutexWake(tc, p->childClearTID, p->tgid());
110
111 bool last_thread = true;
112 Process *parent = nullptr, *tg_lead = nullptr;

--- 6 unchanged lines hidden (view full) ---

119 * Threads in a thread group require special handing. For instance,
120 * we send the SIGCHLD signal so that it appears that it came from
121 * the head of the group. We also only delete file descriptors if
122 * we are the last thread in the thread group.
123 */
124 if (walk->pid() == p->tgid())
125 tg_lead = walk;
126
149 if ((sys->threadContexts[i]->status() != ThreadContext::Halted)
150 && (walk != p)) {
127 if ((sys->threadContexts[i]->status() != ThreadContext::Halted) &&
128 (sys->threadContexts[i]->status() != ThreadContext::Halting) &&
129 (walk != p)) {
151 /**
152 * Check if we share thread group with the pointer; this denotes
153 * that we are not the last thread active in the thread group.
154 * Note that setting this to false also prevents further
155 * iterations of the loop.
156 */
130 /**
131 * Check if we share thread group with the pointer; this denotes
132 * that we are not the last thread active in the thread group.
133 * Note that setting this to false also prevents further
134 * iterations of the loop.
135 */
157 if (walk->tgid() == p->tgid())
158 last_thread = false;
136 if (walk->tgid() == p->tgid()) {
137 /**
138 * If p is trying to exit_group and both walk and p are in
139 * the same thread group (i.e., sharing the same tgid),
140 * we need to halt walk's thread context. After all threads
141 * except p are halted, p becomes the last thread in the
142 * group.
143 *
144 * If p is not doing exit_group and there exists another
145 * active thread context in the group, last_thread is
146 * set to false to prevent the parent thread from killing
147 * all threads in the group.
148 */
149 if (*(p->exitGroup)) {
150 sys->threadContexts[i]->halt();
151 } else {
152 last_thread = false;
153 }
154 }
159
160 /**
161 * A corner case exists which involves execve(). After execve(),
162 * the execve will enable SIGCHLD in the process. The problem
163 * occurs when the exiting process is the root process in the
164 * system; there is no parent to receive the signal. We obviate
165 * this problem by setting the root process' ppid to zero in the
166 * Python configuration files. We really should handle the

--- 17 unchanged lines hidden (view full) ---

184 */
185 for (int i = 0; i < p->fds->getSize(); i++) {
186 if ((*p->fds)[i])
187 p->fds->closeFDEntry(i);
188 }
189 }
190
191 tc->halt();
155
156 /**
157 * A corner case exists which involves execve(). After execve(),
158 * the execve will enable SIGCHLD in the process. The problem
159 * occurs when the exiting process is the root process in the
160 * system; there is no parent to receive the signal. We obviate
161 * this problem by setting the root process' ppid to zero in the
162 * Python configuration files. We really should handle the

--- 17 unchanged lines hidden (view full) ---

180 */
181 for (int i = 0; i < p->fds->getSize(); i++) {
182 if ((*p->fds)[i])
183 p->fds->closeFDEntry(i);
184 }
185 }
186
187 tc->halt();
188
189 /**
190 * check to see if there is no more active thread in the system. If so,
191 * exit the simulation loop
192 */
193 int activeContexts = 0;
194 for (auto &system: sys->systemList)
195 activeContexts += system->numRunningContexts();
196
197 if (activeContexts == 0) {
198 /**
199 * Even though we are terminating the final thread context, dist-gem5
200 * requires the simulation to remain active and provide
201 * synchronization messages to the switch process. So we just halt
202 * the last thread context and return. The simulation will be
203 * terminated by dist-gem5 in a coordinated manner once all nodes
204 * have signaled their readiness to exit. For non dist-gem5
205 * simulations, readyToExit() always returns true.
206 */
207 if (!DistIface::readyToExit(0)) {
208 return status;
209 }
210
211 exitSimLoop("exiting with last active thread context", status & 0xff);
212 return status;
213 }
214
192 return status;
193}
194
195SyscallReturn
196exitFunc(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc)
197{
198 return exitImpl(desc, callnum, p, tc, false);
199}

--- 1504 unchanged lines hidden ---
215 return status;
216}
217
218SyscallReturn
219exitFunc(SyscallDesc *desc, int callnum, Process *p, ThreadContext *tc)
220{
221 return exitImpl(desc, callnum, p, tc, false);
222}

--- 1504 unchanged lines hidden ---