Professional Documents
Culture Documents
User
Device
Kernel
File
Device Driver
Hardware
Device Driver
return ret ;
}
r e t = a l l o c _ k l i f e (& k ) ;
i f ( ret )
return ret ;
f i l p −>p r i v a t e _ d a t a = k ;
return 0;
}
k = k m a l l o c ( s i z e o f ( ∗ k ) , GFP_KERNEL ) ;
if (! k)
r e t u r n −ENOMEM;
ret = i n i t _ k l i f e (k );
i f ( ret ) {
kfree ( k ) ;
k = NULL ;
}
∗pk = k ;
return ret ;
}
memset ( k , 0 , s i z e o f ( ∗ k ) ) ;
s p i n _ l o c k _ i n i t (& k−>l o c k ) ;
r e t = −ENOMEM;
/ ∗ one page t o be e x p o r t e d t o userspace ∗ /
k−>g r i d = ( v o i d ∗ ) get_zeroed_page (GFP_KERNEL ) ;
i f ( ! k−>g r i d )
goto done ;
free_grid :
free_page ( ( unsigned l o n g ) k−>g r i d ) ;
done :
return ret ;
}
k b u f = k m a l l o c ( sz , GFP_KERNEL ) ;
i f ( ! kbuf )
r e t u r n −ENOMEM;
r e t = k l i f e _ a d d _ p o s i t i o n ( k , k b u f , sz ) ;
i f ( ret == 0)
r e t = sz ;
free_buf :
kfree ( kbuf ) ;
return ret ;
}
k l i f e = f i l p −>p r i v a t e _ d a t a ;
/ ∗ s p e c i a l h a n d l i n g f o r mmap ∗ /
i f ( k l i f e −>mapped )
r e t u r n klife_read_mapped ( f i l p , ubuf , count , f_pos ) ;
Note that the lock is held for the shortest possible time.
We will see later what the lock protects us against.
∗ f_pos + = l e n ;
r e t = len ;
free_page :
k f r e e ( page ) ;
return ret ;
}
k l i f e = f i l p −>p r i v a t e _ d a t a ;
s p i n _ l o c k _ i r q s a v e (& k l i f e −>l o c k , f l a g s ) ;
klife_next_generation ( k l i f e ) ;
s p i n _ u n l o c k _ i r q r e s t o r e (& k l i f e −>l o c k , f l a g s ) ;
return 0;
}
i f ( ret == 0)
k l i f e −>mapped = 1 ;
return ret ;
}
s t a t i c void k l i f e _ t i m e r _ r e g i s t e r ( s t r u c t k l i f e ∗ k l i f e )
{
unsigned l o n g f l a g s ;
int ret ;
s p i n _ l o c k _ i r q s a v e (& k l i f e −>l o c k , f l a g s ) ;
/ ∗ prime t h e t a s k l e t w i t h t h e c o r r e c t data − ours ∗ /
t a s k l e t _ i n i t (& k l i f e _ t a s k l e t , k l i f e _ t a s k l e t _ f u n c ,
( unsigned l o n g ) k l i f e ) ;
r e t = r e g i s t e r _ t i m e r _ i n t e r r u p t (& k l i f e −>timer_hook ) ;
i f ( ! ret )
k l i f e −>t i m e r = 1 ;
s p i n _ u n l o c k _ i r q r e s t o r e (& k l i f e −>l o c k , f l a g s ) ;
pr_debug ( " r e g i s t e r _ t i m e r _ i n t e r r u p t r e t u r n e d %d \ n " , r e t ) ;
}
/ ∗ 2 t i m e s a second ∗ /
i f ( k l i f e −>t i m e r _ i n v o c a t i o n ++ % (HZ / 2 ) = = 0 )
t a s k l e t _ s c h e d u l e (& k l i f e _ t a s k l e t ) ;
}
s t a t i c v o i d k l i f e _ t a s k l e t _ f u n c ( unsigned l o n g data )
{
s t r u c t k l i f e ∗ k l i f e = ( v o i d ∗ ) data ;
s p i n _ l o c k (& k l i f e −>l o c k ) ;
klife_next_generation ( k l i f e ) ;
s p i n _ u n l o c k (& k l i f e −>l o c k ) ;
}
In drivers/char/Kconfig:
+ c o n f i g GAME_OF_LIFE
+ t r i s t a t e " k e r n e l game o f l i f e "
+ help
+ K e r n e l i m p l e m e n t a t i o n o f t h e Game o f L i f e .
in drivers/char/Makefile
+ o b j−$ ( CONFIG_GAME_OF_LIFE ) + = k l i f e . o
Questions?