0% found this document useful (0 votes)
14 views21 pages

Lab4 Scheduling

This document discusses multi-tasking and scheduling in operating systems. It describes different multi-threading models and scheduling subsystems. It also outlines various programming interfaces for multi-tasking like fork(), pthreads, signals, and the BK task pool API. The document provides details on the Linux scheduler Cron and practices for implementing a multi-tasking framework.

Uploaded by

Huy Lâm
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
14 views21 pages

Lab4 Scheduling

This document discusses multi-tasking and scheduling in operating systems. It describes different multi-threading models and scheduling subsystems. It also outlines various programming interfaces for multi-tasking like fork(), pthreads, signals, and the BK task pool API. The document provides details on the Linux scheduler Cron and practices for implementing a multi-tasking framework.

Uploaded by

Huy Lâm
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 21

HCMC University Of Technology

Faculty of Computer Science & Engineering

Lab 4
Multi-tasking and Scheduler activations
Course: Operating Systems

April 1, 2024

Goal This lab helps the student practice scheduler activation in multi-tasking context (process or thread
based implementation), and figure out why we need the multi-task management framework.

Contents In detail, this lab requires the student practice experiments using scheduler activation to
provide the multi-tasking environment:

• CPU scheduler

• Dispatcher

• Scheduler policy description (using crontab)

Besides, the practices include the implementation of self-setup multi-tasking framework called bktpool
(BK task pool). In addition to support implicit threading technique, we might cover further model of
creation and management of threads i.e. fork-join, OpenMP (or CUDA), Grand Central Dispatch, Thread
Building Block etc.

Result After doing this lab, student can understand the framework of multi-tasking using the techniques
above to provide the scheduling feature.

Requirements Student need to review the theory of multi-tasking and scheduling.

1
CONTENTS CONTENTS

Contents
1 Background 3
1.1 Multi-tasking environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Scheduling subsystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2 Programming Interfaces 6
2.1 Multi-task programming interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.1.1 fork() API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.1.2 pthread create API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.1.3 clone() API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2 Signal handler API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2.1 kill and tkill . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2.2 sigwait() API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2.3 sigaction() API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.3 BK TaskPool API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.3.1 Task declaration API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.3.2 Task Pool Usage API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.4 A Linux Scheduler - Cron . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.4.1 Introduction to Cron . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.4.2 Crontab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.4.3 Crontab Syntax and Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.4.4 Linux Crontab Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

3 Practices 13
3.1 Multitasking framework illustration BK TPool . . . . . . . . . . . . . . . . . . . . . . . . 13
3.1.1 Create a set of resource entities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.1.2 CPU scheduler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.1.3 Dispatcher . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.1.4 Finalize task pool and resource worker . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.2 Practice with CronTab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

4 Exercise 20

2
1 BACKGROUND

1 Background
1.1 Multi-tasking environment
Multicore or multiprocessor systems putting pressure on programmers, challenges include:

• Dividing activities

• Balance

• Data splitting

• Data dependency

• Testing and debugging

The task is an abstract entity to quantitize the CPU computation power. We can implement it using
the both concepts introduced in the first few chapter of Operating System course include process creating
with fork system call or thread creating with thread library such as POSIX Thread (aka pthread). Despite
of the comfortable of using the provided library, thread has a long history of development from userspace
(down) to kernel space.

When the thread are placed in userspace or the legacy code, the mapping model is N:1 in which
multiple thread is mapped in to one kernel thread and the scheduler has to decide which user thread are
dispatch to take owner the computation resource. In this work, we deal with the same problem as the
legacy thread library. We develop a scheduling subsystem to deploy multi-task on top a limit hardware
computation resource.

There are some other concerned approaches in multi-tasking framework development:

Control using Signals are used in UNIX systems to notify a process that a particular event has
occurred.

Communication using Shared memory or Message passing

Resouce sharing management Scheduling subsystem

Multithreading model

Many-to-one Many user-level threads mapped to single kernel thread

• One thread blocking causes all to block

• Multiple threads may not run in parallel on multicore system.

• Example system GNU Portable Thread (Few system currently use this model)

3
1.2 Scheduling subsystem 1 BACKGROUND

One-to-one Each user-level thread maps to one kernel thread

• Creating a user-level thread creates a kernel thread

• Number of threads per process sometimes restricted due to overhead.

• Example systems: Window, Linux

Mnay-to-many Allows many user level threads to be mapped to many kernel threads

• Allows the operating system to create a sufficient number of kernel threads

• Example system: Windows with the ThreadFiber package (Otherwise not very common)

• Example systems: Window, Linux

Figure 1: Multi-threading Model

The thread issues include:

• Semantics of fork() and exec() system calls

• Signal handling

– Synchronous and asynchronous

• Thread cancellation of target thread

– Asynchronous or deferred

• Thread-local storage

• Scheduler Activations

1.2 Scheduling subsystem


The CPU scheduler selects one process from among the processes in ready queue, and allocates the
CPU core to it

4
1.2 Scheduling subsystem 1 BACKGROUND

Dispatcher module gives control of the CPU to the process selected by the short-term scheduler; this
involves:

Figure 2: The two components of scheduling system

5
2 PROGRAMMING INTERFACES

2 Programming Interfaces
2.1 Multi-task programming interface
2.1.1 fork() API

creates a new process by duplicating the calling process. The new process, referred to as the child, is an
exact duplicate of the calling process, referred to as the parent
#include <u n i s t d . h>
p i d t f o r k ( void )

2.1.2 pthread create API

creates a new thread start by a predeclared function in the calling process.


int p t h r e a d c r e a t e ( p t h r e a d t ∗ thread , const p t h r e a d a t t r t ∗ a t t r ,
void ∗ ( ∗ s t a r t r o u t i n e ) ( void ∗ ) , void ∗ a r g ) ;

Notice: Compile and link with -pthread.

2.1.3 clone() API

The system call is the backend for both fork() API and pthread create() API. clone() creates a new
process, in a manner similar to fork(2). It is actually a library function layered on top of the underlying
clone() system call. The superior of system call clone is the backend to provide a thread creation inside
a thread. Pthread create() is so-called a wrapper of system call clone().

(From the clone user manual)

CLONE THREAD (since Linux 2.4.0-test8) If CLONE THREAD is set, the child is placed in the
same thread group as the calling process. To make the remainder of the discussion of CLONE THREAD
more readable, the term ”thread” is used to refer to the processes within a thread group. Thread groups
were a feature added in Linux 2.4 to support the POSIX threads notion of a set of threads that share
a single PID. Internally, this shared PID is the so-called thread group identifier (TGID) for the thread
group.
#define GNU SOURCE
#include <s c h e d . h>

int c l o n e ( int ( ∗ f n ) ( void ∗ ) , void ∗ s t a c k , int f l a g s , void ∗ arg , . . .


/∗ p i d t ∗ p a r e n t t i d , v o i d ∗ t l s , p i d t ∗ c h i l d t i d ∗/ )

2.2 Signal handler API


2.2.1 kill and tkill

The set of system call support sending a signal to a thread or process


The kill() system call can be used to send any signal to any process group or process.

6
2.3 BK TaskPool API 2 PROGRAMMING INTERFACES

The tgkill() system call sends the signal sig to the thread with the thread ID tid in the thread group
tgid. The tkill() is an obsolete predecessor to tgkill(). It allows only the target thread ID to be specified,
which may result in the wrong thread being signaled if a thread terminates and its thread ID is recycled.
Avoid using this system call.
#include <s i g n a l . h>

int k i l l ( p i d t pid , int s i g ) ;


-----------------------------------------
#include <s i g n a l . h> /∗ D e f i n i t i o n o f SIG∗ c o n s t a n t s ∗/
#include <s y s / s y s c a l l . h> /∗ D e f i n i t i o n o f SYS ∗ c o n s t a n t s ∗/
#include <u n i s t d . h>

int s y s c a l l ( S Y S t k i l l , p i d t t i d , int s i g ) ;
-----------------------------------------
#include <s i g n a l . h>

int t g k i l l ( p i d t t g i d , p i d t t i d , int s i g ) ;

2.2.2 sigwait() API

The function suspends execution of the calling thread until one of the signals specified in the signal set
set becomes pending. The function accepts the signal (removes it from the pending list of signals), and
returns the signal number in sig.
#include <s i g n a l . h>

int s i g w a i t ( const s i g s e t t ∗ r e s t r i c t s e t , int ∗ r e s t r i c t s i g ) ;

2.2.3 sigaction() API

The system call is used to change the action taken by a process on receipt of a specific signal.
#include <s i g n a l . h>

int s i g a c t i o n ( int signum , const struct s i g a c t i o n ∗ r e s t r i c t act ,


struct s i g a c t i o n ∗ r e s t r i c t o l d a c t ) ;

2.3 BK TaskPool API


2.3.1 Task declaration API

Task definition requires a job execution function. We share almost the same API with other library by
defining task init include the 2 information of what function task will be executed and the argument to
passing to the function.
int b k t a s k i n i t ( int ∗ t a s k i d , void ∗ ( ∗ s t a r t r o u t i n e ) ( void ∗ ) , void ∗ a r g ) ;

7
2.3 BK TaskPool API 2 PROGRAMMING INTERFACES

An example of new task declarations:


int f u n c ( void ∗ a r g )
{
int i d = ∗ ( ( int ∗ ) a r g ) ;

p r i n t f ( ” Task f u n c - H e l l o from %d\n” , i d ) ;


f f l u s h ( stdout ) ;

return 0 ;
}

int main ( )
{
...
id [ 0 ] = 1; b k t a s k i n i t (& t i d [ 0 ] , &func , ( void ∗ )& i d [ 0 ] ) ;
id [ 1 ] = 2; b k t a s k i n i t (& t i d [ 0 ] , &func , ( void ∗ )& i d [ 1 ] ) ;
id [ 2 ] = 5; b k t a s k i n i t (& t i d [ 0 ] , &func , ( void ∗ )& i d [ 2 ] ) ;
...
}

2.3.2 Task Pool Usage API

Defined task is passed to assigned worker and is dispatched to be executed.


#include ” b k t p o o l . h”

int b k w r k g e t w o r k e r ( ) ;
-------------------
int b k t a s k a s s i g n w o r k e r ( int b k t a s k i d , int wrkid ) ;
-------------------
int b k w r k d i s p a t c h w o r k e r ( int wrkid ) ;

An example of using Task Pool API


int main ( )
...
wid [ 1 ] = b k w r k g e t w o r k e r ( ) ;
r e t = b k t a s k a s s i g n w o r k e r ( t i d [ 0 ] , wid [ 1 ] ) ;
i f ( r e t != 0 )
p r i n t f ( ” a s s i g n t a s k f a i l e d t i d=%d wid=%d\n” , t i d [ 0 ] , wid [ 1 ] ) ;

b k w r k d i s p a t c h w o r k e r ( wid [ 1 ] ) ;
...
}

8
2.4 A Linux Scheduler - Cron 2 PROGRAMMING INTERFACES

Figure 3: The calling procedure of BK Task Pool’s routines

2.4 A Linux Scheduler - Cron


2.4.1 Introduction to Cron

Cron is a scheduling daemon that executes tasks at specified intervals. These tasks are called cron jobs
and are mostly used to automate system maintenance or administration.

For example, we can set up a cron job to automate repetitive tasks such as backing up databases or
data, updating the system with the latest security patches, checking disk space usage, sending emails, etc.

The cron jobs can be scheduled to run by a minute, hour, day of the month, month, day of the week, or
any combination of these. For Ubuntu, we can inspect the cron service by running the following command:

$ sudo systemctl status cron . s e r v i c e

In the case there is an error of "command not found", you need to check and install the package from
the repository
# Verify the existance of the required package
$ sudo dpkg - l | grep systemd
i i libpam - systemd : amd64 system and s e r v i c e manager - PAM module
i i libsystemd - daemon0 : amd64 systemd u t i l i t y l i b r a r y
i i libsystemd - login0 : amd64 systemd login u t i l i t y l i b r a r y
i i systemd - s e r v i c e s systemd runtime s e r v i c e s
i i systemd - shim shim for systemd

# I n s t a l l the package ”systemd”


$ sudo apt - get i n s t a l l systemd

# When the package i s i n s t a l l e d , the command i s working now:


$ sudo systemctl status cron . s e r v i c e
cron . s e r v i c e
Loaded : e r r o r ( Reason : No such f i l e or d i r e c t o r y )
Active : i n a c t i v e ( dead )

9
2.4 A Linux Scheduler - Cron 2 PROGRAMMING INTERFACES

Figure 4: Cron Cycle

2.4.2 Crontab

Crontab (cron table) is a text file that specifies the schedule of cron jobs. There are two types of crontab
files. The system-wide crontab files and individual user crontab files. Users’ crontab files are named ac-
cording to the user’s name, and their location is at the /var/spool/cron/crontabs directory on Ubuntu.
The /etc/crontab file and the scripts inside the /etc/cron.d directory are system-wide crontab files
that can be edited only by the system administrators.

Fgure 4 describes the cron cycle. Cron will inspect the user defined cron jobs and execute them if
needed. It will also inspect the crontab file where several default cron jobs are defined by default.

Those default cron jobs are scripts that instructs your host to verify every minute, every hour, every
day and every week specific folders and to execute the scripts that are inside them.

10
2.4 A Linux Scheduler - Cron 2 PROGRAMMING INTERFACES

Finally, the cron.d directory is inspected. The cron.d may contain custom cron files and it also
contains a very important file which is the anacron cron file.

2.4.3 Crontab Syntax and Operators

Each line in the user crontab file contains six fields separated by a space followed by the command to be
run:
∗ ∗ ∗ ∗ ∗ command( s ) output
- - - - -
| | | | |
| | | | - - - - - Day of week (0 - 7) (Sunday=0 or 7) (Mon - Sun)
| | | - - - - - - - Month (1 - 12)
| | - - - - - - - - - Day of month (1 - 31)
| - - - - - - - - - - - Hour (0 - 23)
- - - - - - - - - - - - - Minute (0 - 59)

The detail of a cron command are:

• The first five fields * * * * * specify the time/date and recurrence of the job.

• In the second section, the command specifies the location and script you want to run.

• The final segment output is optional. It defines how the system notifies the user of the job comple-
tion. Cron will issue an email if there is any output from the cron job. Cron jobs are meant to not
produce any output if everything is ok.

The first five fields may contain one or more values, separated by a comma or a range of values
separated by a hyphen.

• “*” - The asterisk operator means any value or always. If you have the asterisk symbol in the Hour
field, it means the task will be performed each hour.

• “,” - The comma operator allows you to specify a list of values for repetition. For example, if you
have 1,3,5 in the Hour field, the task will run at 1 am, 3 am, and 5 am.

• ”-” The hyphen operator allows you to specify a range of values. If you have 1-5 in the Day of the
week field, the task will run every weekday (From Monday to Friday).

• “/” - The slash operator allows you to specify values that will be repeated over a certain interval
between them. For example, if you have */4 in the Hour field, it means the action will be performed
every four hours. It is same as specifying 0,4,8,12,16,20. Instead of an asterisk before the slash
operator, you can also use a range of values, 1-30/10 means the same as 1,11,21.

There are several special Cron schedule macros used to specify common intervals. We can use these
shortcuts in place of the five-column date specification:

• @yearly (or @annually) - Run the specified task once a year at midnight (12:00 am) of the 1st of
January. Equivalent to 0 0 1 1 *.

11
2.4 A Linux Scheduler - Cron 2 PROGRAMMING INTERFACES

• @monthly - Run the specified task once a month at midnight on the first day of the month. Equiv-
alent to 0 0 1 * *.

• @weekly - Run the specified task once a week at midnight on Sunday. Equivalent to 0 0 * * 0.

• @daily - Run the specified task once a day at midnight. Equivalent to 0 0 * * *.

• @hourly - Run the specified task once an hour at the beginning of the hour. Equivalent to 0 * *
* *.

• @reboot - Run the specified task at the system startup (boot-time).

Example:

1. 10 10 1 * * /path/to/script.sh: A cron job that executes every 10:10 AM each month on the
first day.

2. 23 0-23/2 * * * /path/to/scripts.sh: Execute the script.sh at 23 minutes after midnight, 2


am, 4 am. . . , everyday

Exercise: Convert the following intervals to crontab presentation:

• Every Monday at 08:30

• Every workday, every 30 minutes, from 8:15 to 17:45

• Last day of every month at 17:30

2.4.4 Linux Crontab Command

The crontab command allows you to install, view, or open a crontab file for editing:

• crontab -e - Edit crontab file, or create one if it doesn’t already exist.

• crontab -l - Display crontab file contents.

• crontab -r - Remove your current crontab file.

• crontab -i - Remove your current crontab file with a prompt before removal.

• crontab -u <username> - Edit other user crontab file. This option requires system administrator
privileges.

The cron daemon automatically sets several environment variables::

• The default path is set to PATH=/usr/bin:/bin. If the command you are executing is not present
in the cron-specified path, you can either use the absolute path to the command or change the cron
PATH variable. You can’t implicitly append PATH as you would do with a regular script.

• The default shell is set to /bin/sh. To change to a different shell, use the SHELL variable.

• Cron invokes the command from the user’s home directory. The HOME variable can be set in the
crontab.

12
3 PRACTICES

3 Practices
In this section, we work on step by step building up a multi-task framework.

3.1 Multitasking framework illustration BK TPool


The task pool implement follows the below steps:

3.1.1 Create a set of resource entities

#include < s i g n a l . h>


#include <s t d i o . h>

#d e f i n e GNU SOURCE
#include <l i n u x / s c h e d . h>
#include <s y s / s y s c a l l . h> /∗ D e f i n i t i o n o f SYS ∗ c o n s t a n t s ∗/
#include <u n i s t d . h>
#d e f i n e INFO
#d e f i n e WORK THREAD

int bkwrk create worker ( )


{
unsigned i n t i ;

f o r ( i = 0 ; i < MAX WORKER; i ++)


{
#i f d e f WORK THREAD
void ∗∗ c h i l d s t a c k = ( void ∗ ∗ ) m a l l o c ( STACK SIZE ) ;
unsigned i n t w r k i d = i ;
pthread t threadid ;

sigset t set ;
int s ;

s i g e m p t y s e t (& s e t ) ;
s i g a d d s e t (& s e t , SIGQUIT ) ;
s i g a d d s e t (& s e t , SIGUSR1 ) ;
s i g p r o c m a s k ( SIG BLOCK , &s e t , NULL ) ;

/∗ S t a c k g r o w down - s t a r t a t t o p ∗/
void ∗ s t a c k t o p = c h i l d s t a c k + STACK SIZE ;

w r k i d t i d [ i ] = c l o n e (& bk w r k w o rk e r , s t a c k t o p ,
CLONE VM| CLONE FILES ,
( void ∗ ) &i ) ;
#i f d e f INFO
f p r i n t f ( s t d e r r , ” b k w r k c r e a t e w o r k e r g o t w o r k e r %u\n” , wrkid tid [ i ] ) ;
#e n d i f

usleep (100);

#e l s e
int bkwrk create worker ( )
{
unsigned i n t i ;

f o r ( i = 0 ; i < MAX WORKER; i ++)


{
#i f d e f WORK THREAD
void ∗∗ c h i l d s t a c k = ( void ∗ ∗ ) m a l l o c ( STACK SIZE ) ;
unsigned i n t w r k i d = i ;
pthread t threadid ;

sigset t set ;
int s ;

s i g e m p t y s e t (& s e t ) ;
s i g a d d s e t (& s e t , SIGQUIT ) ;
s i g a d d s e t (& s e t , SIGUSR1 ) ;
s i g p r o c m a s k ( SIG BLOCK , &s e t , NULL ) ;

/∗ S t a c k g r o w down - s t a r t a t t o p ∗/
void ∗ s t a c k t o p = c h i l d s t a c k + STACK SIZE ;

w r k i d t i d [ i ] = c l o n e (& bk w r k w o rk e r , s t a c k t o p ,
CLONE VM| CLONE FILES ,
( void ∗ ) &i ) ;
#i f d e f INFO
f p r i n t f ( s t d e r r , ” b k w r k c r e a t e w o r k e r g o t w o r k e r %u\n” , wrkid tid [ i ] ) ;
#e n d i f

13
3.1 Multitasking framework illustration BK TPool 3 PRACTICES

usleep (100);

#e l s e

Step 3.1.1 Create resoruce instance using thread or process technique. The two kinds of instance can
be initialized using the system call clone() or the wrapped library function fork() and pthread create().
Step 3.1.2 Set up the control signal masking with allowance of the two signal SIGQUIT or SIGUSR1.

3.1.2 CPU scheduler

int b k w r k g e t w o r k e r ( )
{
w r k i d b u s y [ 1 ] != 0 ;

return 1 ;

/∗ TODO Implement t h e s c h e d u l e r t o s e l e c t t h e r e s o u r c e e n t i t y ∗/
}

3.1.3 Dispatcher

Assign worker a assign a task to a worker


int b k t a s k a s s i g n w o r k e r ( unsigned int b k t a s k i d , unsigned int wrkid )
{
i f ( wrkid < 0 | | wrkid > MAXWORKER)
return - 1 ;

struct b k t a s k t ∗ t s k = b k t a s k g e t b y i d ( b k t a s k i d ) ;

i f ( t s k == NULL)
return - 1 ;

/∗ A d v e r t i s e I AM WORKING ∗/
w r k i d b u s y [ wrkid ] = 1 ;

worker [ wrkid ] . f u n c = t s k ->f u n c ;


worker [ wrkid ] . a r g = t s k ->a r g ;
worker [ wrkid ] . b k t a s k i d = b k t a s k i d ;

p r i n t f ( ” A s s i g n t s k %d wrk %d \n” , t s k ->b k t a s k i d , wrkid ) ;


return 0 ;
}

14
3.1 Multitasking framework illustration BK TPool 3 PRACTICES

Assign worker a assign a task to a worker


int b k w r k d i s p a t c h w o r k e r ( unsigned int wrkid )
{

#i f d e f d busy [ w r k i d c u r ] != 0kORK THREAD


unsigned int t i d = w r k i d t i d [ wrkid ] ;

/∗ I n v a l i d t a s k ∗/
i f ( worker [ wrkid ] . f u n c == NULL)
return - 1 ;

#i f d e f DEBUG
f p r i n t f ( s t d e r r , ” brkwrk d i s p a t c h wrkid %d - send s i g n a l %u \n” , wrkid , t i d ) ;
#endif

s y s c a l l ( S Y S t k i l l , t i d , SIG DISPATCH ) ;
#e l s e
/∗ TODO: Implement f o r k v e r s i o n t o s i g n a l worker p r o c e s s h e r e ∗/

#endif
}

3.1.4 Finalize task pool and resource worker

Task pool data structure delaration and pool initialization function


/∗
∗ From b k t p o o l . h
∗/

#include < s t d l i b . h>


#include <p t h r e a d . h>

#define MAXWORKER 10

#define WRK THREAD 1


#define STACK SIZE 4096

#define SIG DISPATCH SIGUSR1

typedef void ∗ ( ∗ t h r e a d f u n c t ) ( void ∗ ) ;

/∗ Task ID i s u n i q u e non - d e c r e a s i n g i n t e g e r ∗/
int t a s k i d s e e d ;

int w r k i d t i d [MAXWORKER] ;

15
3.1 Multitasking framework illustration BK TPool 3 PRACTICES

int w r k i d b u s y [MAXWORKER] ;
int w r k i d c u r ;

struct b k t a s k t {
void ( ∗ f u n c ) ( void ∗ a r g ) ;
void ∗ a r g ;
unsigned int b k t a s k i d ;
struct b k t a s k t ∗ t n e x t ;
} ∗ b k ta s k ;

int b k t a s k s z ;

struct b k w o r k e r t {
void ( ∗ f u n c ) ( void ∗ a r g ) ;
void ∗ a r g ;
unsigned int wrkid ;
unsigned int b k t a s k i d ;
};

struct b k w o r k e r t worker [MAXWORKER] ;

/∗
∗ From b k t p o o l . c
∗/

#include ” b k t p o o l . h”

int b k t p o o l i n i t ( )
{
return b k w r k c r e a t e w o r k e r ( ) ;
}

Resource worker Take a loop of waiting for incoming control signal and do its job. After finishing the
task work, it backs to waiting state to catch the next event.

void ∗ bkwrk worker ( void ∗ a r g )


{
sigset t set ;
int s i g ;
int s ;
int i = ∗ ( ( int ∗ ) a r g ) ; // D e f a u l t a r g i s i n t e g e r o f w o r k i d
struct b k w o r k e r t ∗wrk = &worker [ i ] ;

/∗ Taking t h e mask f o r waking up ∗/

16
3.1 Multitasking framework illustration BK TPool 3 PRACTICES

s i g e m p t y s e t (& s e t ) ;
s i g a d d s e t (& s e t , SIGUSR1 ) ;
s i g a d d s e t (& s e t , SIGQUIT ) ;

#i f d e f DEBUG
f p r i n t f ( s t d e r r , ” worker %i s t a r t l i v i n g t i d %d \n” , i , g e t p i d ( ) ) ;
fflush ( stderr );
#endif

while ( 1 )
{
/∗ w a i t f o r s i g n a l ∗/
s = s i g w a i t (& s e t , &s i g ) ;
i f ( s != 0 )
continue ;

#i f d e f INFO
f p r i n t f ( s t d e r r , ” worker wake %d up\n” , i ) ;
#endif

/∗ Busy running ∗/
i f ( wrk ->f u n c != NULL)
wrk ->f u n c ( wrk ->a r g ) ;

/∗ A d v e r t i s e I DONE WORKING ∗/
wrkid busy [ i ] = 0 ;
worker [ i ] . f u n c = NULL;
worker [ i ] . a r g = NULL;
worker [ i ] . b k t a s k i d = - 1 ;
}
}

Worker data structure delaration and pool initialization function

void ∗ bkwrk worker ( void ∗ a r g )


{
sigset t set ;
int s i g ;
int s ;
int i = ∗ ( ( int ∗ ) a r g ) ; // D e f a u l t a r g i s i n t e g e r o f w o r k i d
struct b k w o r k e r t ∗wrk = &worker [ i ] ;

/∗ Taking t h e mask f o r waking up ∗/


s i g e m p t y s e t (& s e t ) ;
s i g a d d s e t (& s e t , SIGUSR1 ) ;

17
3.2 Practice with CronTab 3 PRACTICES

s i g a d d s e t (& s e t , SIGQUIT ) ;

#i f d e f DEBUG
f p r i n t f ( s t d e r r , ” worker %i s t a r t l i v i n g t i d %d \n” , i , g e t p i d ( ) ) ;
fflush ( stderr );
#endif

while ( 1 )
{
/∗ w a i t f o r s i g n a l ∗/
s = s i g w a i t (& s e t , &s i g ) ;
i f ( s != 0 )
continue ;

#i f d e f INFO
f p r i n t f ( s t d e r r , ” worker wake %d up\n” , i ) ;
#endif

/∗ Busy running ∗/
i f ( wrk ->f u n c != NULL)
wrk ->f u n c ( wrk ->a r g ) ;

/∗ A d v e r t i s e I DONE WORKING ∗/
wrkid busy [ i ] = 0 ;
worker [ i ] . f u n c = NULL;
worker [ i ] . a r g = NULL;
worker [ i ] . b k t a s k i d = - 1 ;
}
}

3.2 Practice with CronTab


In this lab, we will look at an example of how to schedule a simple script with a cron job. First, we will
create a script called date-script.sh in our HOME folder to print the system date and time and appends
it to a file. The content of our script is shown below:
#!/ bin/sh

$ echo $ ( date ) >> date - out . txt

Don’t forget to make the script executable by using the chmod command. Then we define our job in
the CronTab. To open the crontab configuration file for the current user, enter the following command:
$ crontab - e

We can add any number of scheduled tasks, one per line. In this case, we want to make our job run
every minute, so we will add the following command (please change the user of the absolute path to your
Linux username):

18
3.2 Practice with CronTab 3 PRACTICES

∗/1 ∗ ∗ ∗ ∗ /home/ user /date - s c r i p t . sh

Wait for some minutes and verify our cron job by checking the content of our output file:
$ cat date - out . txt

Thu 20 Oct 2022 04:02:01 PM UTC


Thu 20 Oct 2022 04:03:01 PM UTC
Thu 20 Oct 2022 04:04:02 PM UTC
Thu 20 Oct 2022 04:05:02 PM UTC
Thu 20 Oct 2022 04:06:01 PM UTC

Practice

Convert the following intervals to crontab presentation

• Every Monday at 08:30

• Every workday, every 30 minutes, from 8:15 to 17:45

• Last day of every month at 17:30

19
4 EXERCISE

4 Exercise
PROBLEM 1 Implement the FIFO scheduler policy to bkwrk get worker() in section 3.1.2.

Expected TaskPool Output

$ . / mypool
b k w r k c r e a t e w o r k e r g o t worker 7593
b k w r k c r e a t e w o r k e r g o t worker 7594
b k w r k c r e a t e w o r k e r g o t worker 7595
b k w r k c r e a t e w o r k e r g o t worker 7596
b k w r k c r e a t e w o r k e r g o t worker 7597
b k w r k c r e a t e w o r k e r g o t worker 7598
b k w r k c r e a t e w o r k e r g o t worker 7599
b k w r k c r e a t e w o r k e r g o t worker 7600
b k w r k c r e a t e w o r k e r g o t worker 7601
b k w r k c r e a t e w o r k e r g o t worker 7602
A s s i g n t s k 0 wrk 0
worker wake 0 up
Task f u n c - H e l l o from 1
A s s i g n t s k 1 wrk 0 >>>>>>>>>> A c t i v a t e a s y n c h r o n o u s l y
A s s i g n t s k 2 wrk 1 >>>>>>>>>> A c t i v a t e a s y n c h r o n o u s l y
worker wake 0 up
Task f u n c - H e l l o from 2
worker wake 1 up
Task f u n c - H e l l o from 5

PROBLEM 2 In section 3.1.1 You are provided a thread based implementation of task worker in the
function bkwrk create worker(). Try to implement another version of the worker using more common
fork() API.

PROBLEM 3 Base on the provided material of multi-task programming and signal control, develop
your own framework of Fork-Join in theory.

20
Revision History 4 EXERCISE

Revision History

Revision Date Author(s) Description


1.0 03.15 PD Nguyen Document created
... ... ...
2 10.2022 LHT Hoang Update lab content, practices and exercises
3 10.2023 PD Nguyen add BK TPool and related description, update exercises

21

You might also like