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 --- |