Difference between revisions of "Tutorials/C Programming Tutorial/Syscall.cpp"

From ThorstensHome
Jump to: navigation, search
Line 1: Line 1:
You are here: [[Main Page]] -> [[My Tutorials]] -> [[Programming Tutorials]] -> [[C Programming Tutorial]] -> [[Syscall.cpp]]
+
{{DISPLAYTITLE:Syscall.cpp}}
  
 
This chapter demonstrates how to do a [http://en.wikipedia.org/wiki/Syscall syscall] with Linux. A syscall in POSIX systems is according to [http://www.wikipedia.org wikipedia] e.g. open, read, write, close, wait, exec, fork, exit, and kill. There is a list of all syscalls to be found at /usr/include/bits/syscall.h (don't #include bits/syscall.h as stated in the file). A program to display all syscalls from a program is strace.
 
This chapter demonstrates how to do a [http://en.wikipedia.org/wiki/Syscall syscall] with Linux. A syscall in POSIX systems is according to [http://www.wikipedia.org wikipedia] e.g. open, read, write, close, wait, exec, fork, exit, and kill. There is a list of all syscalls to be found at /usr/include/bits/syscall.h (don't #include bits/syscall.h as stated in the file). A program to display all syscalls from a program is strace.

Revision as of 05:30, 11 May 2009


This chapter demonstrates how to do a syscall with Linux. A syscall in POSIX systems is according to wikipedia e.g. open, read, write, close, wait, exec, fork, exit, and kill. There is a list of all syscalls to be found at /usr/include/bits/syscall.h (don't #include bits/syscall.h as stated in the file). A program to display all syscalls from a program is strace.

Contents

open

syscall.cpp

#include <stdio.h>
#include <fcntl.h>

int main()
{
  open("/tmp/test",5);
  printf("hallo");
}

Compile, link and run it

g++ -o syscall syscall.cpp && ./syscall

Now we want to see if the program really calls open, so we strace it:

strace ./syscall

And we indeed find

open("/tmp/test", O_WRONLY|0x4 /* O_??? */) = -1 ENOENT (No such file or directory)
fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 3), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f8f48d78000
write(1, "hallo", 5hallo)                    = 5
exit_group(0)

write

In the above output from strace, we have seen a write syscall. We want to call it as well, so we issue

man 2 write

and read that stuff a bit. Then we change syscall.cpp to be like

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
  open("/tmp/test",5);
  printf("hallo");
  write(1,"hallo",5);
}

Compile, link and run it again

g++ -o syscall syscall.cpp && ./syscall

And find it works, because it does a write after the printf:

tweedleburg:~/test # g++ -o syscall syscall.cpp && ./syscall
hallohallotweedleburg:~/test #

Congratulations, you can now go on on your own using strace further.

lock

Now we are marching straightly towards contention testing. We implement a lock and append a string. Appending requires us according to http://linux.die.net/man/2/open that we use the mode O_APPEND, but not alone, but in combination, e.g. with O_WRONLY:

#include <stdio.h>
#include <fcntl.h>
#include <sys/file.h>
#include <unistd.h>

int main()
{
  int handle=open("/mnt/sdc/test",O_WRONLY|O_APPEND);
  flock(handle,LOCK_EX);
  write(handle, "this is awriter",14);
  flock(handle,LOCK_UN);
  close(handle);
}

Compile, link and run it again

g++ -o syscall syscall.cpp && ./syscall

reboot

This shows how to use the syscall reboot.

#include <unistd.h>
#include <sys/reboot.h>
#include <iostream>

using namespace std;

int main()
{
  cout << "Trying a reboot" << endl;
  reboot(0x1234567);
}

sched_setaffinity

Sched_setaffinity is a syscall that sets a processor's affinity to run on a given processor. Example: You have 4 processor cores and want your process to run only on core 2 - then use this program. The benefit is that - depending on your architecture - cache usage can be optimized if two processes run on the same (or another) processor. You may gain performance by setting the processor affinity.

main.cpp

#include <sched.h>
#include <iostream>
#include <stdlib.h>

using namespace std;

int main (int argc, char* argv[])
{
  int pid=atoi(argv[1]);
  cpu_set_t mask;
  unsigned int len = sizeof(mask);
  CPU_ZERO(&mask);
  CPU_SET(0,&mask);
  cout << "cpu settings: " << CPU_ISSET(0,&mask) << CPU_ISSET(1,&mask);
  cout << CPU_ISSET(2,&mask) << CPU_ISSET(3,&mask) << endl;
  sched_setaffinity(pid, len, &mask);
}

Compile and link

g++ -o sched_setaffinity main.cpp

Example usage

tweedleburg:~/sched # while true; do i=5; done &
[1] 28546

Now start xosview and watch that one processor is full loaded.

tweedleburg:~/sched # ./sched_setaffinity 28546
cpu settings: 1000

Now see in xosview that the fully loaded processor is the first one.

See also