Use libc's __extern_inline which works properly according to optimization flags --- libdiskfs/diskfs.h | 17 ++++++---- libpipe/pipe.h | 74 ++++++++++++++++++++++++++++++++------------ libpipe/pq.h | 57 ++++++++++++++++++++++++++------- libshouldbeinlibc/idvec.h | 29 ++++++++++++----- libshouldbeinlibc/maptime.h | 13 ++++--- libshouldbeinlibc/ugids.h | 25 ++++++++++---- libstore/store.h | 13 ++++--- libthreads/rwlock.h | 27 +++++++++++----- 8 files changed, 184 insertions(+), 71 deletions(-) --- a/libdiskfs/diskfs.h +++ b/libdiskfs/diskfs.h @@ -27,10 +27,7 @@ #include #include #include - -#ifndef DISKFS_EXTERN_INLINE -#define DISKFS_EXTERN_INLINE extern inline -#endif +#include /* Each user port referring to a file points to one of these (with the aid of the ports library). */ @@ -781,10 +778,16 @@ error_t diskfs_start_protid (struct pero the user to install is USER. */ void diskfs_finish_protid (struct protid *cred, struct iouser *user); +extern struct protid * diskfs_begin_using_protid_port (file_t port); + +extern void diskfs_end_using_protid_port (struct protid *cred); + +# ifdef __USE_EXTERN_INLINES + /* Called by MiG to translate ports into struct protid *. fsmutations.h arranges for this to happen for the io and fs interfaces. */ -DISKFS_EXTERN_INLINE struct protid * +__extern_inline struct protid * diskfs_begin_using_protid_port (file_t port) { return ports_lookup_port (diskfs_port_bucket, port, diskfs_protid_class); @@ -793,13 +796,15 @@ diskfs_begin_using_protid_port (file_t p /* Called by MiG after server routines have been run; this balances begin_using_protid_port, and is arranged for the io and fs interfaces by fsmutations.h. */ -DISKFS_EXTERN_INLINE void +__extern_inline void diskfs_end_using_protid_port (struct protid *cred) { if (cred) ports_port_deref (cred); } +# endif /* Use extern inlines. */ + /* Called when a protid CRED has no more references. (Because references\ to protids are maintained by the port management library, this is installed in the clean routines list.) The ports library will --- a/libpipe/pipe.h +++ b/libpipe/pipe.h @@ -24,13 +24,10 @@ #define EWOULDBLOCK EAGAIN /* XXX */ #include /* For conditions & mutexes */ +#include #include "pq.h" -#ifndef PIPE_EI -#define PIPE_EI extern inline -#endif - /* A description of a class of pipes and how to operate on them. */ struct pipe_class @@ -107,9 +104,24 @@ struct pipe /* Pipe flags. */ #define PIPE_BROKEN 0x1 /* This pipe isn't connected. */ + +extern size_t pipe_readable (struct pipe *pipe, int data_only); + +extern int pipe_is_readable (struct pipe *pipe, int data_only); + +extern error_t pipe_wait_readable (struct pipe *pipe, int noblock, int data_only); + +extern error_t pipe_select_readable (struct pipe *pipe, int data_only); + +extern error_t pipe_wait_writable (struct pipe *pipe, int noblock); + +extern error_t pipe_select_writable (struct pipe *pipe); + +# ifdef __USE_EXTERN_INLINES + /* Returns the number of characters quickly readable from PIPE. If DATA_ONLY is true, then `control' packets are ignored. */ -PIPE_EI size_t +__extern_inline size_t pipe_readable (struct pipe *pipe, int data_only) { size_t readable = 0; @@ -128,7 +140,7 @@ pipe_readable (struct pipe *pipe, int da then `control' packets are ignored. Note that this is different than (pipe_readable (PIPE) > 0) in the case where a control packet containing only ports is present. */ -PIPE_EI int +__extern_inline int pipe_is_readable (struct pipe *pipe, int data_only) { struct pq *pq = pipe->queue; @@ -143,7 +155,7 @@ pipe_is_readable (struct pipe *pipe, int this operation will return EWOULDBLOCK instead of blocking when no data is immediately available. If DATA_ONLY is true, then `control' packets are ignored. */ -PIPE_EI error_t +__extern_inline error_t pipe_wait_readable (struct pipe *pipe, int noblock, int data_only) { while (! pipe_is_readable (pipe, data_only) && ! (pipe->flags & PIPE_BROKEN)) @@ -160,7 +172,7 @@ pipe_wait_readable (struct pipe *pipe, i returns once threads waiting using pipe_wait_readable have been woken and given a chance to read, and if there is still data available thereafter. If DATA_ONLY is true, then `control' packets are ignored. */ -PIPE_EI error_t +__extern_inline error_t pipe_select_readable (struct pipe *pipe, int data_only) { while (! pipe_is_readable (pipe, data_only) && ! (pipe->flags & PIPE_BROKEN)) @@ -172,7 +184,7 @@ pipe_select_readable (struct pipe *pipe, /* Block until data can be written to PIPE. If NOBLOCK is true, then EWOULDBLOCK is returned instead of blocking if this can't be done immediately. */ -PIPE_EI error_t +__extern_inline error_t pipe_wait_writable (struct pipe *pipe, int noblock) { size_t limit = pipe->write_limit; @@ -193,7 +205,7 @@ pipe_wait_writable (struct pipe *pipe, i /* Block until some data can be written to PIPE. This call only returns once threads waiting using pipe_wait_writable have been woken and given a chance to write, and if there is still space available thereafter. */ -PIPE_EI error_t +__extern_inline error_t pipe_select_writable (struct pipe *pipe) { size_t limit = pipe->write_limit; @@ -203,6 +215,8 @@ pipe_select_writable (struct pipe *pipe) return 0; } +# endif /* Use extern inlines. */ + /* Creates a new pipe of class CLASS and returns it in RESULT. */ error_t pipe_create (struct pipe_class *class, struct pipe **pipe); @@ -223,8 +237,28 @@ void _pipe_no_readers (struct pipe *pipe should be locked. */ void _pipe_no_writers (struct pipe *pipe); +extern void pipe_acquire_reader (struct pipe *pipe); + +extern void pipe_acquire_writer (struct pipe *pipe); + +extern void pipe_release_reader (struct pipe *pipe); + +extern void pipe_release_writer (struct pipe *pipe); + +extern void pipe_add_reader (struct pipe *pipe); + +extern void pipe_add_writer (struct pipe *pipe); + +extern void pipe_remove_reader (struct pipe *pipe); + +extern void pipe_remove_writer (struct pipe *pipe); + +extern void pipe_drain (struct pipe *pipe); + +# ifdef __USE_EXTERN_INLINES + /* Lock PIPE and increment its readers count. */ -PIPE_EI void +__extern_inline void pipe_acquire_reader (struct pipe *pipe) { mutex_lock (&pipe->lock); @@ -233,7 +267,7 @@ pipe_acquire_reader (struct pipe *pipe) } /* Lock PIPE and increment its writers count. */ -PIPE_EI void +__extern_inline void pipe_acquire_writer (struct pipe *pipe) { mutex_lock (&pipe->lock); @@ -243,7 +277,7 @@ pipe_acquire_writer (struct pipe *pipe) /* Decrement PIPE's (which should be locked) reader count and unlock it. If there are no more refs to PIPE, it will be destroyed. */ -PIPE_EI void +__extern_inline void pipe_release_reader (struct pipe *pipe) { if (--pipe->readers == 0) @@ -254,7 +288,7 @@ pipe_release_reader (struct pipe *pipe) /* Decrement PIPE's (which should be locked) writer count and unlock it. If there are no more refs to PIPE, it will be destroyed. */ -PIPE_EI void +__extern_inline void pipe_release_writer (struct pipe *pipe) { if (--pipe->writers == 0) @@ -264,7 +298,7 @@ pipe_release_writer (struct pipe *pipe) } /* Increment PIPE's reader count. PIPE should be unlocked. */ -PIPE_EI void +__extern_inline void pipe_add_reader (struct pipe *pipe) { pipe_acquire_reader (pipe); @@ -272,7 +306,7 @@ pipe_add_reader (struct pipe *pipe) } /* Increment PIPE's writer count. PIPE should be unlocked. */ -PIPE_EI void +__extern_inline void pipe_add_writer (struct pipe *pipe) { pipe_acquire_writer (pipe); @@ -281,7 +315,7 @@ pipe_add_writer (struct pipe *pipe) /* Decrement PIPE's (which should be unlocked) reader count and unlock it. If there are no more refs to PIPE, it will be destroyed. */ -PIPE_EI void +__extern_inline void pipe_remove_reader (struct pipe *pipe) { mutex_lock (&pipe->lock); @@ -290,7 +324,7 @@ pipe_remove_reader (struct pipe *pipe) /* Decrement PIPE's (which should be unlocked) writer count and unlock it. If there are no more refs to PIPE, it will be destroyed. */ -PIPE_EI void +__extern_inline void pipe_remove_writer (struct pipe *pipe) { mutex_lock (&pipe->lock); @@ -298,12 +332,14 @@ pipe_remove_writer (struct pipe *pipe) } /* Empty out PIPE of any data. PIPE should be locked. */ -PIPE_EI void +__extern_inline void pipe_drain (struct pipe *pipe) { pq_drain (pipe->queue); } +# endif /* Use extern inlines. */ + /* Writes up to LEN bytes of DATA, to PIPE, which should be locked, and returns the amount written in AMOUNT. If present, the information in CONTROL & PORTS is written in a preceding control packet. If an error is --- a/libpipe/pq.h +++ b/libpipe/pq.h @@ -25,10 +25,7 @@ #include /* for size_t */ #include #include - -#ifndef PQ_EI -#define PQ_EI extern inline -#endif +#include struct packet @@ -70,13 +67,19 @@ error_t packet_set_ports (struct packet /* If PACKET has any ports, deallocates them. */ void packet_dealloc_ports (struct packet *packet); +extern size_t packet_readable (struct packet *packet); + +# ifdef __USE_EXTERN_INLINES + /* Returns the number of bytes of data in PACKET. */ -PQ_EI size_t +__extern_inline size_t packet_readable (struct packet *packet) { return packet->buf_end - packet->buf_start; } +# endif /* Use extern inlines. */ + /* Append the bytes in DATA, of length DATA_LEN, to what's already in PACKET, and return the amount appended in AMOUNT if that's not the null pointer. */ error_t packet_write (struct packet *packet, @@ -94,14 +97,20 @@ error_t packet_read (struct packet *pack error_t packet_read_ports (struct packet *packet, mach_port_t **ports, size_t *num_ports); +extern void packet_read_source (struct packet *packet, void **source); + +# ifdef __USE_EXTERN_INLINES + /* Return the source addressd in PACKET in SOURCE, deallocating it from PACKET. */ -PQ_EI void +__extern_inline void packet_read_source (struct packet *packet, void **source) { *source = packet->source; packet->source = 0; } + +# endif /* Use extern inlines. */ /* The packet size above which we start to do things differently to avoid copying around data. */ @@ -125,9 +134,17 @@ int packet_extend (struct packet *packet returned. */ error_t packet_realloc (struct packet *packet, size_t new_len); +extern int packet_fit (struct packet *packet, size_t amount); + +extern error_t packet_ensure (struct packet *packet, size_t amount); + +extern int packet_ensure_efficiently (struct packet *packet, size_t amount); + +# ifdef __USE_EXTERN_INLINES + /* Try to make space in PACKET for AMOUNT more bytes without growing the buffer, returning true if we could do it. */ -PQ_EI int +__extern_inline int packet_fit (struct packet *packet, size_t amount) { char *buf = packet->buf, *end = packet->buf_end; @@ -159,7 +176,7 @@ packet_fit (struct packet *packet, size_ /* Make sure that PACKET has room for at least AMOUNT more bytes, or return the reason why not. */ -PQ_EI error_t +__extern_inline error_t packet_ensure (struct packet *packet, size_t amount) { if (! packet_fit (packet, amount)) @@ -176,7 +193,7 @@ packet_ensure (struct packet *packet, si it can be done efficiently, e.g., the packet can be grown in place, rather than moving the contents (or there is little enough data so that copying it is OK). True is returned if room was made, false otherwise. */ -PQ_EI int +__extern_inline int packet_ensure_efficiently (struct packet *packet, size_t amount) { if (! packet_fit (packet, amount)) @@ -189,6 +206,8 @@ packet_ensure_efficiently (struct packet } return 0; } + +# endif /* Use extern inlines. */ struct pq { @@ -201,10 +220,14 @@ struct pq the packet, or deallocated by calling pipe_dealloc_addr. */ struct packet *pq_queue (struct pq *pq, unsigned type, void *source); +extern struct packet * pq_tail (struct pq *pq, unsigned type, void *source); + +# ifdef __USE_EXTERN_INLINES + /* Returns the tail of the packet queue PQ, which may mean pushing a new packet if TYPE and SOURCE do not match the current tail, or this is the first packet. */ -PQ_EI struct packet * +__extern_inline struct packet * pq_tail (struct pq *pq, unsigned type, void *source) { struct packet *tail = pq->tail; @@ -214,16 +237,24 @@ pq_tail (struct pq *pq, unsigned type, v return tail; } +# endif /* Use extern inlines. */ + /* Remove the first packet (if any) in PQ, deallocating any resources it holds. True is returned if a packet was found, false otherwise. */ int pq_dequeue (struct pq *pq); +extern struct packet * pq_head (struct pq *pq, unsigned type, void *source); + +extern struct packet * pq_next (struct pq *pq, unsigned type, void *source); + +# ifdef __USE_EXTERN_INLINES + /* Returns the next available packet in PQ, without removing it from the queue, or NULL if there is none, or the next packet isn't appropriate. A packet is inappropriate if SOURCE is non-NULL its source field doesn't match it, or TYPE is non-NULL and the packet's type field doesn't match it. */ -PQ_EI struct packet * +__extern_inline struct packet * pq_head (struct pq *pq, unsigned type, void *source) { struct packet *head = pq->head; @@ -237,7 +268,7 @@ pq_head (struct pq *pq, unsigned type, v } /* The same as pq_head, but first discards the head of the queue. */ -PQ_EI struct packet * +__extern_inline struct packet * pq_next (struct pq *pq, unsigned type, void *source) { if (!pq->head) @@ -246,6 +277,8 @@ pq_next (struct pq *pq, unsigned type, v return pq_head (pq, type, source); } +# endif /* Use extern inlines. */ + /* Dequeues all packets in PQ. */ void pq_drain (struct pq *pq); --- a/libshouldbeinlibc/idvec.h +++ b/libshouldbeinlibc/idvec.h @@ -24,10 +24,7 @@ #include #include #include - -#ifndef IDVEC_EI -#define IDVEC_EI extern inline -#endif +#include struct idvec { @@ -50,22 +47,30 @@ void idvec_free_wrapper (struct idvec *i /* Free IDVEC and any storage associated with it. */ void idvec_free (struct idvec *idvec); +extern void idvec_clear (struct idvec *idvec); + +extern int idvec_is_empty (const struct idvec *idvec); + +extern int idvec_equal (const struct idvec *idvec1, const struct idvec *idvec2); + +# ifdef __USE_EXTERN_INLINES + /* Mark IDVEC as not containing any ids. */ -IDVEC_EI void +__extern_inline void idvec_clear (struct idvec *idvec) { idvec->num = 0; } /* Returns true if IDVEC contains no ids. */ -IDVEC_EI int +__extern_inline int idvec_is_empty (const struct idvec *idvec) { return idvec->num == 0; } /* Return true if IDVEC1 has contents identical to IDVEC2. */ -IDVEC_EI int +__extern_inline int idvec_equal (const struct idvec *idvec1, const struct idvec *idvec2) { size_t num = idvec1->num; @@ -74,6 +79,8 @@ idvec_equal (const struct idvec *idvec1, || memcmp (idvec1->ids, idvec2->ids, num * sizeof *idvec1->ids) == 0); } +# endif /* Use extern inlines. */ + /* Ensure that IDVEC has enough spaced allocated to hold NUM ids, thus ensuring that any subsequent ids added won't return a memory allocation error unless it would result in more ids that NUM. ENOMEM is returned if @@ -87,13 +94,19 @@ error_t idvec_grow (struct idvec *idvec, /* Returns true if IDVEC contains ID, at or after position POS. */ int idvec_tail_contains (const struct idvec *idvec, unsigned pos, uid_t id); +extern int idvec_contains (const struct idvec *idvec, uid_t id); + +# ifdef __USE_EXTERN_INLINES + /* Returns true if IDVEC contains ID. */ -IDVEC_EI int +__extern_inline int idvec_contains (const struct idvec *idvec, uid_t id) { return idvec_tail_contains (idvec, 0, id); } +# endif /* Use extern inlines. */ + /* Insert ID into IDVEC at position POS, returning ENOMEM if there wasn't enough memory, or 0. */ error_t idvec_insert (struct idvec *idvec, unsigned pos, uid_t id); --- a/libshouldbeinlibc/maptime.h +++ b/libshouldbeinlibc/maptime.h @@ -21,13 +21,10 @@ #ifndef __MAPTIME_H__ #define __MAPTIME_H__ -#ifndef MAPTIME_EI -#define MAPTIME_EI extern inline -#endif - #include #include #include +#include /* Return the mach mapped time page in MTIME. If USE_MACH_DEV is false, then the hurd time device DEV_NAME, or "/dev/time" if DEV_NAME is 0, is @@ -37,8 +34,12 @@ error_t maptime_map (int use_mach_dev, char *dev_name, volatile struct mapped_time_value **mtime); +extern void maptime_read (volatile struct mapped_time_value *mtime, struct timeval *tv); + +# ifdef __USE_EXTERN_INLINES + /* Read the current time from MTIME into TV. This should be very fast. */ -MAPTIME_EI void +__extern_inline void maptime_read (volatile struct mapped_time_value *mtime, struct timeval *tv) { do @@ -49,4 +50,6 @@ maptime_read (volatile struct mapped_tim while (tv->tv_sec != mtime->check_seconds); } +# endif /* Use extern inlines. */ + #endif /* __MAPTIME_H__ */ --- a/libshouldbeinlibc/ugids.h +++ b/libshouldbeinlibc/ugids.h @@ -23,10 +23,7 @@ #include /* For inline function stuff. */ #include - -#ifndef UGIDS_EI -#define UGIDS_EI extern inline -#endif +#include /* A structure holding a set of the common various types of ids. */ struct ugids @@ -47,8 +44,18 @@ struct ugids /* Return a new ugids structure, or 0 if an allocation error occurs. */ struct ugids *make_ugids (); +extern void ugids_fini (struct ugids *ugids); + +extern void ugids_free (struct ugids *ugids); + +extern int ugids_is_empty (const struct ugids *ugids); + +extern int ugids_equal (const struct ugids *ugids1, const struct ugids *ugids2); + +# ifdef __USE_EXTERN_INLINES + /* Free all resources used by UGIDS except UGIDS itself. */ -UGIDS_EI void +__extern_inline void ugids_fini (struct ugids *ugids) { idvec_fini (&ugids->eff_uids); @@ -60,7 +67,7 @@ ugids_fini (struct ugids *ugids) } /* Free all resources used by UGIDS. */ -UGIDS_EI void +__extern_inline void ugids_free (struct ugids *ugids) { ugids_fini (ugids); @@ -68,7 +75,7 @@ ugids_free (struct ugids *ugids) } /* Return true if UGIDS contains no ids. */ -UGIDS_EI int +__extern_inline int ugids_is_empty (const struct ugids *ugids) { /* We needn't test the imp_*_gids vectors because they are subsets of the @@ -81,7 +88,7 @@ ugids_is_empty (const struct ugids *ugid } /* Free all resources used by UGIDS except UGIDS itself. */ -UGIDS_EI int +__extern_inline int ugids_equal (const struct ugids *ugids1, const struct ugids *ugids2) { return @@ -93,6 +100,8 @@ ugids_equal (const struct ugids *ugids1, && idvec_equal (&ugids1->imp_avail_gids, &ugids2->imp_avail_gids); } +# endif /* Use extern inlines. */ + /* Add all ids in NEW to UGIDS. */ error_t ugids_merge (struct ugids *ugids, const struct ugids *new); --- a/libstore/store.h +++ b/libstore/store.h @@ -33,10 +33,7 @@ #include #include #include - -#ifndef STORE_EI -#define STORE_EI extern inline -#endif +#include /* Type for addresses inside the store. */ @@ -270,9 +267,13 @@ error_t store_set_child_flags (struct st STORE's flags. */ error_t store_clear_child_flags (struct store *store, int flags); +extern int store_is_securely_returnable (struct store *store, int open_flags); + +# ifdef __USE_EXTERN_INLINES + /* Returns true if STORE can safely be returned to a user who has accessed it via a node using OPEN_FLAGS, without compromising security. */ -STORE_EI int +__extern_inline int store_is_securely_returnable (struct store *store, int open_flags) { int flags = store->flags; @@ -283,6 +284,8 @@ store_is_securely_returnable (struct sto || (flags & STORE_HARD_READONLY))); } +# endif /* Use extern inlines. */ + /* Fills in the values of the various fields in STORE that are derivable from the set of runs & the block size. */ void _store_derive (struct store *store); --- a/libthreads/rwlock.h +++ b/libthreads/rwlock.h @@ -21,6 +21,7 @@ #include #include +#include struct rwlock { @@ -31,12 +32,20 @@ struct rwlock int readers_waiting; }; -#ifndef RWLOCK_EI -#define RWLOCK_EI extern inline -#endif +extern void rwlock_reader_lock (struct rwlock *lock); + +extern void rwlock_writer_lock (struct rwlock *lock); + +extern void rwlock_reader_unlock (struct rwlock *lock); + +extern void rwlock_writer_unlock (struct rwlock *lock); + +extern void rwlock_init (struct rwlock *lock); + +# ifdef __USE_EXTERN_INLINES /* Get a reader lock on reader-writer lock LOCK for disknode DN */ -RWLOCK_EI void +__extern_inline void rwlock_reader_lock (struct rwlock *lock) { mutex_lock (&lock->master); @@ -53,7 +62,7 @@ rwlock_reader_lock (struct rwlock *lock) } /* Get a writer lock on reader-writer lock LOCK for disknode DN */ -RWLOCK_EI void +__extern_inline void rwlock_writer_lock (struct rwlock *lock) { mutex_lock (&lock->master); @@ -70,7 +79,7 @@ rwlock_writer_lock (struct rwlock *lock) } /* Release a reader lock on reader-writer lock LOCK for disknode DN */ -RWLOCK_EI void +__extern_inline void rwlock_reader_unlock (struct rwlock *lock) { mutex_lock (&lock->master); @@ -82,7 +91,7 @@ rwlock_reader_unlock (struct rwlock *loc } /* Release a writer lock on reader-writer lock LOCK for disknode DN */ -RWLOCK_EI void +__extern_inline void rwlock_writer_unlock (struct rwlock *lock) { mutex_lock (&lock->master); @@ -94,7 +103,7 @@ rwlock_writer_unlock (struct rwlock *loc } /* Initialize reader-writer lock LOCK */ -RWLOCK_EI void +__extern_inline void rwlock_init (struct rwlock *lock) { mutex_init (&lock->master); @@ -104,6 +113,8 @@ rwlock_init (struct rwlock *lock) lock->writers_waiting = 0; } +# endif /* Use extern inlines. */ + #define RWLOCK_INITIALIZER \ { MUTEX_INITIALIZER, CONDITION_INITIALIZER, 0, 0, 0 }