Newbie Common Lisp question here.
Is there a way to reset the state of the environment? What I mean, is there some command that brings the REPL back to the same state it was right after it started up, that is, uninterning all variables, functions, etc. Or if that's not in the Common Lisp standard, is there some extension in SBCL (the implementation I use) to do that?
(EDIT: I know that in SLIME, M-x slime-restart-inferior-lisp does that but I wonder if there's a way without restarting the process)
Not in general, no. I occasionally want to do something like that, so my workflow is generally to create a new package to hold whatever project I'm starting, then when I want to reset things I use DELETE-PACKAGE. I never do any work in the CL-USER package, since different implementations have different things stuffed into it.
Use C-c M-o, as given in REPL menu's Clear Buffer
Related
Commands which are invoked from LISP are having trouble with buffered IO streams, how to turn it off? I found only flushing functions, which are good for nothing in this situation.
You cannot do that
There is no portable way to turn buffering on and off, and for a very good reason: buffered i/o is orders of magnitude faster.
You should not try to do that
You might be able to find out how to do it in the implementation you use, but it will be a waste of time - you will soon realize that it was a mistake. Please do yourself a favor and do not retrace my steps - I tried that almost 20 years ago.
There is a better way
When you are done writing, just flush the output.
You can encapsulate this using classes or macros, so that no additional typing would be involved.
It is better for many reasons
Please note that the approach I suggest will make your code more readable - it will require you to specify your message boundaries explicitly.
Remember, you write code for others (and yourself 6 months from now!) to read, modify, and debug.
So, I finally found the problem (maybe bug??)
Form looks like this (SBCL API)
(run-program "sudo" '("mv" "foo.txt" "/usr/bin")
:search t
:output t
:input t
:wait t)
This works exactly how I wanted, problem was that instead of t in input and output args, I specified *standard-input* and *standard-output* which caused not proper working of command (if invoked program wanted some input from user like sudo for example).
No idea why, but at least, it works now.
I'm very new to unix programming, so please bear with me. :)
I'd like to pass data between two processes. I was going to use named pipes, but read about these "half-duplex" pipes, and it was very intriguing, so I figured that I would give them a try first.
I have two issues with these pipes thus far:
I haven't figured out how to get execlp to run another application from my child process
Even if I could, debugging is tough because I've only been able to set breakpoints in the parent process
I'm sure there are reasons for these issues. I am starting to wonder if it makes sense to just forget about them and just use named pipes so I can debug each application in a separate instance of eclipse.
If there is any relevant information, please let me know. The code I am using is essentially what it found on tldp.org.
EDIT -- I renamed my question to be about unix pipes in general. I had assumed that for named pipes, I wouldn't have to use fork(), but all of the examples I have seen so far require it. So regardless of half-duplex or named pipes, I'm going to need to be able to debug the child process somehow!
EDIT #2 -- this example clearly shows that what I had seen before (on an IBM link) regarding named pipes wasn't necessarily true.
I recommend two tools:
strace -ff should give you a trace of all significant events, allowing you to examine in detail what's going on, namely, all reads and writes;
lsof allows you to dump file descriptors of involved processes, clearly showing what is connected to what else and, in particular, if you forgot to close() some descriptors and the whole thing deadlocks.
another quick question, I want to make simple console based game, nothing too fancy, just to have some weekend project to get more familiar with C. Basically I want to make tetris, but I end up with one problem:
How to let the game engine go, and in the same time wait for input? Obviously cin or scanf is useless for me.
You're looking for a library such as ncurses.
Many Rogue-like games are written using ncurses or similar.
There's two ways to do it:
The first is to run two threads; one waits for input and updates state accordingly while the other runs the game.
The other (more common in game development) way is to write the game as one big loop that executes many times a second, updating game state, redrawing the screen, and checking for input.
But instead of blocking when you get key input, you check for the presence of pending keypresses, and if nothing has happened, you just continue through your loop. If you have multiple input sources (keyboard, network, etc.) they all get put there in the loop, checking one after another.
Yes, it's called polling. No, it's not efficient. But high-end games are usually all about pulling the maximum performance and framerates out of the computer, not running cool.
For added efficiency, you can optionally block with a timeout -- saying "wait for a keypress, but no longer than 300 milliseconds" so you can continue on with your loop.
select() comes to mind, but there are other ways of waiting or checking for input as well.
You could work out how to change stdin to non-blocking, which would enable you to write something like tetris, but the game might be more directly expressed in an event-driven paradigm. Maybe it's a good excuse to learn windows programming.
Anyway, if you want to go the console route, if you are using the microsoft compiler, then you should have kbhit() available (via conio.h) which can tell you whether a call to fgetc on stdin would block.
Actually should mention that the MinGW gcc compiler 3.4.5 also supports kbhit().
is there a way to implement multitasking using setjmp and longjmp functions
You can indeed. There are a couple of ways to accomplish it. The difficult part is initially getting the jmpbufs which point to other stacks. Longjmp is only defined for jmpbuf arguments which were created by setjmp, so there's no way to do this without either using assembly or exploiting undefined behavior. User level threads are inherently not portable, so portability isn't a strong argument for not doing it really.
step 1
You need a place to store the contexts of different threads, so make a queue of jmpbuf stuctures for however many threads you want.
Step 2
You need to malloc a stack for each of these threads.
Step 3
You need to get some jmpbuf contexts which have stack pointers in the memory locations you just allocated. You could inspect the jmpbuf structure on your machine, find out where it stores the stack pointer. Call setjmp and then modify its contents so that the stack pointer is in one of your allocated stacks. Stacks usually grow down, so you probably want your stack pointer somewhere near the highest memory location. If you write a basic C program and use a debugger to disassemble it, and then find instructions it executes when you return from a function, you can find out what the offset ought to be. For example, with system V calling conventions on x86, you'll see that it pops %ebp (the frame pointer) and then calls ret which pops the return address off the stack. So on entry into a function, it pushes the return address and frame pointer. Each push moves the stack pointer down by 4 bytes, so you want the stack pointer to start at the high address of the allocated region, -8 bytes (as if you just called a function to get there). We will fill the 8 bytes next.
The other thing you can do is write some very small (one line) inline assembly to manipulate the stack pointer, and then call setjmp. This is actually more portable, because in many systems the pointers in a jmpbuf are mangled for security, so you can't easily modify them.
I haven't tried it, but you might be able to avoid the asm by just deliberately overflowing the stack by declaring a very large array and thus moving the stack pointer.
Step 4
You need exiting threads to return the system to some safe state. If you don't do this, and one of the threads returns, it will take the address right above your allocated stack as a return address and jump to some garbage location and likely segfault. So first you need a safe place to return to. Get this by calling setjmp in the main thread and storing the jmpbuf in a globally accessible location. Define a function which takes no arguments and just calls longjmp with the saved global jmpbuf. Get the address of that function and copy it to your allocated stacks where you left room for the return address. You can leave the frame pointer empty. Now, when a thread returns, it will go to that function which calls longjmp, and jump right back into the main thread where you called setjmp, every time.
Step 5
Right after the main thread's setjmp, you want to have some code that determines which thread to jump to next, pulling the appropriate jmpbuf off the queue and calling longjmp to go there. When there are no threads left in that queue, the program is done.
Step 6
Write a context switch function which calls setjmp and stores the current state back on the queue, and then longjmp on another jmpbuf from the queue.
Conclusion
That's the basics. As long as threads keep calling context switch, the queue keeps getting repopulated, and different threads run. When a thread returns, if there are any left to run, one is chosen by the main thread, and if none are left, the process terminates. With relatively little code you can have a pretty basic cooperative multitasking setup. There are more things you probably want to do, like implement a cleanup function to free the stack of a dead thread, etc. You can also implement preemption using signals, but that is much more difficult because setjmp doesn't save the floating point register state or the flags registers, which are necessary when the program is interrupted asynchronously.
It may be bending the rules a little, but GNU pth does this. It's possible, but you probably shouldn't try it yourself except as an academic proof-of-concept exercise, use the pth implementation if you want to do it seriously and in a remotely portable fashion -- you'll understand why when you read the pth thread creation code.
(Essentially it uses a signal handler to trick the OS into creating a fresh stack, then longjmp's out of there and keeps the stack around. It works, evidently, but it's sketchy as hell.)
In production code, if your OS supports makecontext/swapcontext, use those instead. If it supports CreateFiber/SwitchToFiber, use those instead. And be aware of the disappointing truth that one of the most compelling use of coroutines -- that is, inverting control by yielding out of event handlers called by foreign code -- is unsafe because the calling module has to be reentrant, and you generally can't prove that. This is why fibers still aren't supported in .NET...
This is a form of what is known as userspace context switching.
It's possible but error-prone, especially if you use the default implementation of setjmp and longjmp. One problem with these functions is that in many operating systems they'll only save a subset of 64-bit registers, rather than the entire context. This is often not enough, e.g. when dealing with system libraries (my experience here is with a custom implementation for amd64/windows, which worked pretty stable all things considered).
That said, if you're not trying to work with complex external codebases or event handlers, and you know what you're doing, and (especially) if you write your own version in assembler that saves more of the current context (if you're using 32-bit windows or linux this might not be necessary, if you use some versions of BSD I imagine it almost definitely is), and you debug it paying careful attention to the disassembly output, then you may be able to achieve what you want.
I did something like this for studies.
https://github.com/Kraego/STM32L476_MiniOS/blob/main/Usercode/Concurrency/scheduler.c
The context/thread switching is done by setjmp/longjmp. The difficult part was to get the allocated stack correct (see allocateStack()) this depends on your platform.
This is just a demonstration how this could work, I would never use this in production.
As was already mentioned by Sean Ogden,
longjmp() is not good for multitasking, as
it can only move the stack upward and can't
jump between different stacks. No go with that.
As mentioned by user414736, you can use getcontext/makecontext/swapcontext
functions, but the problem with those is that
they are not fully in user-space. They actually
call the sigprocmask() syscall because they switch
the signal mask as part of the context switching.
This makes swapcontext() much slower than longjmp(),
and you likely don't want the slow co-routines.
To my knowledge there is no POSIX-standard solution to
this problem, so I compiled my own from different
available sources. You can find the context-manipulating
functions extracted from libtask here:
https://github.com/dosemu2/dosemu2/tree/devel/src/base/lib/mcontext
The functions are:
getmcontext(), setmcontext(), makemcontext() and swapmcontext().
They have the similar semantic to the standard functions with similar names,
but they also mimic the setjmp() semantic in that getmcontext()
returns 1 (instead of 0) when jumped to by setmcontext().
On top of that you can use a port of libpcl, the coroutine library:
https://github.com/dosemu2/dosemu2/tree/devel/src/base/lib/libpcl
With this, it is possible to implement the fast cooperative user-space
threading. It works on linux, on i386 and x86_64 arches.
Let's say you have a function foo() compiled into a program that is running on Unix.
While the program is running, can one "replace" the function foo by dynamically loading an object file containining a modified version of foo()?
On an embedded system I worked on in the past, we could unprotect the text segment and then essentially "patch" the address of foo() to point to the newly modified foo().
It was used for debugging on occasion and with lots of special constraints, on customer sites.
Is this possible on Unix?
It depends on the environment, I suppose. I know that hot-swapping production code is trivial in Erlang modules and not too difficult in Ruby. C might be a different animal.
Yes. That's how debuggers like gdb work, after all.
The short of it is yes, of course it's possible. The question should really be, "how difficult?"
You can load & unload shared libraries (.so & .DLL) all you want on Linux & Windows. Specific variants of UNIX, I'm not sure about. This would be the easiest way to achieve your goal.
If you don't mind getting your hands dirty, you can always patch up the code segment to jump to someplace else out on the heap. I don't recommend it.