Commit ee75e7b5 authored by Charlie Jacobsen's avatar Charlie Jacobsen
Browse files

lcd: Removed internal synchronization for now.

It adds too much overhead, and the synchronization may not be
necessary for some libfipc use cases. It's reasonable to require
the libfipc user to do the synchronization.
parent 4d3e568d
......@@ -127,7 +127,6 @@ static void ring_buf_init(struct fipc_ring_buf *ring_buf,
unsigned int buf_order,
void *buffer)
{
fipc_mutex_init(&ring_buf->lock);
ring_buf->buffer = buffer;
ring_buf->order_two_mask = order_two_mask(buf_order);
}
......@@ -167,8 +166,6 @@ int fipc_send_msg_start(struct fipc_ring_channel *chnl,
{
int ret = -EWOULDBLOCK;
fipc_mutex_lock(&chnl->tx.lock);
if (check_tx_slot_available(get_current_tx_slot(chnl))) {
*msg = get_current_tx_slot(chnl);
......@@ -177,8 +174,6 @@ int fipc_send_msg_start(struct fipc_ring_channel *chnl,
}
fipc_mutex_unlock(&chnl->tx.lock);
#if FIPC_DEBUG_LVL >= FIPC_DEBUG_VERB
if (!ret)
......@@ -229,8 +224,6 @@ int fipc_recv_msg_start(struct fipc_ring_channel *chnl,
int ret;
struct fipc_message *m;
fipc_mutex_lock(&chnl->rx.lock);
ret = recv_msg_peek(chnl, &m);
if (!ret) {
/* Message waiting to be received */
......@@ -238,8 +231,6 @@ int fipc_recv_msg_start(struct fipc_ring_channel *chnl,
inc_rx_slot(chnl);
}
fipc_mutex_unlock(&chnl->rx.lock);
#if FIPC_DEBUG_LVL >= FIPC_DEBUG_VERB
if (!ret)
......@@ -261,8 +252,6 @@ int fipc_recv_msg_if(struct fipc_ring_channel *chnl,
int ret;
struct fipc_message *m;
fipc_mutex_lock(&chnl->rx.lock);
ret = recv_msg_peek(chnl, &m);
if (!ret) {
/* Message waiting to be received; query predicate */
......@@ -276,8 +265,6 @@ int fipc_recv_msg_if(struct fipc_ring_channel *chnl,
}
}
fipc_mutex_unlock(&chnl->rx.lock);
#if FIPC_DEBUG_LVL >= FIPC_DEBUG_VERB
if (!ret)
......
......@@ -87,6 +87,16 @@
* Send/Receive
* ------------
*
* IMPORTANT: If you plan to share the same tx or rx header on one
* side of the channel amongst multiple threads, fipc_send_msg_start and
* fipc_recv_msg_start/if are NOT thread safe. (Some libfipc users may
* not require it, so we don't do any synchronization internally.) So,
* you should wrap calls to these functions in locks as necessary. See
* their documentation for more comments.
*
* (Of course, communication across the channel itself to the other side
* does not require explicit synchronization of threads on opposite sides.)
*
* A typical send/receive sequence is as follows, assuming the headers
* have been initialized already:
*
......@@ -213,8 +223,11 @@ int fipc_ring_channel_init(struct fipc_ring_channel *chnl,
* be marked as ready to receive, for the receiver to pick up.) So, make
* sure the code in between start and end cannot fail.
*
* This function is thread safe -- if you are returned a message slot,
* you know that no other thread got a hold of it.
* IMPORTANT: This function is NOT thread safe. To make this code fast,
* we do not do any internal synchronization. If you plan to share the
* tx buffer amongst several threads, you should wrap a call to this
* function with a tx-specific lock, for example. Once this call has
* returned, however, a subsequent call will not return the same message.
*/
int fipc_send_msg_start(struct fipc_ring_channel *chnl,
struct fipc_message **msg);
......@@ -225,6 +238,8 @@ int fipc_send_msg_start(struct fipc_ring_channel *chnl,
*
* Returns non-zero on failure. (For now, this never fails, but in case
* failure is possible in the future, we provide for this possibility.)
*
* This function is thread safe.
*/
int fipc_send_msg_end(struct fipc_ring_channel *chnl,
struct fipc_message *msg);
......@@ -254,8 +269,11 @@ int fipc_send_msg_end(struct fipc_ring_channel *chnl,
* will potentially block waiting for the slot to become free. So, make sure
* your code cannot fail between start/end.
*
* This function is thread safe -- if you are returned a message,
* you know that no other thread got a hold of it.
* IMPORTANT: This function is NOT thread safe. To make this code fast,
* we do not do any internal synchronization. If you plan to share the
* rx buffer amongst several threads, you should wrap a call to this
* function with a rx-specific lock, for example. Once this call has
* returned, however, a subsequent call will not return the same message.
*/
int fipc_recv_msg_start(struct fipc_ring_channel *chnl,
struct fipc_message **msg);
......@@ -274,7 +292,11 @@ int fipc_recv_msg_start(struct fipc_ring_channel *chnl,
* @pred should return non-zero to indicate the caller should receive the
* message, and zero if no.
*
* IMPORTANT: @pred should be simple, as it is executed inside of a
* IMPORTANT: This function is NOT thread safe. To make this code fast,
* we do not do any internal synchronization. If you plan to share the
* rx buffer amongst several threads, you should wrap a call to this
* function with an rx-specific lock, for example. In that case, you
* should ensure @pred is simple, as it is would be executed inside of a
* critical section.
*/
int fipc_recv_msg_if(struct fipc_ring_channel *chnl,
......@@ -288,6 +310,8 @@ int fipc_recv_msg_if(struct fipc_ring_channel *chnl,
*
* Returns non-zero on failure. (For now, this never fails, but in case
* failure is possible in the future, we provide for this possibility.)
*
* This function is thread safe.
*/
int fipc_recv_msg_end(struct fipc_ring_channel *chnl,
struct fipc_message *msg);
......
......@@ -58,14 +58,8 @@ struct fipc_message {
* it to be double cacheline sized.
*/
#define FIPC_RING_BUF_PADDING \
(FIPC_CACHE_LINE_SIZE - \
(3 * sizeof(unsigned long) + sizeof(fipc_mutex_t)))
(FIPC_CACHE_LINE_SIZE - (3 * sizeof(unsigned long))
struct fipc_ring_buf {
/**
* Protects slot. (Note that this synchronizes threads only
* on one side of a buffer.)
*/
fipc_mutex_t lock;
/**
* Where *I* am in the IPC buffer. (The other guy knows where I am
* by looking at message statuses.)
......
......@@ -8,32 +8,12 @@
#ifndef LIBFIPC_PLATFORM_INTERNAL_H
#define LIBFIPC_PLATFORM_INTERNAL_H
#include <linux/mutex.h>
#include <linux/bug.h>
#include <linux/printk.h>
#include <libfipc_platform_types.h>
#define __fipc_debug(fmt, ...) \
printk(KERN_ERR "fipc: %s:%d: "fmt,__FUNCTION__,__LINE__,##__VA_ARGS__)
static inline int __fipc_mutex_init(fipc_mutex_t *mutex)
{
spin_lock_init(mutex);
return 0;
}
static inline int __fipc_mutex_lock(fipc_mutex_t *mutex)
{
spin_lock(mutex);
return 0;
}
static inline int __fipc_mutex_unlock(fipc_mutex_t *mutex)
{
spin_unlock(mutex);
return 0;
}
#define __FIPC_BUILD_BUG_ON_NOT_POWER_OF_2(x) (BUILD_BUG_ON_NOT_POWER_OF_2(x))
#define __FIPC_BUILD_BUG_ON(x) (BUILD_BUG_ON(x))
......
......@@ -8,9 +8,6 @@
#ifndef LIBFIPC_PLATFORM_TYPES_H
#define LIBFIPC_PLATFORM_TYPES_H
#include <linux/spinlock.h>
typedef spinlock_t fipc_mutex_t;
/* Nothing for now */
#endif /* LIBFIPC_PLATFORM_TYPES_H */
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment