Sysprog 12
Upcoming SlideShare
Loading in...5
×
 

Sysprog 12

on

  • 1,207 views

 

Statistics

Views

Total Views
1,207
Views on SlideShare
1,205
Embed Views
2

Actions

Likes
0
Downloads
9
Comments
0

2 Embeds 2

http://www.slideshare.net 1
http://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Sysprog 12 Sysprog 12 Presentation Transcript

    • C/C++ Linux System Programming
        • Session 12
        • User-space System Programming
        • – session 2
    • Outline
      • Signals
      • Job Control
      • Scheduling
      • IPC Intro
    • Sending Signals
      • int kill(pid_t pid, int sig);
      • int raise(int sig); // = kill(getpid(), sig);
      • int sigqueue(pid_t pid, int sig, const union sigval value); // value is a payload (IPC w/data!!)
    • Handling Signals – old school
      • Handler
        • typedef void (*sighandler_t)(int);
        • sighandler_t signal(int signum, sighandler_t handler);
        • SIG_IGN / SIG_DFL
        • Example from sshd.c:
      static void main_sigchld_handler(int sig) { int save_errno = errno; pid_t pid; int status; while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || (pid < 0 && errno == EINTR)) ; signal(SIGCHLD, main_sigchld_handler); errno = save_errno; }
    • Signal sets
        • int sigemptyset(sigset_t *set); // Init
        • int sigfillset(sigset_t *set); // Init with all
        • int sigaddset(sigset_t *set, int signum);
        • int sigdelset(sigset_t *set, int signum);
        • int sigismember(const sigset_t *set, int signum);
        • Non-POSIX:
          • int sigisemptyset (sigset_t *set);
          • int sigorset (sigset_t *dest, sigset_t *left, sigset_t *right);
          • int sigandset (sigset_t *dest, sigset_t *left, sigset_t *right);
    • Masking
      • Mask/Unmask
        • int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
        • how: SIG_BLOCK/SIG_UNBLOCK/SIG_SETMASK
      • Check pending (temporarily masked)
        • int sigpending(sigset_t *set);
      • Waiting for a signal
        • int pause(void);
        • int sigsuspend(const sigset_t *mask);
    • Masking Example - ssh/server_loop.c /* block SIGCHLD while we check for dead children */ sigemptyset(&nset); sigaddset(&nset, SIGCHLD); sigprocmask(SIG_BLOCK, &nset, &oset); if (child_terminated) { debug(&quot;Received SIGCHLD.&quot;); while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || (pid < 0 && errno == EINTR)) if (pid > 0) session_close_by_pid(pid, status); child_terminated = 0; } sigprocmask(SIG_SETMASK, &oset, NULL); }
    • Versatile Signal Handling Interface
      • int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
      • Important sigaction fields:
        • void (*sa_handler)(int);
        • void (*sa_sigaction)(int, siginfo_t *, void *);
        • sigset_t sa_mask;
      • Important siginfo_t:
        • si_signo , si_uid, si_value, si_addr
    • Example - inetd memset(&sa, 0, sizeof(sa)); sigaddset(&sa.sa_mask, SIGALRM); sigaddset(&sa.sa_mask, SIGCHLD); sigaddset(&sa.sa_mask, SIGHUP); sa.sa_handler = retry_network_setup; sigaction_set(SIGALRM, &sa); sa.sa_handler = reread_config_file; sigaction_set(SIGHUP, &sa); sa.sa_handler = reap_child; sigaction_set(SIGCHLD, &sa); sa.sa_handler = clean_up_and_exit; sigaction_set(SIGTERM, &sa); sa.sa_handler = clean_up_and_exit; sigaction_set(SIGINT, &sa); sa.sa_handler = SIG_IGN; sigaction(SIGPIPE, &sa, &saved_pipe_handler); static void clean_up_and_exit(int sig UNUSED_PARAM){ ,,,, remove_pidfile(_PATH_INETDPID); exit(EXIT_SUCCESS); } int FAST_FUNC sigaction_set(int signum, const struct sigaction *act){ return sigaction(signum, act, NULL); }
    • Some Signal Notes
      • Behavior in fork
      • Behavior in exec
      • Process Group relevance
      • System call interruptions
      • Intro to race conditions
        • Critical region
        • Reentrancy
        • Minimal work
        • Sigatomic_t
    • system/popen
      • fork/exec (/bin/sh)
      • Security hole
      • Signal blocking
    • Scheduling
      • Time-sharing (timeslices)
      • States
      • Process table
      • Context switch
      • Priorities
      • Preemptive vs Cooperative Multitasking
      • Idle process
    • 2.4 Scheduling
      • Nice values
        • [-20,19], -20 is not nice, i.e. high priority
        • Time slice length & run queue order
        • Superuser to decrement
      • int nice(int inc); // nice(0) is current
      • get/set priority
        • int getpriority (int which, int who);
        • int setpriority (int which, int who, int prio);
        • Absolute
        • PRIO_RPOCESS, PRIO_PGRP, PRIO_USER
    • Relinquishing CPU
        • int sched_yield
          • why?
          • 2.4 vs 2.6 (RT vs non-RT)
        • Sleep
          • unsigned int sleep(unsigned int seconds);
          • int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
          • int usleep(useconds_t usec);
    • Real-time Scheduling
      • Real-time - soft/hard
        • determinism
      • Priorities: 1-99, 0 non-RT
      • Scheduling classes
        • Round-robin
        • FIFO
      • Chrt
      • Be “nice” !!!
      struct sched_param { /* ... */ int sched_priority; /* ... */ }; int sched_getparam (pid_t pid, struct sched_param *sp); int sched_setparam (pid_t pid, const struct sched_param *sp);
    • Processor Affinity
      • SMP
      • Affinity: Which processor?
        • By default, try the same and hereditary
      • Do I care? -- Cache coherency
      • Do I really care?
        • http://www.linuxjournal.com/article/6799
      pid = atol(argv[1]); sscanf(argv[2], &quot;%08lx&quot;, &new_mask); if (sched_getaffinity(pid, len, &cur_mask) < 0) { perror(&quot;sched_getaffinity&quot;); return -1; } printf(&quot;pid %d's old affinity: %08lx &quot;, pid, cur_mask); if (sched_setaffinity(pid, len, &new_mask)) { perror(&quot;sched_setaffinity&quot;); return -1; } if (sched_getaffinity(pid, len, &cur_mask) < 0) { perror(&quot;sched_getaffinity&quot;); return -1; }
    • Time
      • Monotonic time / real time / process time
      • POSIX
        • int clock_getres(clockid_t clk_id, struct timespec *res);
        • int clock_gettime(clockid_t clk_id, struct timespec *tp);
        • int clock_settime(clockid_t clk_id, const struct timespec *tp);
    • System time
      • get/set
        • int gettimeofday(struct timeval *tv, struct timezone *tz);
        • int settimeofday(const struct timeval *tv, const struct timezone *tz);
        • time_t time(time_t *t); // seconds
      • Printable
        • char *ctime(const time_t *timep); //And family
      • int adjtime(const struct timeval *delta, struct timeval *olddelta);
    • Examples from NTP gettimeofday(&tv, 0); epoch = tv.tv_sec; ... fprintf(stdout, &quot;# %s # %s&quot;, filename, ctime(&epoch)); curtime = time(0); printf(&quot;Starting: %s&quot;, ctime(&curtime));
    • Interval Timers
      • Set a timer
      • Signal when expired
      int getitimer(int which, struct itimerval *value); int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue); struct itimerval { struct timeval it_interval; /* next value */ struct timeval it_value; /* current value */ }; struct timeval { long tv_sec; /* seconds */ long tv_usec; /* microseconds */ }; unsigned int alarm(unsigned int seconds);
    • Example – ping.c static void noresp(int ign UNUSED_PARAM) { printf(&quot;No response from %s &quot;, hostname); exit(EXIT_FAILURE); } main() { ... signal(SIGALRM, noresp); alarm(5); /* give the host 5000ms to respond */ ... }
    • IPC Intro
      • Share data
      • Synchronize
      • Mutual Exclusion
        • Critical region
        • Semaphores