#ifndef extc_phase5_h
#define extc_phase5_h
/***************************************************************************
 *  phase5.h
 *
 *  Tue Jul 26 21:25:12 2005
 *  Copyright  2005  James Scully- aka jtox
 *  Jtoxification@users.sourceforge.net
 ****************************************************************************
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */
 
 
 /* The main concern right now with processes is that the maintainer of this
    project has insufficient knowledge concerning how dynamic memory accessed
    from static memory is treated in sibling processes: it could be duplicated,
    for all I know.  Thus while this is thread-safe, the pre-emptive support for
    multiple processes may actually break the code rather than strengthen it.
     
    This won't be a problem in another two weeks: the homework assignment due
    is an academic implementation of a memory pager for a minix-like OS -
    hence, in finishing the homework, this programmer will get all the knowledge
    he needs and then some ... */
 
 
 
/* YOUR OWN process info  //////////////////////////////////////////////////*/
#if defined(YOUR_PROCESS_INFO)
    #define YOUR_PROCESS_ID_FUNCTION your_proc_id()
/* END SECTION YOUR OWN PROCESS UTILITIES //////////////////////////////////*/
#elif defined (_usloss_h)

    #include <provided_prototypes.h>
    #include <libuser.h>
    
    #define in_usermode !(psr_get()&PSR_CURRENT_MODE)

    int getpid__     (       );
    int  Mutex__     (       );
    int   SemF__     (int* id);
    int   SemP__     (int* id);
    int   SemV__     (int* id);
    int  MUTEX__     (int* id);
    
    int getpid__(){int pid; getPID(&pid);return pid;}
    int Mutex__ (){int s; SemCreate(1,&s);return s;}
    
    int SemP__ (int* id){in_usermode?return SemP(*id):return semp_real(*id);}
    int SemV__ (int* id){in_usermode?return SemV(*id):return semv_real(*id);}
    int SemF__ (int* id){in_usermode?return SemFree(*id):return semfree_real(*id);}
    int MUTEX__(int* id){in_usermode?return Mutex__():return semcreate_real(*id);}

    #define GETPID() (psr_get()&PSR_CURRENT_MODE)?getpid_real():__getpid()
    
#elif defined (unix)
    
    #if defined ( _SYS_TYPES_H )
        #if defined ( _UNISTD_H )
            #define GETPID() (int)getpid()
        #else
            #define GETPID() 0
        #endif
    #else
        #define GETPID() 0
    #endif
    
#endif

/* YOUR OWN thread info ///////////////////////////////////////////////////*/
#if defined(YOUR_THREAD_INFO)
    #define YOUR_THREAD_ID_FUNCTION your_thread_id()
/*Endsection your own info ////////////////////////////////////////////////*/
#elif defined (_usloss_h)
    #define GETTID() 0
#elif defined( _PTHREAD_H )
    #define GETTID() pthread_self()
    int SemP__     (int* id);
    int SemV__     (int* id);
    int Semaphore__(int* id);


    int SemP__     (int* id)
    {
        return pthread_mutex_lock((pthread_mutex_t*)id);        
    }
    
    int SemV__     (int* id)
    {
        return pthread_mutex_unlock((pthread_mutex_t*)id);
    }
    
    int MUTEX__(int* id)
    {
        return pthread_mutex_init((pthread_mutex_t*)id,NULL);
    }
#else
    #define GETTID() 0
#endif

#endif