syscall_emul.hh (9008:59d2bcf37782) | syscall_emul.hh (9112:6e854ea87bab) |
---|---|
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; --- 320 unchanged lines hidden (view full) --- 329/// Target getegid() handler. 330SyscallReturn getegidFunc(SyscallDesc *desc, int num, 331 LiveProcess *p, ThreadContext *tc); 332 333/// Target clone() handler. 334SyscallReturn cloneFunc(SyscallDesc *desc, int num, 335 LiveProcess *p, ThreadContext *tc); 336 | 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; --- 320 unchanged lines hidden (view full) --- 329/// Target getegid() handler. 330SyscallReturn getegidFunc(SyscallDesc *desc, int num, 331 LiveProcess *p, ThreadContext *tc); 332 333/// Target clone() handler. 334SyscallReturn cloneFunc(SyscallDesc *desc, int num, 335 LiveProcess *p, ThreadContext *tc); 336 |
337/// Futex system call 338/// Implemented by Daniel Sanchez 339/// Used by printf's in multi-threaded apps 340template <class OS> 341SyscallReturn 342futexFunc(SyscallDesc *desc, int callnum, LiveProcess *process, 343 ThreadContext *tc) 344{ 345 int index_uaddr = 0; 346 int index_op = 1; 347 int index_val = 2; 348 int index_timeout = 3; |
|
337 | 349 |
350 uint64_t uaddr = process->getSyscallArg(tc, index_uaddr); 351 int op = process->getSyscallArg(tc, index_op); 352 int val = process->getSyscallArg(tc, index_val); 353 uint64_t timeout = process->getSyscallArg(tc, index_timeout); 354 355 std::map<uint64_t, std::list<ThreadContext *> * > 356 &futex_map = tc->getSystemPtr()->futexMap; 357 358 DPRINTF(SyscallVerbose, "In sys_futex: Address=%llx, op=%d, val=%d\n", 359 uaddr, op, val); 360 361 362 if (op == OS::TGT_FUTEX_WAIT) { 363 if (timeout != 0) { 364 warn("sys_futex: FUTEX_WAIT with non-null timeout unimplemented;" 365 "we'll wait indefinitely"); 366 } 367 368 uint8_t *buf = new uint8_t[sizeof(int)]; 369 tc->getMemProxy().readBlob((Addr)uaddr, buf, (int)sizeof(int)); 370 int mem_val = *((int *)buf); 371 delete buf; 372 373 if(val != mem_val) { 374 DPRINTF(SyscallVerbose, "sys_futex: FUTEX_WAKE, read: %d, " 375 "expected: %d\n", mem_val, val); 376 return -OS::TGT_EWOULDBLOCK; 377 } 378 379 // Queue the thread context 380 std::list<ThreadContext *> * tcWaitList; 381 if (futex_map.count(uaddr)) { 382 tcWaitList = futex_map.find(uaddr)->second; 383 } else { 384 tcWaitList = new std::list<ThreadContext *>(); 385 futex_map.insert(std::pair< uint64_t, 386 std::list<ThreadContext *> * >(uaddr, tcWaitList)); 387 } 388 tcWaitList->push_back(tc); 389 DPRINTF(SyscallVerbose, "sys_futex: FUTEX_WAIT, suspending calling " 390 "thread context\n"); 391 tc->suspend(); 392 return 0; 393 } else if (op == OS::TGT_FUTEX_WAKE){ 394 int wokenUp = 0; 395 std::list<ThreadContext *> * tcWaitList; 396 if (futex_map.count(uaddr)) { 397 tcWaitList = futex_map.find(uaddr)->second; 398 while (tcWaitList->size() > 0 && wokenUp < val) { 399 tcWaitList->front()->activate(); 400 tcWaitList->pop_front(); 401 wokenUp++; 402 } 403 if(tcWaitList->empty()) { 404 futex_map.erase(uaddr); 405 delete tcWaitList; 406 } 407 } 408 DPRINTF(SyscallVerbose, "sys_futex: FUTEX_WAKE, activated %d waiting " 409 "thread contexts\n", wokenUp); 410 return wokenUp; 411 } else { 412 warn("sys_futex: op %d is not implemented, just returning..."); 413 return 0; 414 } 415 416} 417 418 |
|
338/// Pseudo Funcs - These functions use a different return convension, 339/// returning a second value in a register other than the normal return register 340SyscallReturn pipePseudoFunc(SyscallDesc *desc, int num, 341 LiveProcess *process, ThreadContext *tc); 342 343/// Target getpidPseudo() handler. 344SyscallReturn getpidPseudoFunc(SyscallDesc *desc, int num, 345 LiveProcess *p, ThreadContext *tc); --- 923 unchanged lines hidden --- | 419/// Pseudo Funcs - These functions use a different return convension, 420/// returning a second value in a register other than the normal return register 421SyscallReturn pipePseudoFunc(SyscallDesc *desc, int num, 422 LiveProcess *process, ThreadContext *tc); 423 424/// Target getpidPseudo() handler. 425SyscallReturn getpidPseudoFunc(SyscallDesc *desc, int num, 426 LiveProcess *p, ThreadContext *tc); --- 923 unchanged lines hidden --- |