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