summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk@arm.linux.org.uk>2014-08-04 20:20:47 +0100
committerWladimir J. van der Laan <laanwj@gmail.com>2014-08-05 14:56:07 +0200
commitbc73bd328d22681f7d9670b622706692f956bfb9 (patch)
tree8bf7e7b9176ea7c864b3648ba88b3d3bb49ac657
parent95b2cdf23223f1e0458d64b30408d21d240fadc6 (diff)
downloadetna_viv-bc73bd328d22681f7d9670b622706692f956bfb9.tar.gz
etna_viv-bc73bd328d22681f7d9670b622706692f956bfb9.tar.xz
Direct debugging output via stderr not stdout
Avoid writing to stdout; depending on the program using etnaviv, stdout may not be the console, and, in the case of programs such as Xorg, may not be something which should receive any output. As the C library uses stderr internally for assert(), it is reasonable to expect that this will be suitable for debug output. Therefore, direct etnaviv debugging output to stderr. Signed-off-by: Russell King <rmk@arm.linux.org.uk>
-rw-r--r--src/etnaviv/etna.c56
-rw-r--r--src/etnaviv/etna_bo.c12
-rw-r--r--src/etnaviv/viv.c66
3 files changed, 67 insertions, 67 deletions
diff --git a/src/etnaviv/etna.c b/src/etnaviv/etna.c
index b78445d..64feb0a 100644
--- a/src/etnaviv/etna.c
+++ b/src/etnaviv/etna.c
@@ -105,13 +105,13 @@ static int gpu_context_clear(struct etna_ctx *ctx)
*/
int rv;
#ifdef DEBUG
- printf("gpu_context_clear (context %i)\n", (int)GCCTX(ctx)->id);
+ fprintf(stderr, "gpu_context_clear (context %i)\n", (int)GCCTX(ctx)->id);
#endif
if(GCCTX(ctx)->inUse != NULL &&
*GCCTX(ctx)->inUse)
{
#ifdef DEBUG
- printf("gpu_context_clear: context was in use, deferred freeing and reallocating it\n");
+ fprintf(stderr, "gpu_context_clear: context was in use, deferred freeing and reallocating it\n");
#endif
if((rv = etna_bo_del(ctx->conn, ctx->ctx_bo, ctx->queue)) != ETNA_OK)
{
@@ -206,7 +206,7 @@ static int gpu_context_finish_up(struct etna_ctx *ctx)
/* Update buffer size to final value */
GCCTX(ctx)->bufferSize = ptr*4;
#ifdef DEBUG
- printf("gpu_context_finish_up: bufferSize %i link %p inUse %p\n",
+ fprintf(stderr, "gpu_context_finish_up: bufferSize %i link %p inUse %p\n",
(int)GCCTX(ctx)->bufferSize, GCCTX(ctx)->link, GCCTX(ctx)->inUse);
#endif
return ETNA_OK;
@@ -231,7 +231,7 @@ static int gpu_context_initialize(struct etna_ctx *ctx)
}
#ifdef DEBUG
- printf("Context 0x%08x\n", (int)id.u.Attach.context);
+ fprintf(stderr, "Context 0x%08x\n", (int)id.u.Attach.context);
#endif
ctx->ctx = VIV_TO_HANDLE(id.u.Attach.context);
@@ -262,7 +262,7 @@ int etna_create(struct viv_conn *conn, struct etna_ctx **ctx_out)
return ETNA_INTERNAL_ERROR;
}
#ifdef DEBUG
- printf("Created user signal %i\n", ctx->sig_id);
+ fprintf(stderr, "Created user signal %i\n", ctx->sig_id);
#endif
/* Allocate command buffers, and create a synchronization signal for each.
@@ -294,7 +294,7 @@ int etna_create(struct viv_conn *conn, struct etna_ctx **ctx_out)
return ETNA_INTERNAL_ERROR;
}
#ifdef DEBUG
- printf("Allocated buffer %i: phys=%08x log=%08x bytes=%08x [signal %i]\n", x,
+ fprintf(stderr, "Allocated buffer %i: phys=%08x log=%08x bytes=%08x [signal %i]\n", x,
(uint32_t)buf0_physical, (uint32_t)buf0_logical, buf0_bytes, ctx->cmdbufi[x].sig);
#endif
}
@@ -330,12 +330,12 @@ static int switch_next_buffer(struct etna_ctx *ctx)
{
int next_buf_id = (ctx->cur_buf + 1) % NUM_COMMAND_BUFFERS;
#if 0
- printf("Switching to new buffer %i\n", next_buf_id);
+ fprintf(stderr, "Switching to new buffer %i\n", next_buf_id);
#endif
if(viv_user_signal_wait(ctx->conn, ctx->cmdbufi[next_buf_id].sig_id, VIV_WAIT_INDEFINITE) != 0)
{
#ifdef DEBUG
- printf("Error waiting for command buffer sync signal\n");
+ fprintf(stderr, "Error waiting for command buffer sync signal\n");
#endif
return ETNA_INTERNAL_ERROR;
}
@@ -344,7 +344,7 @@ static int switch_next_buffer(struct etna_ctx *ctx)
ctx->buf = VIV_TO_PTR(ctx->cmdbuf[next_buf_id]->logical);
ctx->offset = ctx->cmdbuf[next_buf_id]->offset / 4;
#ifdef DEBUG
- printf("Switched to command buffer %i\n", ctx->cur_buf);
+ fprintf(stderr, "Switched to command buffer %i\n", ctx->cur_buf);
#endif
return ETNA_OK;
}
@@ -378,35 +378,35 @@ int _etna_reserve_internal(struct etna_ctx *ctx, size_t n)
{
int status;
#ifdef DEBUG
- printf("Buffer full\n");
+ fprintf(stderr, "Buffer full\n");
#endif
if((ctx->offset*4 + END_COMMIT_CLEARANCE) > COMMAND_BUFFER_SIZE)
{
- printf("%s: Command buffer overflow! This is likely a programming error in the GPU driver.\n", __func__);
+ fprintf(stderr, "%s: Command buffer overflow! This is likely a programming error in the GPU driver.\n", __func__);
abort();
}
#ifdef GCABI_HAS_CONTEXT
if(ctx->cur_buf == ETNA_CTX_BUFFER)
{
- printf("%s: Context buffer overflow! This is likely a programming error in the GPU driver.\n", __func__);
+ fprintf(stderr, "%s: Context buffer overflow! This is likely a programming error in the GPU driver.\n", __func__);
abort();
}
#endif
if(ctx->cur_buf != ETNA_NO_BUFFER)
{
#if 0
- printf("Submitting old buffer %i\n", ctx->cur_buf);
+ fprintf(stderr, "Submitting old buffer %i\n", ctx->cur_buf);
#endif
/* Queue signal to signify when buffer is available again */
if((status = etna_queue_signal(ctx->queue, ctx->cmdbufi[ctx->cur_buf].sig_id, VIV_WHERE_COMMAND)) != ETNA_OK)
{
- printf("%s: queue signal for old buffer failed: %i\n", __func__, status);
+ fprintf(stderr, "%s: queue signal for old buffer failed: %i\n", __func__, status);
abort(); /* buffer is in invalid state XXX need some kind of recovery */
}
/* Otherwise, if there is something to be committed left in the current command buffer, commit it */
if((status = etna_flush(ctx, NULL)) != ETNA_OK)
{
- printf("%s: reserve failed: %i\n", __func__, status);
+ fprintf(stderr, "%s: reserve failed: %i\n", __func__, status);
abort(); /* buffer is in invalid state XXX need some kind of recovery */
}
}
@@ -414,7 +414,7 @@ int _etna_reserve_internal(struct etna_ctx *ctx, size_t n)
/* Move on to next buffer if not enough free in current one */
if((status = switch_next_buffer(ctx)) != ETNA_OK)
{
- printf("%s: can't switch to next command buffer: %i\n", __func__, status);
+ fprintf(stderr, "%s: can't switch to next command buffer: %i\n", __func__, status);
abort(); /* Buffer is in invalid state XXX need some kind of recovery.
This could involve waiting and re-uploading the context state. */
}
@@ -442,7 +442,7 @@ int etna_flush(struct etna_ctx *ctx, uint32_t *fence_out)
/* Get next fence ID */
if((status = _viv_fence_new(ctx->conn, &fence, &signal)) != VIV_STATUS_OK)
{
- printf("%s: could not request fence\n", __func__);
+ fprintf(stderr, "%s: could not request fence\n", __func__);
goto unlock_and_return_status;
}
} while(fence == 0); /* don't return fence handle 0 as it is interpreted as error value downstream */
@@ -453,7 +453,7 @@ int etna_flush(struct etna_ctx *ctx, uint32_t *fence_out)
*/
if((status = etna_queue_signal(ctx->queue, signal, VIV_WHERE_PIXEL)) != ETNA_OK)
{
- printf("%s: error %i queueing fence signal %i\n", __func__, status, signal);
+ fprintf(stderr, "%s: error %i queueing fence signal %i\n", __func__, status, signal);
goto unlock_and_return_status;
}
*fence_out = fence;
@@ -484,7 +484,7 @@ int etna_flush(struct etna_ctx *ctx, uint32_t *fence_out)
cur_buf->offset = ctx->offset*4; /* Copy over current end offset into CMDBUF, for kernel */
#ifdef DEBUG
- printf("Committing command buffer %i startOffset=%x offset=%x\n", ctx->cur_buf,
+ fprintf(stderr, "Committing command buffer %i startOffset=%x offset=%x\n", ctx->cur_buf,
cur_buf->startOffset, ctx->offset*4);
#endif
#ifdef DEBUG_CMDBUF
@@ -520,12 +520,12 @@ int etna_flush(struct etna_ctx *ctx, uint32_t *fence_out)
/* Start building GPU context */
if((status = gpu_context_build_start(ctx)) != ETNA_OK)
{
- printf("%s: gpu_context_build_start failed with status %i\n", __func__, status);
+ fprintf(stderr, "%s: gpu_context_build_start failed with status %i\n", __func__, status);
return status;
}
if((status = ctx->ctx_cb(ctx->ctx_cb_data, ctx, &initial_pipe, &final_pipe)) != ETNA_OK)
{
- printf("%s: Context callback failed with status %i\n", __func__, status);
+ fprintf(stderr, "%s: Context callback failed with status %i\n", __func__, status);
return status;
}
/* Set initial pipe in context */
@@ -533,7 +533,7 @@ int etna_flush(struct etna_ctx *ctx, uint32_t *fence_out)
/* Finish building GPU context */
if((status = gpu_context_build_end(ctx, final_pipe)) != ETNA_OK)
{
- printf("%s: gpu_context_build_end failed with status %i\n", __func__, status);
+ fprintf(stderr, "%s: gpu_context_build_end failed with status %i\n", __func__, status);
return status;
}
}
@@ -555,9 +555,9 @@ int etna_flush(struct etna_ctx *ctx, uint32_t *fence_out)
ctx->offset = cur_buf->offset / 4;
#ifdef DEBUG
#ifdef GCABI_HAS_CONTEXT
- printf(" New start offset: %x New offset: %x Contextbuffer used: %i\n", cur_buf->startOffset, cur_buf->offset, *(GCCTX(ctx)->inUse));
+ fprintf(stderr, " New start offset: %x New offset: %x Contextbuffer used: %i\n", cur_buf->startOffset, cur_buf->offset, *(GCCTX(ctx)->inUse));
#else
- printf(" New start offset: %x New offset: %x\n", cur_buf->startOffset, cur_buf->offset);
+ fprintf(stderr, " New start offset: %x New offset: %x\n", cur_buf->startOffset, cur_buf->offset);
#endif
#endif
return ETNA_OK;
@@ -581,7 +581,7 @@ int etna_finish(struct etna_ctx *ctx)
if((status = etna_flush(ctx, NULL)) != ETNA_OK)
return status;
#ifdef DEBUG
- printf("finish: Waiting for signal...\n");
+ fprintf(stderr, "finish: Waiting for signal...\n");
#endif
/* Wait for signal */
if(viv_user_signal_wait(ctx->conn, ctx->sig_id, VIV_WAIT_INDEFINITE) != 0)
@@ -669,11 +669,11 @@ void etna_dump_cmd_buffer(struct etna_ctx *ctx)
uint32_t start_offset = ctx->cmdbuf[ctx->cur_buf]->startOffset/4 + 8;
uint32_t *buf = &ctx->buf[start_offset];
size_t size = ctx->offset - start_offset;
- printf("cmdbuf:\n");
+ fprintf(stderr, "cmdbuf:\n");
for(unsigned idx=0; idx<size; ++idx)
{
- printf(":%08x ", buf[idx]);
- printf("\n");
+ fprintf(stderr, ":%08x ", buf[idx]);
+ fprintf(stderr, "\n");
}
}
diff --git a/src/etnaviv/etna_bo.c b/src/etnaviv/etna_bo.c
index 655e856..6777cbe 100644
--- a/src/etnaviv/etna_bo.c
+++ b/src/etnaviv/etna_bo.c
@@ -131,7 +131,7 @@ static int etna_bo_lock(struct viv_conn *conn, struct etna_bo *mem)
return ETNA_INTERNAL_ERROR;
}
#ifdef DEBUG
- printf("Locked: phys=%08x log=%08x\n", (uint32_t)mem->address, (uint32_t)mem->logical);
+ fprintf(stderr, "Locked: phys=%08x log=%08x\n", (uint32_t)mem->address, (uint32_t)mem->logical);
#endif
return ETNA_OK;
@@ -219,7 +219,7 @@ struct etna_bo* etna_bo_new(struct viv_conn *conn, size_t bytes, uint32_t flags)
return NULL;
}
#ifdef DEBUG
- printf("Allocated: type:%s mem=%p node=%08x size=%08x\n", etna_bo_surf_type(mem), mem, (uint32_t)mem->node, mem->size);
+ fprintf(stderr, "Allocated: type:%s mem=%p node=%08x size=%08x\n", etna_bo_surf_type(mem), mem, (uint32_t)mem->node, mem->size);
#endif
int status = etna_bo_lock(conn, mem);
if(status != ETNA_OK)
@@ -304,26 +304,26 @@ int etna_bo_del(struct viv_conn *conn, struct etna_bo *mem, struct etna_queue *q
{
if((rv = etna_bo_unlock(conn, mem, queue)) != ETNA_OK)
{
- printf("etna: Warning: could not unlock memory\n");
+ fprintf(stderr, "etna: Warning: could not unlock memory\n");
}
}
if(queue)
{
if((rv = etna_queue_free_vidmem(queue, mem->node)) != ETNA_OK)
{
- printf("etna: Warning: could not queue free video memory\n");
+ fprintf(stderr, "etna: Warning: could not queue free video memory\n");
}
} else {
if((rv = viv_free_vidmem(conn, mem->node)) != ETNA_OK)
{
- printf("etna: Warning: could not free video memory\n");
+ fprintf(stderr, "etna: Warning: could not free video memory\n");
}
}
break;
case ETNA_BO_TYPE_VIDMEM_EXTERNAL:
if((rv = etna_bo_unlock(conn, mem, queue)) != ETNA_OK)
{
- printf("etna: Warning: could not unlock memory\n");
+ fprintf(stderr, "etna: Warning: could not unlock memory\n");
}
break;
case ETNA_BO_TYPE_USERMEM:
diff --git a/src/etnaviv/viv.c b/src/etnaviv/viv.c
index 6c62731..bf8ad53 100644
--- a/src/etnaviv/viv.c
+++ b/src/etnaviv/viv.c
@@ -120,7 +120,7 @@ int viv_invoke(struct viv_conn *conn, struct _gcsHAL_INTERFACE *cmd)
#ifdef DEBUG
if(cmd->status != 0)
{
- printf("Command %i failed with status %i\n", cmd->command, cmd->status);
+ fprintf(stderr, "Command %i failed with status %i\n", cmd->command, cmd->status);
}
#endif
return cmd->status;
@@ -227,14 +227,14 @@ int viv_open(enum viv_hw_type hw_type, struct viv_conn **out)
"Vivante GPL kernel driver %i.%i.%i.%i",
conn->kernel_driver.major, conn->kernel_driver.minor,
conn->kernel_driver.patch, conn->kernel_driver.build);
- printf("Kernel: %s\n", conn->kernel_driver.name);
+ fprintf(stderr, "Kernel: %s\n", conn->kernel_driver.name);
/* Determine base address */
id.command = gcvHAL_GET_BASE_ADDRESS;
if((err=viv_invoke(conn, &id)) != gcvSTATUS_OK)
goto error;
conn->base_address = id.u.GetBaseAddress.baseAddress;
- printf("Physical address of internal memory: %08x\n", conn->base_address);
+ fprintf(stderr, "Physical address of internal memory: %08x\n", conn->base_address);
/* Get chip identity */
id.command = gcvHAL_QUERY_CHIP_IDENTITY;
@@ -246,13 +246,13 @@ int viv_open(enum viv_hw_type hw_type, struct viv_conn **out)
id.command = gcvHAL_QUERY_VIDEO_MEMORY;
if((err=viv_invoke(conn, &id)) != gcvSTATUS_OK)
goto error;
- printf("* Video memory:\n");
- printf(" Internal physical: 0x%08x\n", (uint32_t)id.u.QueryVideoMemory.internalPhysical);
- printf(" Internal size: 0x%08x\n", (uint32_t)id.u.QueryVideoMemory.internalSize);
- printf(" External physical: %08x\n", (uint32_t)id.u.QueryVideoMemory.externalPhysical);
- printf(" External size: 0x%08x\n", (uint32_t)id.u.QueryVideoMemory.externalSize);
- printf(" Contiguous physical: 0x%08x\n", (uint32_t)id.u.QueryVideoMemory.contiguousPhysical);
- printf(" Contiguous size: 0x%08x\n", (uint32_t)id.u.QueryVideoMemory.contiguousSize);
+ fprintf(stderr, "* Video memory:\n");
+ fprintf(stderr, " Internal physical: 0x%08x\n", (uint32_t)id.u.QueryVideoMemory.internalPhysical);
+ fprintf(stderr, " Internal size: 0x%08x\n", (uint32_t)id.u.QueryVideoMemory.internalSize);
+ fprintf(stderr, " External physical: %08x\n", (uint32_t)id.u.QueryVideoMemory.externalPhysical);
+ fprintf(stderr, " External size: 0x%08x\n", (uint32_t)id.u.QueryVideoMemory.externalSize);
+ fprintf(stderr, " Contiguous physical: 0x%08x\n", (uint32_t)id.u.QueryVideoMemory.contiguousPhysical);
+ fprintf(stderr, " Contiguous size: 0x%08x\n", (uint32_t)id.u.QueryVideoMemory.contiguousSize);
conn->mem_base = (viv_addr_t)id.u.QueryVideoMemory.contiguousPhysical;
conn->mem = mmap(NULL, id.u.QueryVideoMemory.contiguousSize, PROT_READ|PROT_WRITE, MAP_SHARED, conn->fd, conn->mem_base);
@@ -501,24 +501,24 @@ int viv_user_signal_destroy(struct viv_conn *conn, int sig_id)
void viv_show_chip_info(struct viv_conn *conn)
{
- printf("* Chip identity:\n");
- printf(" Chip model: %08x\n", conn->chip.chip_model);
- printf(" Chip revision: %08x\n", conn->chip.chip_revision);
- printf(" Chip features: 0x%08x\n", conn->chip.chip_features[0]);
- printf(" Chip minor features 0: 0x%08x\n", conn->chip.chip_features[1]);
- printf(" Chip minor features 1: 0x%08x\n", conn->chip.chip_features[2]);
- printf(" Chip minor features 2: 0x%08x\n", conn->chip.chip_features[3]);
- printf(" Chip minor features 3: 0x%08x\n", conn->chip.chip_features[4]);
- printf(" Stream count: 0x%08x\n", conn->chip.stream_count);
- printf(" Register max: 0x%08x\n", conn->chip.register_max);
- printf(" Thread count: 0x%08x\n", conn->chip.thread_count);
- printf(" Shader core count: 0x%08x\n", conn->chip.shader_core_count);
- printf(" Vertex cache size: 0x%08x\n", conn->chip.vertex_cache_size);
- printf(" Vertex output buffer size: 0x%08x\n", conn->chip.vertex_output_buffer_size);
- printf(" Pixel pipes: 0x%08x\n", conn->chip.pixel_pipes);
- printf(" Instruction count: 0x%08x\n", conn->chip.instruction_count);
- printf(" Num constants: 0x%08x\n", conn->chip.num_constants);
- printf(" Buffer size: 0x%08x\n", conn->chip.buffer_size);
+ fprintf(stderr, "* Chip identity:\n");
+ fprintf(stderr, " Chip model: %08x\n", conn->chip.chip_model);
+ fprintf(stderr, " Chip revision: %08x\n", conn->chip.chip_revision);
+ fprintf(stderr, " Chip features: 0x%08x\n", conn->chip.chip_features[0]);
+ fprintf(stderr, " Chip minor features 0: 0x%08x\n", conn->chip.chip_features[1]);
+ fprintf(stderr, " Chip minor features 1: 0x%08x\n", conn->chip.chip_features[2]);
+ fprintf(stderr, " Chip minor features 2: 0x%08x\n", conn->chip.chip_features[3]);
+ fprintf(stderr, " Chip minor features 3: 0x%08x\n", conn->chip.chip_features[4]);
+ fprintf(stderr, " Stream count: 0x%08x\n", conn->chip.stream_count);
+ fprintf(stderr, " Register max: 0x%08x\n", conn->chip.register_max);
+ fprintf(stderr, " Thread count: 0x%08x\n", conn->chip.thread_count);
+ fprintf(stderr, " Shader core count: 0x%08x\n", conn->chip.shader_core_count);
+ fprintf(stderr, " Vertex cache size: 0x%08x\n", conn->chip.vertex_cache_size);
+ fprintf(stderr, " Vertex output buffer size: 0x%08x\n", conn->chip.vertex_output_buffer_size);
+ fprintf(stderr, " Pixel pipes: 0x%08x\n", conn->chip.pixel_pipes);
+ fprintf(stderr, " Instruction count: 0x%08x\n", conn->chip.instruction_count);
+ fprintf(stderr, " Num constants: 0x%08x\n", conn->chip.num_constants);
+ fprintf(stderr, " Buffer size: 0x%08x\n", conn->chip.buffer_size);
}
int viv_reset(struct viv_conn *conn)
@@ -623,7 +623,7 @@ int _viv_fence_new(struct viv_conn *conn, uint32_t *fence_out, int *signal_out)
if(conn->fences_pending & (1<<fence_mod_signals)) /* fence still pending? */
{
#ifdef FENCE_DEBUG
- printf("Waiting for old fence %08x (which is after %08x)\n", oldfence,
+ fprintf(stderr, "Waiting for old fence %08x (which is after %08x)\n", oldfence,
conn->last_fence_id);
#endif
if((status = viv_user_signal_wait(conn, signal, VIV_WAIT_INDEFINITE)) != VIV_STATUS_OK)
@@ -638,7 +638,7 @@ int _viv_fence_new(struct viv_conn *conn, uint32_t *fence_out, int *signal_out)
*fence_out = fence;
*signal_out = signal;
#ifdef FENCE_DEBUG
- printf("New fence: %08x [signal %08x], pending %08x\n", fence, signal, conn->fences_pending);
+ fprintf(stderr, "New fence: %08x [signal %08x], pending %08x\n", fence, signal, conn->fences_pending);
#endif
return VIV_STATUS_OK;
}
@@ -659,7 +659,7 @@ int viv_fence_finish(struct viv_conn *conn, uint32_t fence, uint32_t timeout)
if(signal == -1)
{
#ifdef FENCE_DEBUG
- printf("Fence already expired: %08x\n", fence);
+ fprintf(stderr, "Fence already expired: %08x\n", fence);
#endif
goto unlock_and_ok; /* fence too old, it must have been signalled already */
}
@@ -674,7 +674,7 @@ int viv_fence_finish(struct viv_conn *conn, uint32_t fence, uint32_t timeout)
VIV_FENCE_BEFORE_EQ(fence, conn->last_fence_id))
{
#ifdef FENCE_DEBUG
- printf("Fence already signaled: %08x, pending %i, newer than %08x; next fence id is %08x\n",
+ fprintf(stderr, "Fence already signaled: %08x, pending %i, newer than %08x; next fence id is %08x\n",
fence,
(conn->fences_pending >> fence_mod_signals)&1,
conn->last_fence_id, conn->next_fence_id);
@@ -694,7 +694,7 @@ int viv_fence_finish(struct viv_conn *conn, uint32_t fence, uint32_t timeout)
{
conn->last_fence_id = fence;
#ifdef FENCE_DEBUG
- printf("Last fence id updated to %i\n", conn->last_fence_id);
+ fprintf(stderr, "Last fence id updated to %i\n", conn->last_fence_id);
#endif
}
pthread_mutex_unlock(&conn->fence_mutex);