use std::str::Chars; /// Define the BurritOS running time basic unit pub struct BurritosTime { seconds: i64, nanos: i64 } /// A unique identifier for a thread executed within a user program pub struct ThreadId{ id: u64 } /// The system call interface. These are the operations the BurritOS /// kernel needs to support, to be able to run user programs. pub struct TError { t: i32 } /// A unique identifier for an open BurritOS file. pub struct OpenFiledId{ id: u64 } /// System calls concerning semaphores management pub struct SemId{ id: u64 } /// System calls concerning locks management pub struct LockId{ id: u64 } /// System calls concerning conditions variables. pub struct CondId{ id: u64 } extern "C" { ///Stop Nachos, and print out performance stats fn Shutdown() -> (); /// Return the time spent running BurritOS /// ## Param /// - **t** a struct to define the time unit fn SysTime(t: BurritosTime) -> (); /// This user program is done /// ## Param /// - **status** status at the end of execution *(status = 0 means exited normally)*. fn Exit(status: i32) -> (); /// Run the executable, stored in the BurritOS file "name", and return the /// master thread identifier fn Exec(name: *const char) -> ThreadId; /// Create a new thread in the current process /// Return thread identifier fn newThread(debug_name: *const char, func: i32, arg: i32) -> ThreadId; /// Only return once the the thread "id" has finished. fn Join (id: ThreadId) -> TError; /// Yield the CPU to another runnable thread, whether in this address space /// or not. fn Yield() -> (); /// Print the last error message with the personalized one "mess" fn PError(mess: *const char) -> (); /// Create a BurritOS file, with "name" fn Create(name: *const char, size: i32) -> TError; /// Open the Nachos file "name", and return an "OpenFileId" that can /// be used to read and write to the file. fn Open(name: *const char) -> OpenFiledId; /// Write "size" bytes from "buffer" to the open file. fn Write(buffer: *const char, size: i32, id: OpenFiledId) -> TError; /// Read "size" bytes from the open file into "buffer". /// Return the number of bytes actually read -- if the open file isn't /// long enough, or if it is an I/O device, and there aren't enough /// characters to read, return whatever is available (for I/O devices, /// you should always wait until you can return at least one character). fn Read(buffer: *const char, size: i32, id:OpenFiledId) -> TError; /// Seek to a specified offset into an opened file fn Seek(offset: i32, id: OpenFiledId) -> TError; /// Close the file, we're done reading and writing to it. fn Close(id: OpenFiledId) -> TError; /// Remove the file fn Remove(name: *const char) -> TError; //////////////////////////////////////////////////// /// system calls concerning directory management /// //////////////////////////////////////////////////// /// Create a new repertory /// Return a negative number if an error ocurred. fn mkdir(name: *const char) -> t_length; /// Destroy a repertory, which must be empty. /// Return a negative number if an error ocurred. fn Rmdir(name: *const char) -> TError; /// List the content of BurritOS FileSystem fn FSList() -> TError; /// Create a semaphore, initialising it at count. /// Return a Semid, which will enable to do operations on this /// semaphore fn SemCreate(debug_name: *const char, count: i32) -> SemId; /// Destroy a semaphore identified by sema. /// Return a negative number if an error occured during the destruction fn SemDestroy(sema: SemId) -> TError; /// Do the operation P() on the semaphore sema fn P(sema: SemId) -> TError; /// Do the operation V() on the semaphore sema fn V(sema: SemId) -> TError; /// Create a lock. /// Return an identifier fn LockCreate(debug_name: *const char) -> LockId; /// Destroy a lock. /// Return a negative number if an error ocurred /// during the destruction. fn LockDestroy(id: LockId) -> TError; /// Do the operation Acquire on the lock id. /// Return a negative number if an error ocurred. fn LockAcquire(id: LockId) -> TError; /// Do the operation Release on the lock id. /// Return a negative number if an error ocurred. fn LockRelease(id: LockId) -> TError; /// Create a new condition variable fn CondCreate(debug_name: *const char) -> CondId; /// Destroy a condition variable. /// Return a negative number if an error ocurred. fn CondDestroy(id: CondId) -> TError; /// Do the operation Wait on a condition variable. /// Returns a negative number if an error ocurred. fn CondWait(id: CondId) -> TError; /// Do the operation Signal on a condition variable (wake up only one thread). /// Return a negative number if an error ocurred. fn CondSignal(id: CondId) -> TError; /// Do the operation Signal on a condition variable (wake up all threads). /// Return a negative number if an error ocurred. fn CondBroadcast(id: CondId) -> TError; /////////////////////////////////////////////////////// /// # System calls concerning serial port and console /////////////////////////////////////////////////////// ///Send the message on the serial communication link. /// Returns the number of bytes successfully sent. fn TtySend(mess: *const char) -> i32; /// Wait for a message comming from the serial communication link. /// The length of the buffer where the bytes will be copied is given as a parameter. /// Returns the number of characters actually received. fn TtyReceive(mess: *const char, length: i32) -> i32; /// Map an opened file in memory. Size is the size to be mapped in bytes. fn Mmap(id: OpenFiledId, size: i32) -> *mut (); /// For debug purpose fn Debug(param: i32)-> (); }